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