www.pudn.com > screenmode.zip > ScreenMode.asm


DEBUG		equ	0 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	Programmed by 罗云彬, bigluo@telekbird.com.cn 
;	Website: http://asm.yeah.net 
;	LuoYunBin's Win32 ASM page (罗云彬的编程乐园) 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	版本信息 
;	屏幕分辨率设置程序 
;	Current Version -- Ver 1.0 (2000.12) 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
	.386 
	.model flat, stdcall 
	option casemap :none   ; case sensitive 
 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	Include 数据 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
include		windows.inc 
include		user32.inc 
include		kernel32.inc 
include		comctl32.inc 
include		comdlg32.inc 
include		shell32.inc 
include		gdi32.inc 
 
includelib	user32.lib 
includelib	kernel32.lib 
includelib	comctl32.lib 
includelib	comdlg32.lib 
includelib	shell32.lib 
includelib	gdi32.lib 
;**************	声明 ************************************** 
DialogMainProc	PROTO	:DWORD,:DWORD,:DWORD,:DWORD 
_SetDisplayMode	PROTO	:DWORD,:DWORD,:DWORD,:DWORD 
 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	equ 数据 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
DM_ORIENTATION		equ	000001h 
DM_PAPERSIZE		equ	000002h 
DM_PAPERLENGTH		equ	000004h 
DM_PAPERWIDTH		equ	000008h 
DM_SCALE		equ	000010h 
DM_COPIES		equ	000100h 
DM_DEFAULTSOURCE	equ	000200h 
DM_PRINTQUALITY		equ	000400h 
DM_COLOR		equ	000800h 
DM_DUPLEX		equ	001000h 
DM_YRESOLUTION		equ	002000h 
DM_TTOPTION		equ	004000h 
DM_COLLATE		equ	008000h 
DM_FORMNAME		equ	010000h 
DM_LOGPIXELS		equ	020000h 
DM_BITSPERPEL		equ	040000h 
DM_PELSWIDTH		equ	080000h 
DM_PELSHEIGHT		equ	100000h 
DM_DISPLAYFLAGS		equ	200000h 
DM_DISPLAYFREQUENCY	equ	400000h 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
ICO_MAIN	equ	1000 
 
IDM_ABOUT	equ	1000 
 
DLG_MAIN	equ	2000 
IDC_LIST	equ	2001 
IDC_TEST	equ	2002 
IDC_CHECK	equ	2003 
IDC_FREQ	equ	2004 
IDC_NOW		equ	2005 
 
DLG_TEST	equ	2100 
IDC_SAVE	equ	2101 
IDC_TIME	equ	2102 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	数据段 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
		.data? 
 
hInstance	dd	? 
hWinMain	dd	? 
hWinList	dd	? 
 
dwNowWidth	dd	? 
dwNowHeight	dd	? 
dwNowColor	dd	? 
dwNowFreq	dd	? 
 
dwSelectWidth	dd	? 
dwSelectHeight	dd	? 
dwSelectColor	dd	? 
dwSelectFreq	dd	? 
 
dwCount		dd	? 
dwData		dw	1000 * 4 dup (?) 
szBuffer	db	512 dup (?) 
szBuffer1	db	256 dup (?) 
;**************	数据段 ************************************ 
 
		.data 
 
szMenuAbout	db	"关于本程序(&A)...",0 
szResult	db	'%4d x %4d象素 %2d位彩色',0 
szFreq		db	' %dHz',0 
szCount		db	'%d 秒...',0 
szError		db	'无法正确设置到指定的显示模式!',0 
szTitle		db	'设置错误!',0 
 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	代码段 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
 
		.code 
 
if		DEBUG 
include		Debug.asm 
endif 
 
include		Win.asm 
include		About.asm 
 
start: 
		invoke	InitCommonControls 
		invoke	GetModuleHandle,NULL 
		mov	hInstance,eax 
		invoke	DialogBoxParam,hInstance,DLG_MAIN,NULL,offset DialogMainProc,0 
		invoke	ExitProcess,NULL 
 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	测试程序 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
_DialogTestProc	proc	uses ebx edi esi, \ 
		hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD 
 
		mov	eax,uMsg 
		.if	eax == WM_CLOSE 
			invoke	EndDialog,hWnd,NULL 
		.elseif	eax == WM_INITDIALOG 
			invoke	_CenterWindow,hWnd 
			mov	dwCount,10 
			invoke	SetTimer,hWnd,1,1000,NULL 
		.elseif	eax == WM_TIMER 
			dec	dwCount 
			invoke	wsprintf,offset szBuffer,offset szCount,dwCount 
			invoke	SetDlgItemText,hWnd,IDC_TIME,offset szBuffer 
			.if	dwCount == 0 
				invoke	KillTimer,hWnd,1 
				invoke	EndDialog,hWnd,NULL 
				invoke	_SetDisplayMode,dwNowWidth,dwNowHeight,\ 
					dwNowColor,dwNowFreq 
			.endif 
		.elseif	eax == WM_COMMAND 
			mov	eax,wParam 
			.if	eax ==	IDCANCEL 
				invoke	_SetDisplayMode,dwNowWidth,dwNowHeight,\ 
					dwNowColor,dwNowFreq 
			.endif 
			invoke	KillTimer,hWnd,1 
			invoke	EndDialog,hWnd,NULL 
		.else 
;******************************************************************** 
;	注意:对话框的消息处理后,要返回 TRUE,对没有处理的消息 
;	要返回 FALSE 
;******************************************************************** 
			mov	eax,FALSE 
			ret 
		.endif 
		mov	eax,TRUE 
		ret 
 
_DialogTestProc	endp 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	主窗口程序 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
DialogMainProc	proc	uses ebx edi esi, \ 
		hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD 
		local	@stPoint:POINT 
		local	@szBuffer[128]:byte 
 
		mov	eax,wMsg 
		.if	eax == WM_CLOSE 
			invoke	EndDialog,hWinMain,NULL 
;******************************************************************** 
		.elseif	eax == WM_INITDIALOG 
			mov	eax,hWnd 
			mov	hWinMain,eax 
			invoke	_CenterWindow,eax 
			call	_Init 
;******************************************************************** 
		.elseif	eax == WM_COMMAND 
			mov	eax,wParam 
			movzx	eax,ax 
			.if	eax ==	IDC_CHECK 
				invoke	IsDlgButtonChecked,hWinMain,IDC_CHECK 
				.if	eax == BST_CHECKED 
					invoke	GetDlgItem,hWinMain,IDC_FREQ 
					invoke	EnableWindow,eax,TRUE 
				.else 
					invoke	GetDlgItem,hWinMain,IDC_FREQ 
					invoke	EnableWindow,eax,FALSE 
				.endif 
				call	_CheckFreq 
			.elseif	eax ==	IDC_LIST 
				mov	eax,wParam 
				shr	eax,16 
				.if	eax ==	LBN_SELCHANGE 
					invoke	GetDlgItem,hWinMain,IDC_TEST 
					invoke	EnableWindow,eax,TRUE 
					invoke	SendMessage,hWinList,LB_GETCURSEL,0,0 
					shl	eax,3 
					add	eax,offset dwData 
					mov	ebx,eax 
					xor	eax,eax 
					mov	ax,word ptr [ebx] 
					mov	dwSelectWidth,eax 
					mov	ax,word ptr [ebx+2] 
					mov	dwSelectHeight,eax 
					mov	ax,word ptr [ebx+4] 
					mov	dwSelectColor,eax 
					mov	ax,word ptr [ebx+6] 
					mov	dwSelectFreq,eax 
					call	_CheckFreq 
				.endif 
			.elseif	eax ==	IDC_TEST 
				invoke	_SetDisplayMode,dwSelectWidth,dwSelectHeight,\ 
					dwSelectColor,dwSelectFreq 
				.if	eax ==	DISP_CHANGE_SUCCESSFUL 
					invoke	DialogBoxParam,hInstance,DLG_TEST,\ 
						hWinMain,offset _DialogTestProc,NULL 
				.else 
					invoke	MessageBox,hWinMain,offset szError,\ 
						offset szTitle,MB_ICONINFORMATION or MB_OK 
				.endif 
				call	_GetCurrentMode 
			.elseif	eax ==	IDC_FREQ 
				call	_CheckFreq 
			.endif 
;******************************************************************** 
		.elseif	eax == WM_SYSCOMMAND 
			mov	eax,wParam 
			movzx	eax,ax 
			.if	eax == IDM_ABOUT 
				invoke	DialogBoxParam,hInstance,DLG_ABOUT,hWnd,offset AboutDialogProc,DLG_ABOUT 
			.else 
				mov	eax,FALSE 
				ret 
			.endif 
;******************************************************************** 
;	注意:对话框的消息处理后,要返回 TRUE,对没有处理的消息 
;	要返回 FALSE 
;******************************************************************** 
		.else 
			mov	eax,FALSE 
			ret 
		.endif 
		mov	eax,TRUE 
		ret 
 
DialogMainProc	endp 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
; 初始化程序: 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
_Init		proc 
		local	@hSysMenu 
 
		invoke	GetDlgItem,hWinMain,IDC_LIST 
		mov	hWinList,eax 
		invoke	CheckDlgButton,hWinMain,IDC_CHECK,BST_UNCHECKED 
		invoke	GetDlgItem,hWinMain,IDC_FREQ 
		invoke	EnableWindow,eax,FALSE 
		invoke	GetDlgItem,hWinMain,IDC_TEST 
		invoke	EnableWindow,eax,FALSE 
 
		invoke	SendDlgItemMessage,hWinMain,IDC_FREQ,EM_LIMITTEXT,3,NULL 
		invoke	LoadIcon,hInstance,ICO_MAIN 
		invoke	SendMessage,hWinMain,WM_SETICON,ICON_SMALL,eax 
 
;******************************************************************** 
;	在系统菜单中添加菜单项 
;******************************************************************** 
		invoke	GetSystemMenu,hWinMain,FALSE 
		mov	@hSysMenu,eax 
		invoke	AppendMenu,@hSysMenu,MF_SEPARATOR,0,NULL 
		invoke	AppendMenu,@hSysMenu,MF_STRING,IDM_ABOUT,offset szMenuAbout 
 
		call	_GetDisplayModeList 
		call	_GetCurrentMode 
 
		ret 
 
_Init		endp 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	列举显示设备支持的显示分辨率 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
_GetDisplayModeList	proc 
		local	@stDev:DEVMODE 
		local	@dwIndex 
 
		mov	@dwIndex,0 
		mov	@stDev.dmSize,sizeof DEVMODE 
		mov	@stDev.dmDriverExtra,0 
 
		@@: 
		invoke	EnumDisplaySettings,NULL,@dwIndex,addr @stDev 
		or	eax,eax 
		jz	@F 
		invoke	wsprintf,addr szBuffer,addr szResult,\ 
			@stDev.dmPelsWidth,@stDev.dmPelsHeight,\ 
			@stDev.dmBitsPerPel 
		.if	@stDev.dmDisplayFrequency != 0 && @stDev.dmDisplayFrequency != 1 
			invoke	wsprintf,addr szBuffer1,addr szFreq,@stDev.dmDisplayFrequency 
			invoke	lstrcat,addr szBuffer,addr szBuffer1 
		.endif 
		invoke	SendMessage,hWinList, LB_ADDSTRING,0,addr szBuffer 
		shl	eax,3 
		add	eax,offset dwData 
		mov	ebx,eax 
		mov	eax,@stDev.dmPelsWidth 
		mov	word ptr [ebx],ax 
		mov	eax,@stDev.dmPelsHeight 
		mov	word ptr [ebx+2],ax 
		mov	eax,@stDev.dmBitsPerPel 
		mov	word ptr [ebx+4],ax 
		mov	eax,@stDev.dmDisplayFrequency 
		mov	word ptr [ebx+6],ax 
		inc	@dwIndex 
		jmp	@B 
		@@: 
 
		ret 
 
_GetDisplayModeList	endp 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	检测当前的屏幕显示分辨率 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
_GetCurrentMode	proc 
		local	@stDev:DEVMODE 
 
		mov	@stDev.dmSize,sizeof DEVMODE 
		mov	@stDev.dmDriverExtra,0 
 
		invoke	EnumDisplaySettings,NULL,ENUM_CURRENT_SETTINGS,addr @stDev 
		invoke	wsprintf,addr szBuffer,addr szResult,\ 
			@stDev.dmPelsWidth,@stDev.dmPelsHeight,\ 
			@stDev.dmBitsPerPel 
		.if	@stDev.dmDisplayFrequency != 0 && @stDev.dmDisplayFrequency != 1 
			invoke	wsprintf,addr szBuffer1,addr szFreq,@stDev.dmDisplayFrequency 
			invoke	lstrcat,addr szBuffer,addr szBuffer1 
		.endif 
		invoke	SetDlgItemText,hWinMain,IDC_NOW,addr szBuffer 
 
		mov	eax,@stDev.dmPelsWidth 
		mov	dwNowWidth,eax 
		mov	eax,@stDev.dmPelsHeight 
		mov	dwNowHeight,eax 
		mov	eax,@stDev.dmBitsPerPel 
		mov	dwNowColor,eax 
		mov	eax,@stDev.dmDisplayFrequency 
		mov	dwNowFreq,eax 
 
		ret 
 
_GetCurrentMode	endp 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	设置当前的屏幕显示分辨率 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
_SetDisplayMode	proc	_dwWidth,_dwHeight,_dwColor,_dwFreq 
		local	@stDev:DEVMODE 
 
		mov	@stDev.dmSize,sizeof DEVMODE 
		mov	@stDev.dmDriverExtra,0 
 
		push	_dwWidth 
		pop	@stDev.dmPelsWidth 
		push	_dwHeight 
		pop	@stDev.dmPelsHeight 
		push	_dwColor 
		pop	@stDev.dmBitsPerPel 
		push	_dwFreq 
		pop	@stDev.dmDisplayFrequency 
		mov	ebx,DM_BITSPERPEL or DM_PELSWIDTH or DM_PELSHEIGHT 
		.if	_dwFreq != 0 
			or	ebx,DM_DISPLAYFREQUENCY 
		.endif 
		mov	@stDev.dmFields,ebx 
		invoke	ChangeDisplaySettings,addr @stDev,CDS_UPDATEREGISTRY 
		ret 
 
_SetDisplayMode	endp 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	检测参数是否有效 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
_CheckFreq	proc 
 
		invoke	IsDlgButtonChecked,hWinMain,IDC_CHECK 
		.if	eax == BST_CHECKED 
			invoke	GetDlgItemInt,hWinMain,IDC_FREQ,addr szBuffer,FALSE 
			mov	dwSelectFreq,eax 
			cmp	dwSelectWidth,0 
			jz	@F 
			invoke	GetDlgItemInt,hWinMain,IDC_FREQ,addr szBuffer,FALSE 
			cmp	eax,56 
			jl	@F 
			cmp	eax,160 
			jg	@F 
			invoke	GetDlgItem,hWinMain,IDC_TEST 
			invoke	EnableWindow,eax,TRUE 
			ret 
			@@: 
			invoke	GetDlgItem,hWinMain,IDC_TEST 
			invoke	EnableWindow,eax,FALSE 
		.else 
			.if	dwSelectWidth != 0 
				invoke	GetDlgItem,hWinMain,IDC_TEST 
				invoke	EnableWindow,eax,TRUE 
			.endif 
		.endif 
		ret 
 
_CheckFreq	endp 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
		end	start