就业数据资源平台
当前位置:首页 > PC技术
PC技术辅导:窗口子类化(3)

  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 来取回这个值。
  .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
  在函数 EditWndProc 中,我们自己处理了WM_CHAR消息: 如果输入的字符是'0'--'9'、'A'-'F'或者是'a'--'f'就接受,并且把此消息转发给原窗口函数,其中若输入的是小写的'a'--'f'就把它变为大写。如果输入的不是十六进制字符,就丢掉它,并且也不转发此消息。因此当输入是非十六进制字符时,这个字符就不会显示在 Edit 控件中。
  .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
  .end
  在这里我们通过处理 回车(Enter) 键进一步示范了子类化的能力。EditWndProc 通过检查 WM_KEYDONW 消息来判断是否是 回车键,若是显示提示消息框,否则转发此消息。 你可以用窗口子类化来控制另外的窗口,这是必须掌握的十分有用的技术之一。
就业数据资源平台