windows訊息機制與例項

blogli發表於2017-06-01

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()函式返回,繼續迴圈處理下一個訊息。

 

 

 

 

 

 

 

 

 

     

相關文章