這篇博文介紹下一個簡單的視窗的建立過程。
一、建立視窗的過程如下:
1、註冊視窗類別---利用建立的視窗類別建立視窗---訊息迴圈等待處理訊息
2、主要的函數如下:
RegisterClassEx---[ CreateWindowEx ShowWindow UpdateWindow ]
---[ GetMessage TranslateMessage DispatchMessage ]
二、Windows的訊息處理機制:
三、視窗代碼:
.386.model flat,stdcalloption casemap:noneinclude windows.incinclude gdi32.incincludelib gdi32.libinclude user32.incincludelib user32.libinclude kernel32.incincludelib kernel32.lib.data?hInstance dd ?hWinMain dd ?.constszClassName db 'MyClass',0szCaptionMain db 'My First Window !',0szText db 'Win32 Assembly,Simple and Powerful !',0.code;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;_ProcWinMain就是視窗過程了;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<_ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam local @stPs:PAINTSTRUCT local @stRect:RECT local @hDc mov eax,uMsg;在調用UpdateWindow時發送WM_PAINT訊息;繪製客服區 .if eax == WM_PAINT invoke BeginPaint,hWnd,addr @stPs mov @hDc,eax invoke GetClientRect,hWnd,addr @stRect invoke DrawText,@hDc,addr szText,-1,\ addr @stRect,\ DT_SINGLELINE or DT_CENTER or DT_VCENTER invoke EndPaint,hWnd,addr @stPs;點擊了視窗右上方的‘X’時會發送WM_CLOSE訊息;DestroyWindow用來銷毀主視窗;PostQuitMessage用來發送WM_QUIT訊息,不發送會發現視窗銷毀進程任存在;因為訊息迴圈還在 .elseif eax == WM_CLOSE invoke DestroyWindow,hWinMain invoke PostQuitMessage,NULL;預設的視窗過程,使用者不處理的訊息都要交予TA處理,否則容易出錯 .else invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .endif xor eax,eax ret_ProcWinMain endp_WinMain proc local @stWndClass:WNDCLASSEX local @stMsg:MSG;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;註冊視窗類別;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;獲得模組控制代碼hInstance invoke GetModuleHandle,NULL mov hInstance,eax;將 @stWndClass 變數清零,因為這是個struct,其中的一些變數我們;不關心也不會去設定,清零使得程式更加健壯和易於把握 invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass;一下的內容就是設定各個需要的變數了 invoke LoadCursor,0,IDC_ARROW mov @stWndClass.hCursor,eax push hInstance pop @stWndClass.hInstance mov @stWndClass.cbSize,sizeof WNDCLASSEX;這裡決定了視窗時可以變大變小的 mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW ;這裡指定了視窗的視窗過程 mov @stWndClass.lpfnWndProc,offset _ProcWinMain mov @stWndClass.hbrBackground,COLOR_HIGHLIGHT + 1;給視窗類別指定名字 mov @stWndClass.lpszClassName,offset szClassName invoke RegisterClassEx,addr @stWndClass;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;利用已經建立的視窗類別建立視窗;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< invoke CreateWindowEx,WS_EX_CLIENTEDGE,\ offset szClassName,offset szCaptionMain,\ WS_OVERLAPPEDWINDOW,\ 100,100,600,400,\ NULL,NULL,hInstance,NULL mov hWinMain,eax invoke ShowWindow,hWinMain,SW_SHOWNORMAL invoke UpdateWindow,hWinMain;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;訊息迴圈;GetMessage進訊息佇列中取訊息,如果是WM_QUIT則返回0,此時訊息迴圈退出;TranslateMessage是將鍵盤資訊轉換成ASCII碼;DispatchMessage會調用在視窗類別註冊時指定的視窗函數處理訊息;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< .while TRUE invoke GetMessage,addr @stMsg,NULL,0,0 .break .if eax == 0 invoke TranslateMessage,addr @stMsg invoke DispatchMessage,addr @stMsg .endw ret_WinMain endpstart: invoke _WinMain invoke ExitProcess,NULL ;退出進程 end start
四、運行結果: