windows 訊息處理過程說明

來源:互聯網
上載者:User

/*------------------------------------------------------------
   HELLOWIN.C -- Displays "Hello, Windows 98!" in client area
                 (c) Charles Petzold, 1998
  ------------------------------------------------------------*/

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("HelloWin") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;

     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;

     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
    
     hwnd = CreateWindow (szAppName,                  // window class name
                          TEXT (" The Hello Program"), // window caption
                          WS_OVERLAPPEDWINDOW,        // window style
                          CW_USEDEFAULT,              // initial x position
                          CW_USEDEFAULT,              // initial y position
                          CW_USEDEFAULT,              // initial x size
                          CW_USEDEFAULT,              // initial y size
                          NULL,                       // parent window handle
                          NULL,                       // window menu handle
                          hInstance,                  // program instance handle
                          NULL) ;                     // creation parameters
     //showwindow 第一個參數剛剛建立的表單,第二個參數是從winmain函數中傳入的,此處改成了SW_SHOWMAXIMIZED代表最大化顯示
     ShowWindow (hwnd,SW_SHOWMAXIMIZED) ;
     UpdateWindow (hwnd) ;
  
   /* msg變數是型態為 MSG 的結構,型態 MSG在 WINUSER.H中定義如下:
 typedef struct tagMSG
 {
 HWND hwnd ;
 UINT message ;
 WPARAM wParam ;
 LPARAM lParam ;
 DWORD time ;
 POINT pt ;
 }
 * POINT 資料型態也是一個結構,它在 WINDEF.H 中定義如下:
 typedef struct tagPOINT
 {
 LONG x ;
 LONG y ;
 }*/
     while (GetMessage (&msg, NULL, 0, 0))
    /*GetMessage
  GetMessage (&msg, NULL, 0, 0)
  這一呼叫傳給 Windows一個指標,指向名為 msg的MSG 結構。第二、第三和第四個參數設定為 NULL 或者 0,
  表示程式接收它自己建立的所有視窗的所有訊息。Windows用從訊息佇列中取出的下一個訊息來填充訊息結構
  的各個欄位,結構的各個欄位包括:
   hwnd 接收訊息的視窗控制代碼。在 HELLOWIN程式中,這一參數與 CreateWindow 傳回的 hwnd
  值相同,因為這是該程式擁有的唯一視窗。
   message 訊息標識符。這是一個數值,用以標識訊息。對於每個訊息,均有一個對應的標識
  符,這些標識符定義於 Windows表標頭檔(其中大多數在 WINUSER.H 中) ,以首碼 WM( 「window message」 ,
  視窗訊息)開頭。例如,使用者將滑鼠游標放在HELLOWIN顯示地區之內,並按下滑鼠左按鈕,Windows就在
  訊息佇列中放入一個訊息,該訊息的 message 欄位等於 WM_LBUTTONDOWN。這是一個常數,其值為0x0201。
   wParam 一個32位的「message parameter(訊息參數) 」 ,其含義和數值根據訊息的不同而不
  同。
   lParam 一個32 位的訊息參數,其值與訊息有關。
   time 訊息放入訊息佇列中的時間。
   pt 訊息放入訊息佇列時的滑鼠座標。
  只要從訊息佇列中取出訊息的 message 欄位不為 WM_QUIT (其值為0x0012) , GetMessage 就傳回一個非零值。
  WM_QUIT訊息將導致GetMessage 傳回 0。*/
  {

          TranslateMessage (&msg) ;//將 msg結構傳給 Windows,進行一些鍵盤轉換
          DispatchMessage (&msg) ;
   /* DispatchMessage又將 msg結構回傳給 Windows。然後,Windows將該訊息發送給適當的視窗訊息處理常式,讓它進   行處理。這也就是說,Windows將呼叫視窗訊息處理常式。在HELLOWIN 中,這個視窗訊息處理常式就是 WndProe 函   數。處理完訊息之後,WndProc 傳回到 Windows。此時,Windows還停留在 DispatchMessage 呼叫中。在結束DispatchMessage 呼叫的處理之後,Windows回到HELLOWIN,並且接著從下一個 GetMessage呼叫開始訊息迴圈。*/
     }
     return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 /*視窗訊息處理常式的四個參數與 MSG 結構的前四個欄位是相同的。第一個參數 hwnd是接收訊息的視窗
的控制代碼,它與 CreateWindow 函數的傳回值相同。對於與HELLOWIN相似的程式(只建立一個視窗),這個參
數是程式所知道的唯一視窗控制代碼。如果程式是依據同一視窗類別別(同時也是同一視窗訊息處理常式)建立多個
視窗,則 hwnd標識接收訊息的特定視窗。
第二個參數與 MSG 結構中的 message 欄位相同,它是標識訊息的數值。最後兩個參數都是 32 位的訊息參數,
提供關於訊息的更多資訊。這些參數包含每個訊息型態的詳細資料。有時訊息參數是兩個存放在一起的 16位
值,而有時訊息參數又是一個指向字串或資料結構的指標。
程式通常不直接呼叫視窗訊息處理常式,視窗訊息處理常式通常由 Windows本身呼叫。通過呼叫 SendMessage
函數,程式能夠直接呼叫它自己的視窗訊息處理常式。*/
{
     HDC         hdc ;//裝置內容控制代碼
     PAINTSTRUCT ps ;//繪圖結構
     RECT        rect ;
    
     switch (message)
     {
     case WM_CREATE:
          PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
          return 0 ;
         
     case WM_PAINT:
  /* WndProc 處理的第二個訊息為 WM_PAINT。這個訊息在 Windows程式設計中是很重要的。當視窗顯示地區的一
  部分顯示內容或者全部變為「無效」,以致於必須「更新畫面」時,將由這個訊息通知程式。
  顯示地區的顯示內容怎麼會變得無效呢?在最初建立視窗的時候,整個顯示地區都是無效的,因為程式還沒有
  在視窗上畫什麼東西。第一條 WM_PAINT 訊息(通常發生在 WinMain 中呼叫UpdateWindow 時)指示視窗訊息
  處理常式在顯示地區上畫一些東西。
  在使用者改變HELLOWIN視窗的大小後,顯示地區的顯示內容重新變得無效。讀者應該還記得,HELLOWIN 中
  wndclass結構的 style欄位設定為標誌 CS_HREDRAW和 CS_VREDRAW,這樣的格式設定指示 Windows,在視窗
  大小改變後,就把整個視窗顯示內容當成無效。然後,視窗訊息處理常式將收到一條 WM_PAINT 訊息。
  當使用者將 HELLOWIN 最小化,然後再次將視窗恢複為以前的大小時,Windows 將不會儲存顯示地區的內容。
  在圖形環境下,視窗顯示地區涉及的資料量很大。因此,Windows令視窗無效,視窗訊息處理常式接收一條
  WM_PAINT 訊息,並自動回復其視窗的內容。
  在移動視窗以致其相互重迭時,Windows不儲存一個視窗中被另一個視窗所遮蓋的內容。在這一部分不再被遮
  蓋之後,它就被標誌為無效。視窗訊息處理常式接收到一條 WM_PAINT 訊息,以更新視窗的內容。
  對 WM_PAINT的處理幾乎總是從一個 BeginPaint呼叫開始:
  hdc = BeginPaint (hwnd, &ps) ;
  而以一個 EndPaint呼叫結束:
  EndPaint (hwnd, &ps) ;
  在這兩個呼叫中,第一個參數都是程式的視窗控制代碼,第二個參數是指向型態為 PAINTSTRUCT 的結構指標。
  PAINTSTRUCT結構中包含一些視窗訊息處理常式,可以用來更新顯示地區的內容。我們將在下一章中討論該結
  構的各個欄位。現在我們只在BeginPaint和 EndPaint函數中用到它。*/
          hdc = BeginPaint (hwnd, &ps) ;
         
          GetClientRect (hwnd, &rect) ;
         
          DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
                    DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
         
          EndPaint (hwnd, &ps) ;
          return 0 ;
         
     case WM_DESTROY://關閉表單的訊息
          PostQuitMessage (0) ;//該函數在程式的訊息佇列中插入一個 WM_QUIT 訊息。前面提到過,GetMessage 對於除了   WM_QUIT 之外的從訊息佇列中取出的所有訊息都傳回非 0值。而當GetMessage 得到一個 WM_QUIT 訊息時,它傳回 0。這將導 致WinMain 退出訊息迴圈,並終止程式。然後程式執行下面的敘述:
          return 0 ;
     }
  //有時候,DefWindowProc處理完訊息後會產生其它的訊息。例如,假設使用者執行 HELLOWIN,並且使用者最
  //終單擊了 Close按鈕,或者假設用鍵盤或滑鼠從系統功能表中選擇了 Close, DefWindowProc 處理這一鍵盤或者
  //滑鼠輸入, 在檢測到使用者選擇了 Close選項之後, 它給視窗訊息處理常式發送一條 WM_SYSCOMMAND訊息。WndProc這個訊息傳給DefWindowProc。DefWindowProc 給視窗訊息處理常式發送一條 WM_CLOSE訊息來響
  //應之。WndProc 再次將它傳給 DefWindowProc。DestroyWindow呼叫DestroyWindow 來響應這條 WM_CLOSE 消
  //息。DestroyWindow導致Windows給視窗訊息處理常式發送一條 WM_DESTROY 訊息。WndProc 再呼叫
  //PostQuitMessage,將一條WM_QUIT訊息放入訊息佇列中,以此來響應此訊息。這個訊息導致 WinMain中的消
  //息迴圈終止,然後程式結束。
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.