WinMain與WndProc以及窗口誕生過程總結


一、int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nCmdShow)

  1. 四個參數:
    1. hInstance:程序當前實例的句柄(handle to current instance),以后隨時可以用GetModuleHandle(0)來獲得
    2. hPrevInstance:前一個實例的句柄(handle to previous instance),在Win32中,每一個進程都有一個獨立的4G地址空間,從0到2G屬於進程私有,對其他進程來說是不可見的。所以,在Win32中,hPrevInstance總是為NULL。
    3. szCmdLine:指向以/0結尾的命令行,不包括EXE本身的文件名(pointer to command line),以后隨時可以用GetCommandLine()來獲取完整的命令行。
    4. iCmdShow:指明應該以什么方式顯示主窗口(show state of window)。
  2. 宏定義:
    1. WINAPI:#define WINAPI      __stdcall    表示函數調用遵循__stdcall規則
    2. HINSTANCE:

      DECLARE_HANDLE(HINSTANCE);
      typedef HINSTANCE HMODULE;

      #define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name

    3. LPSTR:typedef _Null_terminated_ CHAR *NPSTR, *LPSTR, *PSTR;  就是一個以/0結尾的字符串

      #ifndef VOID
      #define VOID void
      typedef char CHAR;

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

  1. 參數:
    1. hwnd:窗口句柄
    2. message:消息ID
    3. wParam和lParam:消息參數
  2. 宏定義:
    1. LRESULT、WPARAM、LPARAM:

      typedef UINT_PTR WPARAM;
      typedef LONG_PTR LPARAM;
      typedef LONG_PTR LRESULT;

      typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;

      typedef _W64 long LONG_PTR, *PLONG_PTR;

    2. CALLBACK:#define CALLBACK    __stdcall
    3. HWND:DECLARE_HANDLE            (HWND);   與HINSTANCE的定義類似
    4. UINT:typedef unsigned int        UINT;

三、窗口誕生過程總結

  1. 定義窗口類結構(WNDCLASS)
    1. #ifdef UNICODE
      typedef WNDCLASSW WNDCLASS;
      typedef PWNDCLASSW PWNDCLASS;
      typedef NPWNDCLASSW NPWNDCLASS;
      typedef LPWNDCLASSW LPWNDCLASS;
      #else
      typedef WNDCLASSA WNDCLASS;
      typedef PWNDCLASSA PWNDCLASS;
      typedef NPWNDCLASSA NPWNDCLASS;
      typedef LPWNDCLASSA LPWNDCLASS;
      #endif // UNICODE

    2. 結構成員:

      typedef struct tagWNDCLASSW {
      UINT style;                          //窗口類型
      WNDPROC lpfnWndProc;      //窗口過程(必須是回調函數)
      int cbClsExtra;                    //預留的額外空間,一般為0
      int cbWndExtra;                  //預留的額外空間,一般為0
      HINSTANCE hInstance;         //應用程序的實例句柄
      HICON hIcon;                      //為所有基於該窗口類的窗口設定一個圖標
      HCURSOR hCursor;              //為所有基於該窗口類的窗口設定一個鼠標指針
      HBRUSH hbrBackground;      //指定窗口背景色
      LPCWSTR lpszMenuName;     //指定窗口菜單
      LPCWSTR lpszClassName;     //指定窗口類名
      } WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;

  2. 注冊窗口類
    1. RegisterClass:注冊在隨后調用CreateWindow函數和CreateWindowEx函數中使用的窗口類。
    2. 參數為lpWndClass,指向一個WNDCLASS結構的指針
    3. 返回值:ATOM的宏定義
      typedef WORD ATOM;
      typedef unsigned short WORD;
    4. 關於RegisterClassEx:參數lpwcx指向一個WNDCLASSEX結構的指針如果函數成功,返回這個窗口類型的標識號;如果函數失敗,返回值為0。若想獲得更多錯誤信息,請調用GetLastError函數。
  3. 創建窗口
    1. HWND WINAPI CreateWindow(
      _In_opt_   LPCTSTR  lpClassName, // 窗口類名稱
      _In_opt_   LPCTSTR  lpWindowName, // 窗口標題
      _In_       DWORD     dwStyle, // 窗口風格,或稱窗口格式
      _In_       int       x, // 初始 x 坐標
      _In_       int       y, // 初始 y 坐標
      _In_       int       nWidth, // 初始 x 方向尺寸
      _In_       int       nHeight, // 初始 y 方向尺寸
      _In_opt_   HWND    hWndParent, // 父窗口句柄
      _In_opt_   HMENU   hMenu, // 窗口菜單句柄
      _In_opt_   HINSTANCE   hInstance, // 程序實例句柄
      _In_opt_   LPVOID   lpParam // 創建參數
      );

    2. _In_說明該參數是輸入的,_opt_說明該參數是可選參數
    3. 函數成功返回窗口句柄,否則返回NULL
  4. 顯示窗口

    BOOL WINAPI ShowWindow(
    _In_ HWND hWnd,
    _In_ int nCmdShow
    );

    1. 第一次調用時應使用WinMain的參數nCmdShow作為參數
    2. 如果窗口之前可見,則返回非0否則返回0
  5. 更新窗口

    BOOL UpdateWindow(
    _In_ HWND hWnd
    );

    1. 繞過消息隊列直接向窗口過程發送WM_PAINT消息
    2. 函數調用成功返回非0
  6. 消息循環
    1. BOOL WINAPI GetMessage(
      _Out_ LPMSG lpMsg,        //指向MSG結構
      _In_opt_ HWND hWnd,    //需要檢索消息窗口的句柄,為NULL時檢索所有的當前線程的窗口消息和線程消息,為-1時只檢索當前線程消息
      _In_ UINT wMsgFilterMin,  //指定被檢索的最小消息值得整數
      _In_ UINT wMsgFilterMax  //指定被檢索的最大消息值得整數
      );

      1. 作用:從當前線程的消息隊列里取出一個消息並放入MSG結構中,不能獲得其他線程的消息
      2. 若消息隊列為空,函數會一直等待到有消息到來才有返回值
      3. 返回值:
        1. 函數出現錯誤則返回-1,
        2. 獲得WM_QUIT消息返回0
        3. 否則返回非0
    2. BOOL WINAPI TranslateMessage(
      _In_ const MSG *lpMsg
      );

      1. 該函數將虛擬鍵消息轉換為字符消息。字符消息被寄送到調用線程的消息隊列里,當下一次線程調用函數GetMessage或PeekMessage時被讀出。
    3. LRESULT WINAPI DispatchMessage(
      _In_ const MSG *lpmsg
      );

      1. 分派一個消息給窗口過程
      2. 返回值為窗口過程返回的值,通常被忽略


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM