《Windows 程式設計》學習筆記(三) (轉)

worldblog發表於2007-12-13
《Windows 程式設計》學習筆記(三) (轉)[@more@]

第三章 視窗和訊息:namespace prefix = o ns = "urn:schemas--com::office" />

 

進行設計實際上是建立“視窗”和處理視窗訊息的過程,“視窗”物件不僅指應用程式視窗,還包括對話方塊,按鈕,單選鈕等許多許多。在Windows中,“視窗”是無所不在的。視窗以“訊息”的形式來接收的輸入的,而“訊息”是操作傳送給應用程式的。比如,我們用滑鼠按下一個按鈕時,Windows把按滑鼠的這個“訊息”告訴按鈕:“嘿!按鈕我現在正在按你呢!”,按鈕收到這個“訊息”後,想了想:“那我就臥倒吧。”這時我們就看到按鈕被滑鼠按下了。就這麼簡單!

每一個視窗是在特定的“視窗類”的基礎上建立的,視窗類中標識了“視窗過程”,而視窗是透過視窗過程接收和處理訊息的。視窗過程實際上是一個,函式的引數含有訊息的若干資訊,我們可以利用這些資訊來進行相應的處理。一個視窗可以接收到許多個訊息,這些訊息不能同時被視窗接收處理,它們就像在食堂打飯一樣按順序排成隊,一個一個被視窗處理,這就是“訊息列隊”;但是,也有例外的情況,如同一個人有急事可能插隊打飯,有些訊息可以直接傳送個視窗過程,不用放入訊息佇列中(用SendMessage函式)。

現在我知道了:建立一個視窗首先需要註冊一個視窗類,需要一個視窗過程來處理視窗訊息。書中的例子說明視窗和訊息到底是什麼,這個例子幾乎會出現在每一個Windows程式中,也就是說,每一個Windows程式都是以這個程式為基礎進行擴充的。熟悉它的每一個細節非常重要。(下面程式中的註釋幾乎解釋了每一條語句的意義)

#include

//申明視窗過程函式

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

//Windows程式的入口函式

int WIN WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

  PSTR szCmdLine, int iCmdShow)

{

  static TCHAR szAppName[] = TEXT ("HelloWin") ;

  HWND  hwnd ;//定義一個Windows控制程式碼的變數

  MSG  msg ;//定義一個訊息的結構變數

/  //第一步: 定義一個視窗類的結構,此結構中的10個域描述了視窗類的特徵,下面依次給這10個域賦值

  WNDCLASS  wndclass ;

  wndclass.style  = CS_HREDRAW | CS_VREDRAW ;//基於此視窗類建立的視窗風格

  wndclass.lpfnWndProc  = WndProc ;//指向視窗過程函式的指標

  wndclass.cbClsExtra  = 0 ;//視窗類結構的預留空間

  wndclass.cbWndExtra  = 0 ;//同上

  wndclass.hInstance  = hInstance ;//Windows程式的例項控制程式碼,這是由提供的

  //為所有基於這個視窗類建立的視窗設定一個圖示

   wndclass.hIcon  = LoadIcon (NULL, IDI_APPLICATION) ;

  //為所有基於這個視窗類建立的視窗設定一個滑鼠

  wndclass.hCursor  = LoadCursor (NULL, IDC_ARROW) ;

  //指定了基於這個視窗類建立的視窗背景顏色,用取得一個白色刷子的控制程式碼來實現

  wndclass.hbrBackground = (HBRUSH) GetStock (WHITE_BRUSH) ;

  //指定視窗類的選單,用NULL賦值表示這個程式中沒有選單

  wndclass.lpszMenuName  = NULL ;

  //指定視窗類的名稱

  wndclass.lpszClassName = szAppName ;

 

/   // 第二步:向Windows註冊一個視窗類,如果在下執行RegisterClass函式,將返回0表明有錯誤發生

if (!RegisterClass (&wndclass))

  {

  MessageBox (NULL, TEXT ("This program requires !"),

  szAppName, MB_ICONERROR) ;

  return 0 ;

  }

 //第三步:基於上面註冊的視窗類建立一個視窗,分配一塊儲存視窗的資訊

hwnd = CreateWindow (szAppName,  // 視窗類的名稱,基於這個視窗類建立視窗

  TEXT ("The Hello Program"), //視窗標題欄的名稱

  WS_OVERLAPPEDWINDOW,  // 視窗的風格

  CW_USEDEFAULT,  //視窗位置的X座標

  CW_USEDEFAULT,  //視窗位置的Y座標

   CW_USEDEFAULT,  //視窗大小寬

  CW_USEDEFAULT,  //視窗大小高

  NULL,  // 父視窗的控制程式碼

  NULL,  // 視窗選單的控制程式碼

  hInstance,   // Windows應用程式的例項控制程式碼

  NULL) ;  // 建立引數的指標,可以用它訪問程式中的資料

 //第四步:  //第四步:顯示視窗,在螢幕上顯示視窗(ShowWindow),並給視窗客戶區刷上背景顏色(UpdateWindow)

 ShowWindow (hwnd, iCmdShow) ;

 UpdateWindow (hwnd) ;

 

//此時視窗已經出現在顯示器上等待使用者的鍵盤和滑鼠的輸入,隨時進行相應的處理

/  //第五步:利用下面的迴圈,在訊息佇列中不斷解析訊息,然後Windows把訊息發給視窗過程函式進行相應的處理。

while (GetMessage (&msg, NULL, 0, 0))  //從訊息佇列中取得訊息

  {

  TranslateMessage (&msg) ;//msg結構傳給Windows,進行一些鍵盤轉換

  DispatchMessage (&msg) ; //Windows將訊息傳送給視窗過程函式(WndPro)進行相應的處理

  }

//上面迴圈的終止條件是:取得WM_QUIT訊息。

  return msg.wParam ;

  }

//定義視窗過程函式,在開發中,我們主要在這個函式中新增處理各種訊息的程式碼。

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 

{

  HDC  hdc ;

  PAINTSTRUCT ps ;

  RECT  rect ;

 

  switch (message)

  {

  case WM_CREATE:  //當建立一個視窗時,WindowsWndProc傳送WM_CREATE

  return 0 ;

  case WM_PAINT:  //當繪製視窗客戶區域時

  hdc = BeginPaint (hwnd, &ps) ;

  GetClientRect (hwnd, &rect) ;

  DrawText (hdc, TEXT ("Hello, !"), -1, &rect,

  DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;

  EndPaint (hwnd, &ps) ;

  return 0 ;

  case WM_DESTROY:  //清除視窗

  PostQuitMessage (0) ;

  return 0 ;

  }

  return DefWindowProc (hwnd, message, wParam, lParam) ;//訊息的預設處理

}

 

實際上Windows把訊息的處理機制封裝起來,使我們只要用視窗類去標識一個視窗過程函式(WndPro),就可以在這個過程函式中處理Windows向視窗傳送的各種訊息了。

最後,需要注意一個視窗類可以建立多個不同的視窗。

 

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992668/,如需轉載,請註明出處,否則將追究法律責任。

相關文章