孫鑫VC++講座筆記-(1)Windows程式內部運行機制

來源:互聯網
上載者:User

1,windows程式設計是種事件驅動方式的程式設計,主要基於訊息的。當使用者需要完成某種功能時,需要調用OS某種支援,然後OS將使用者的需要封裝成訊息,並投入到訊息佇列中,最後應用程式從訊息佇列中取走訊息並進行響應。
2,訊息結構:
typedef struct tagMSG {     // msg
    HWND   hwnd;     //接收訊息的視窗控制代碼。和哪個視窗相關聯。
    UINT   message;  //訊息標識。訊息本身是什麼。
    WPARAM wParam;   //訊息的附加資訊。具體取決於訊息本身。  
    LPARAM lParam;
    DWORD  time;     //訊息投遞時間。 
    POINT  pt;       //訊息投遞時,游標在螢幕上的位置。 
} MSG;

3,訊息佇列:
每個應用程式OS都為它建立一個訊息佇列,訊息佇列是個先進先出的緩衝區,其中每個元素都是一個訊息,OS將產生的每個訊息按先後順序放進訊息佇列中,應用程式總是取走當前訊息佇列中的第一條訊息,應用程式取走訊息後便知道使用者的操作和程式的狀態,然後對其處理即訊息響應,訊息響應通過編碼實現。

4,使用VC編程除了良好的C基礎外還需要掌握兩方面:
一,訊息本身。不同訊息所代表的使用者操作和應用程式的狀態。
二,對於某個特定的訊息來說,要讓OS執行某個特定的功能去響應訊息。

5,Window程式入口:
int WINAPI WinMain(
  HINSTANCE hInstance,  // 當前案例控制代碼。
  HINSTANCE hPrevInstance,  // 先前案例控制代碼。
  LPSTR lpCmdLine,      // 命令列指標
  int nCmdShow          // (視窗)顯示的狀態
);
說明:WinMain函數是Windows程式進入點函數,由OS調用,當OS啟動應用程式的時候,winmain函數的參數由OS傳遞的。

6,建立一個完整的視窗需要經過下面四個操作步驟:
一,設計一個視窗類別;如:WNDCLASS wndcls;
二,註冊視窗類別;    如:RegisterClass(&wndcls);
三,建立視窗;      如:CreateWindow(),CreateWindowEX();
四,顯示及更新視窗。如:ShowWindow(),UpdateWindow();

說明:建立視窗的時候一定要基於已經註冊的視窗類別.

7,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;

8,視窗類別註冊:
ATOM RegisterClass(
  CONST WNDCLASS *lpWndClass   // address of structure with class
                               // data
);

9,建立視窗:
HWND CreateWindow(
  LPCTSTR lpClassName,  // pointer to registered class name
  LPCTSTR lpWindowName, // pointer to window name
  DWORD dwStyle,        // window style
  int x,                // horizontal position of window
  int y,                // vertical position of window
  int nWidth,           // window width
  int nHeight,          // window height
  HWND hWndParent,      // handle to parent or owner window
  HMENU hMenu,          // handle to menu or child-window identifier
  HANDLE hInstance,     // handle to application instance
  LPVOID lpParam        // pointer to window-creation data
);

10,顯示和更新視窗視窗:
BOOL ShowWindow(
  HWND hWnd,     // handle to window
  int nCmdShow   // show state of window
);
BOOL UpdateWindow(
  HWND hWnd   // handle of window
);

11,訊息迴圈:
MSG msg;
while(GetMessage(&msg,...))    //從訊息佇列中取出一條訊息
{
 TranslateMessage(&msg); //進行訊息(如鍵盤訊息)轉換
 DispatchMessage(&msg); //指派訊息到視窗的回呼函數處理,(OS調用視窗回呼函數進行處理)。
}

其中:
//**The GetMessage function retrieves a message from the calling thread's message queue and places it in the specified structure.
//**If the function retrieves a message other than WM_QUIT, the return value is nonzero.If the function retrieves the WM_QUIT message, the return value is zero. If there is an error, the return value is -1.

BOOL GetMessage(
  LPMSG lpMsg,         // address of structure with message
  HWND hWnd,           // handle of window
  UINT wMsgFilterMin,  // first message
  UINT wMsgFilterMax   // last message
);

//The TranslateMessage function translates virtual-key messages into character messages. The character messages are posted to the calling thread's message queue, to be read the next time the thread calls the GetMessage or PeekMessage function.
BOOL TranslateMessage(
  CONST MSG *lpMsg   // address of structure with message
);

//The DispatchMessage function dispatches a message to a window procedure.
LONG DispatchMessage(
  CONST MSG *lpmsg   // pointer to structure with message
);

12,視窗過程函數(回呼函數)原型:
The WindowProc function is an application-defined function that processes messages sent to a window. The WNDPROC type defines a pointer to this callback function. WindowProc is a placeholder(預留位置) for the application-defined function name.

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++|...)

在視窗過程函數中通過一組switch語句來對訊息進行處理:
如:
LRESULT CALLBACK WindowProc( 
  HWND hwnd,
  UINT uMsg,
  WPARAM wParam,
  LPARAM lParam  
)
{
    switch(uMsg)
    {
 case WM_PAINT:
  ...
  break;
 case ...
  break;
 case WM_CLOSE:
  //DestroyWindow(hwnd);
   //銷毀視窗,並發送WM_DESTROY訊息。
  break;
 case WM_DESTROY:
  //PostQuitMessage(0);
  //發送WM_QUIT訊息到訊息佇列中,請求終止。
         //GetMessage()取到WM_QUIT訊息後,返回0,退出訊息循                //   環,從而終止應用程式。
  break;
 default:
  return DefWindowProc(hwnd,uMsg,wParam,lParam);
 //用預設的視窗過程處理我們不感興趣的訊息(其它訊息)。
 //這是必須的。
    }//switch
 return 0;
}//WindowProc

13,DestroyWindow()函數和PostQuitMessage()函數原型:
//**The DestroyWindow function destroys the specified window. The function sends WM_DESTROY and WM_NCDESTROY messages。

BOOL DestroyWindow(
  HWND hWnd   // handle to window to destroy
);

//**The PostQuitMessage function indicates to the system that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message.
//**The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates(預示,通知) to the system that the thread is requesting to quit at some time in the future.

When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system.

VOID PostQuitMessage(
  int nExitCode   // exit code
);

14,關於DC控制代碼擷取:
a)使用BeginPaint(),EndPaint()對。注意只能在響應WM_PAINT訊息時使用。
b)使用GetDc(),ReleaseDC()對。注意他們不能在響應WM_PAINT中使用。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.