1. 程式人生 > >windows消息機制與實例

windows消息機制與實例

默認 style import pcl ++ user 註冊 lpar pub

windows發送窗口消息

  所需工具:spy++,visual studio 2017,c#語言 

  技術路線:首先通過spy++獲得所要操縱的窗口的句柄,函數的原型聲明為:

  [DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

  此函數獲得目標窗口的句柄,如果要獲得某個子窗口的句柄,通過以下函數可獲得:

  [DllImport("User32.dll ")]
public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childe, string strclass, string FrmText);

  對目標窗口的操作(發送指令),使用的函數原型如下:

  [DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

  我通過SendMessage函數發送的是繪圖動作,具體包括鼠標的down,move,up

  另一個發送消息的函數,原型聲明:

   [DllImport("User32.dll", EntryPoint = "PostMessage")]
private static extern int PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

  我通過PostMessage函數發送的是點擊按鈕的動作,具體包括鼠標的down,up

SendMessage與PostMessage函數的差別

  SendMessage為這個指定的消息調用窗口處理程序,直到窗口處理完這個程序後才會返回;PostMessage函數發送一個消息到線程消息對列中,並立即返回。

失敗部分:1.在繪圖過程中,我考慮過用WM_PAINT發送繪圖消息,但是查看MSDN手冊後發現WM_PAINT消息是由系統產生的,它不應該由一個應用程序發送。我也考慮過先生成一個圖形,然後將它發送到窗口,這樣違背了最初測試的目的。

失敗經驗總結:首先要確定技術路線,不能盲目亂試,查看官方文檔的函數介紹。

Windows中的消息機制:消息就是一些指令。如果你想讓窗口或控件(實質上,控件是特殊的窗口)執行何種動作,你應該傳送一個消息給它;如果另一個窗口想讓你執行何種操作,它可以傳送一個消息給你。如果一個事件,如敲擊鍵盤、移動鼠標、點擊按鈕等,系統將消息傳送給窗口,如果你是這些窗口之一,你將接收到消息執行相應的操作。

消息隊列:當消息發送過來,將消息加入消息隊列,當一個消息被處理時,將其從消息隊列移除。這樣確保消息不會丟失,當你正在處理一個消息時,其它到來的消息可以加入到消息隊列直到被處理。

消息循環:

while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg); //可選,有的會用到
DispatchMessage(&Msg);
}

1. 消息循環調用GetMessage()從消息隊列中查找消息進行處理,如果消息隊列為空,程序將停止執行並等待(程序阻塞)。

2. 事件發生時導致一個消息加入到消息隊列(例如系統註冊了一個鼠標點擊事件),GetMessage()將返回一個正值,這表明有消息需要被處理,並且消息已經填充到傳入的MSG參數中;當傳入WM_QUIT消息 時返回0;如果返回值為負表明發生了錯誤。

3. 取出消息(在Msg變量中)並將其傳遞給TranslateMessage()函數,這個函數做一些額外的處理:將虛擬鍵值信息轉換為字符信息。

4. 上面的步驟執行完後,將消息傳遞給DispatchMessage()函數。DispatchMessage()函數將消息分發到消息的目標窗口,並且查找目標窗口過程函數,給窗口過程函數傳遞窗口句柄、消息、wParam、lParam等參數然後調用該函數。

5. 在窗口過程函數中,檢查消息和其他參數,你可以用它來實現你想要的操作。如果不想處理某些特殊的消息,你應該總是調用DefWindowProc()函數,系統將按按默認的方式處理這些消息(通常認為是不做任何操作)。
6. 一旦一個消息處理完成,窗口過程函數返回,DispatchMessage()函數返回,繼續循環處理下一個消息。

    

windows消息機制與實例