2012年8月10日 星期五

子類化(窗體消息)


在這裡我先具體說明子類化
如果各位編成過vc 就可以清楚知道這個過程(我是從vc編成才發現vb也可行的)
首先呢
子類化這個就是基於與windows的消息區塊是同一層的
他可以讓你擁有與被子類化的窗口的所有控制權
現在我舉附件的範例...(範例在下面下載)
假設我想知道客戶他是否有移動窗體(這只是示範 , 真正會用後 , 子類化是很強大的)
那麼就需要子類化
在windows的流程是這樣
未子類化
客戶移動窗體 -> windows -> 默認處理消息函數
子類化

客戶移動窗體 -> windows -> 自訂的處理消息(重新指向新地址) -> 默認處理消息函數
以上流程大家應該都能夠理解的
也就是說被子類化窗體(或者控件)將在windows默認系統處理消息這兩個中間攔截消息
攔截後我們可以自訂要發送到原本應該默認處理消息地方的消息 (有點繞口令XD)
可能會有人問 
我們直接修改客戶發送到windows時的消息
這是不被允許的 , 但是我們卻可以讓他的消息指向別的函數地址
上面說起來很容易
首先我們來看一下檔案中的
Setwindowlong 
  1. C原型: 
  2. LONG WINAPI SetWindowLong(
  3. __in HWND hWnd,
  4. __in int nIndex,
  5. __in LONG dwNewLong
  6. );
  7. VB原型
  8. Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
複製代碼
姑且先不計它在其他地方有甚麼作用
在這裡我們是使它重新設定新的處理消息
參數第一 : 
當然就是處理消息窗口的句柄
參數第二 : 
我們給它一個這樣的常數Const GWL_WNDPROC = (-4&) 
它這個常數在這裡當參數的作用為
設置一個新的窗口過程(函數)地址
在這裡我們就是需要這個常數來攔截
至於其他常數在這裡就不說了,以後有機會會講到.
參數第三 :
新消息函數地址 (我們可以利用addressof來計算我們新的處理消息函數地址)

第二個API
CallWindowProc
  1. C原型

  2. LRESULT WINAPI CallWindowProc(
  3.   __in  WNDPROC lpPrevWndFunc,
  4.   __in  HWND hWnd,
  5.   __in  UINT Msg,
  6.   __in  WPARAM wParam,
  7.   __in  LPARAM lParam
  8. );
  9. VB原型
  10. Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal MSG As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
複製代碼
一樣不說它在哪邊有甚麼功效
這裡我們是用來將處理消息做完後~發送回VB默認的地方 (這是必要的,否則你將會失去對VB的控制權,可能使程序崩潰的)
參數第一 : 
指向前一個地址指針(這裡我們讓它指向前一個消息過程)
參數第二 :
處理消息窗口的句柄
參數第三 : 
要處理的類型 (這裡要處理的是WM_MOVE)
參數第四 : 
附加在參數三
(例如我要知道滑鼠現在按下右鍵或左鍵,那麼參數三就是滑鼠類型,而參數四就是右左鍵的判斷)
參數第五 : 
同上囉
參數四和五默認都是0(沒有任何要附加)的
這裡API說明完後
相信各位已經弄懂了許多:D
附件內有詳細注解以及範例調用
如果還有問題可以在這留言或發信息給我

範例載點

沒有留言:

張貼留言