Steward
分享是一種喜悅、更是一種幸福
程式語言 - Flat Assembler (FASM) - Win32 API - Dialog - Handle Event
參考資訊:
https://board.flatassembler.net/
一般在建立Windows視窗時,會註冊自定義的Class並且設定事件處理的副程式(callback),不過,目前範例使用的Class是系統預設的WC_DIALOG,因此,可以透過SetWindowLong()設定callback,這種替換callback的行為就稱為Subclass,意指為原本Class的Subclass,所以Subclass後,需要將原先callback的位址(SetWindowLong()的回傳值)保存下來,然後透過呼叫CallWindowProc()(傳入原先callback的位址),用來將處理控制權移交回原先視窗元件,所以當有多層Subclass的情形發生時,每次在處理事件時,記得判斷對應的Handle,如:在處理關閉事件時(WM_CLOSE),會先判斷目前的hWnd是否為當前的視窗hWnd,如果是當前視窗hWnd,才進行關閉的動作,避免關閉到其它視窗元件
main.asm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | include "head.asm" section ". text " code readable executable proc WndProc hWnd, uMsg, wParam, lParam mov eax , [uMsg] cmp eax , WM_CLOSE je . handle_close cmp eax , WM_DESTROY je . handle_destroy invoke CallWindowProc , [pDefWndProc], [hWnd], [uMsg], [wParam], [lParam] jmp . finish . handle_close : invoke DestroyWindow , [hWnd] xor eax , eax jmp . finish . handle_destroy : invoke PostQuitMessage , 0 xor eax , eax jmp . finish . finish : ret endp proc WinMain hInst, hPrevInst, CmdLine, CmdShow local msg: MSG invoke CreateWindowEx , WS_EX_LEFT , WC_DIALOG , szName, \ WS_OVERLAPPEDWINDOW or WS_VISIBLE , 0, 0, 300, 300, NULL , NULL , NULL , NULL mov [hWin], eax invoke SetWindowLong , [hWin], GWL_WNDPROC , WndProc mov [pDefWndProc], eax @@: lea eax , [msg] invoke GetMessage , eax , NULL , 0, 0 cmp eax , 0 je @ f lea eax , [msg] invoke DispatchMessage , eax jmp @ b @@: mov eax , [msg.wParam] ret endp start : invoke GetModuleHandle , NULL mov [hInstance], eax invoke GetCommandLine mov [pCommand], eax stdcall WinMain , [hInstance], NULL , [pCommand], SW_SHOWNORMAL invoke ExitProcess , eax |
Line 5~9:關閉視窗的順序為:主視窗收到WM_CLOSE事件時,呼叫DestroyWindow(),DestroyWindow()會自動將子視窗的相關資源也一併釋放掉(包含Resource描述的資源),系統接著會發送WM_DESTROY事件給主視窗,待主視窗收到WM_DESTROY事件時,呼叫PostQuitMessage()結束視窗,值得注意的地方是,SendMessage()是屬於Block方式呼叫(必須等待動作執行完畢才返回),而PostQuitMessage()則是Non-block方式呼叫
Line 10:將處理控制權移交給下一個視窗元件
完成