EditWndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
.data ClassName db "SubclassWinClass",0 AppName db "Subclassing Demo",0 EditClass db "EDIT",0 Message db "You pressed Enter in the text box!",0 逆风者
.data? hInstance HINSTANCE ? hwndEdit dd ? OldWndProc dd ?
.code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke WinMain, hInstance,NULL,NULL, SW_SHOWDEFAULT invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL hwnd:HWND mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_APPWORKSPACE mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL,IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\ WS_OVERLAPPED WS_CAPTION WS_SYSMENU WS_MINIMIZEBOX WS_MAXIMIZEBOX WS_VISIBLE,CW_USEDEFAULT,\ CW_USEDEFAULT,350,200,NULL,NULL,\ hInst,NULL mov hwnd,eax .while TRUE invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .endw mov eax,msg.wParam ret WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .if uMsg==WM_CREATE invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR EditClass,NULL,\ WS_CHILD WS_VISIBLE WS_BORDER,20,\ 20,300,25,hWnd,NULL,\ hInstance,NULL mov hwndEdit,eax invoke SetFocus,eax ;----------------------------------------- ; Subclass it! ;----------------------------------------- invoke SetWindowLong,hwndEdit,GWL_WNDPROC,addr EditWndProc mov OldWndProc,eax .elseif uMsg==WM_DESTROY invoke PostQuitMessage,NULL .else invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .endif xor eax,eax ret WndProc endp
EditWndProc PROC hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD .if uMsg==WM_CHAR mov eax,wParam .if (al>="0" && al<="9") || (al>="A" && al<="F") || (al>="a" && al<="f") || al==VK_BACK .if al>="a" && al<="f" sub al,20h .endif invoke CallWindowProc,OldWndProc,hEdit,uMsg,eax,lParam ret .endif .elseif uMsg==WM_KEYDOWN mov eax,wParam .if al==VK_RETURN invoke MessageBox,hEdit,addr Message,addr AppName,MB_OK MB_ICONINFORMATION invoke SetFocus,hEdit .else invoke CallWindowProc,OldWndProc,hEdit,uMsg,wParam,lParam ret .endif .else invoke CallWindowProc,OldWndProc,hEdit,uMsg,wParam,lParam ret .endif xor eax,eax ret EditWndProc endp end start
分析:
invoke SetWindowLong,hwndEdit,GWL_WNDPROC,addr EditWndProc mov OldWndProc,eax
在创建 Edit 控件后,通过调用 SetWindowLong 把原来的窗口函数地址替换为自定义函数的地址,从而对它实施了窗口子类化,要注意 为了调用函数 CallWindowProc,我们存储了原窗口函数地址,自已编写的EditWndProc 仅仅是个普普通通的窗口函数。当然也可以再调用一次 SetWindowLong 函数来存储这个32位的值,
invoke SetWindowLong ,hwndEdit,GWL_USERDATA,eax 。
当然用的时候就要调用GetWindowLong 来取回这个值。
本文章更多内容:<<上一页 - 1 - 2 - 3 - 下一页>> |