孫鑫VC++視頻學習筆記之1: Windows程序內部運行機制


   一、windows是事件驅動方式的程序設計
  windows程序設計是種事件驅動方式的程序設計,主要基於消息的。當用戶需要完成某種功能時,需要調用OS某種支持,然後OS將用戶的需要包裝成消息,並投入到消息隊列中,最後應用程序從消息隊列中取走消息並進行響應。
  
   二、消息隊列
   每個應用程序OS都爲它建立一個消息隊列,消息隊列是個先進先出的緩衝區,其中每個元素都是一個消息,OS將生成的每個消息按先後順序放進消息隊列中, 應用程序總是取走當前消息隊列中的第一條消息,應用程序取走消息後便知道用戶的操作和程序的狀態,然後對其處理即消息響應,消息響應通過編碼實現。
  
   三、Window程序入口
  WinMain函數是Windows程序入口點函數,由OS調用,當OS啓動應用程序的時候,winmain函數的參數由OS傳遞的。
  
   四、創建一個完整的窗口需要經過下面四個操作步驟
  
  1, 設計一個窗口類。如:WNDCLASS wndcls。
  2, 註冊窗口類。如:RegisterClass(&wndcls)。
  3, 創建窗口。如:CreateWindow(),CreateWindowEX();
  4, 顯示及更新窗口。如:ShowWindow(),UpdateWindow();
  
  其他值得注意的地方
  
  1, 消息結構
  
  typedef struct tagMSG { // msg
   HWND hwnd; //接收消息的窗口句柄。和哪個窗口相關聯。
   UINT message; //消息標識。消息本身是什麼。
   WPARAM wParam; //消息的附加信息。具體取決於消息本身。
   LPARAM lParam;
   DWORD time; //消息投遞時間。
   POINT pt; //消息投遞時,光標在屏幕上的位置。
  } MSG;
  
  2, 掌握windows的消息機制
  
  需要掌握兩方面:(1)消息本身。不同消息所代表的用戶操作和應用程序的狀態。
  
  (2)對於某個特定的消息來說,要讓OS執行某個特定的功能去響應消息。
  
  3, Window入口函數說明
  
  int WINAPI WinMain(
   HINSTANCE hInstance, // 當前事例句柄。
   HINSTANCE hPrevInstance, // 先前事例句柄。32位系統中此值都爲NULL
   LPSTR lpCmdLine, // 命令行指針
   int nCmdShow // (窗口)顯示的狀態
  );
  
  要帶參調用WinMain,類似於命令行的功能,在ProjectèsettingèDebug頁èProgram arguments項填寫參數
  
  4, Windows提供的窗口類詳解
  
  typedef struct _WNDCLASS {
   UINT style; //窗口的類型
   WNDPROC lpfnWndProc; //窗口過程函數指針(回調函數)
   int cbClsExtra; //窗口類附加字節,爲該類窗口所共享。通常0。
   int cbWndExtra; //窗口附加字節。通常設爲0。
   HANDLE hInstance; //當前應用程序事例句柄。
   HICON hIcon; //圖標句柄 LoadIcon();
   HCURSOR hCursor; //光標句柄 LoadCursor();
   HBRUSH hbrBackground; //畫刷句柄 (HBRUSH)GetStockObject();
   LPCTSTR lpszMenuName; //菜單名字
   LPCTSTR lpszClassName; //類的名字
  } WNDCLASS;
  
  5, 消息循環:
  
  MSG msg;
  while(GetMessage(&msg,...)) //從消息隊列中取出一條消息
  {
   TranslateMessage(&msg); //進行消息(如鍵盤消息)轉換
   DispatchMessage(&msg); //分派消息到窗口的回調函數處理,(OS調用窗口回調函數進行處理)。
  }
  
  6, 回調函數
  
  LRESULT CALLBACK WindowProc( //這裏WindowProc是個代號名字。
   HWND hwnd, // handle to window
   UINT uMsg, // message identifier
   WPARAM wParam, // first message parameter
   LPARAM lParam // second message parameter
  );
  
  說明:兩種函數調用約定(__stdcall 和 __cdecl):
  #define CALLBACK __stdcall
  //__stdcall 標準調用預定,是PASCAL 調用約定,象DELPHI使用的就是標準調用約定
  #define WINAPIV __cdecl
  // __cdecl 是C 語言形式的調用約定。
  
  主要區別:函數參數傳遞順序 和 對堆棧的清除上。
   問題:除了那些可變參數的函數調用外,其餘的一般都是__stdcall約定。但 C/C++編譯默然的是__cdecl約定。所以如果在VC等環境中調用__stdcall約定的函數,必須要在函數聲明的時加上 __stdcall 修飾符,以便對這個函數的調用是使用__stdcall約定(如使用DELPHI編寫的DLL時候)。
  (VC中可通過這途徑修改:projectèsettingsèc/c++ècategary選”Code Generation”,出現Call convention選項,修改之)
  
  7, DC句柄的使用
  
  (1)使用BeginPaint(),EndPaint()對。注意只能在響應WM_PAINT消息時使用。
  (2)使用GetDc(),ReleaseDC()對。注意他們不能在響應WM_PAINT中使用。
  
  8, 其它
  
  (1)函數名代表函數的首地址。
  
  (2)創建窗口的時候一定要基於已經註冊的窗口類.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章