WinMain与WndProc以及窗口诞生过程总结

摘要:
因此,在Win32中,hPrevInstance始终为NULL。SzCmdLine:指向以/0结尾的命令行,不包括EXE本身的文件名。您可以在将来的任何时候使用GetCommandLine()获取完整的命令行。ICmdShow:指示主窗口的显示方式。参数为lpWndClass,指向WNDCLASS结构的指针返回一个值:ATOM宏定义typedefWORDATOM;typedefensignedshortWORD;关于RegisterClassEx:参数lpwcx指向WNDCLASSEX结构。如果函数成功,则返回窗口类型的ID;如果函数失败,则返回值为0。有关更多错误信息,请调用GetLastError函数。

一、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. 返回值为窗口过程返回的值,通常被忽略

免责声明:文章转载自《WinMain与WndProc以及窗口诞生过程总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇sql 临时表的使用详解android fragment轻松监听返回键/Fragment中的popupwindow响应返回键隐藏下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

redis基础数据结构源码浅析

基于redis 5.0.6 先列个表格 类型 实现 string sds list quicklist set intset hashtable zset ziplist skiplist+hashtable hash ziplist hashtable string redis的string(字符串)实现称为SDS(...

wParam与lParam的区别

wParam与lParam的区别 lParam 和 wParam 是宏定义,一般在消息函数中带这两个类型的参数,通常用来存储窗口消息的参数。 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);wParam 通常用来存储小段信息,如,标志lParam...

iOS 枚举类型学习

一,两者的用法 枚举类型定义用关键字enum标识,形式为:enum 标识符{ 枚举数据表 };枚举数据(枚举常量)是一些特定的标识符,标识符代表什么含义,完全由程序员决定。数据枚举的顺序规定了枚举数据的序号,从0开始,依次递增。enum status{ copy, delete };枚举类型status仅有两个数据,一个是copy,一个是delete,序号...

嵌入式Linux学习笔记(四) 设备树和UART驱动开发

目录 (1).参考资料 (2).Uart硬件配置 (3).设备树的说明和修改 (4).测试代码     通过完成LED的驱动,我们熟悉了驱动编写的大致结构框架,然而在实际开发中,嵌入式Linux和普通单片机最大的不同就是提供大量的代码,满足大部分的应用需求,如本节中,我们使用的UART驱动已经被集成到内核。不过通过对底层驱动更高级的抽象,使用设备树实现了底...

C++里大写TRUE和小写true区别

1.C++里有区别true是bool型的;TRUE是int型的,VC里这个是ms自己定义的; C++规定不允许只通过返回类型不同区别两个函数================================================你写错了吧……原函数声明是virtual BOOL InitInstance( );你函数声明是bool,麻烦把它写成...

iOS中Block的用法,举例,解析与底层原理

1. 前言 Block:带有自动变量(局部变量)的匿名函数。它是C语言的扩充功能。之所以是拓展,是因为C语言不允许存在这样匿名函数。 1.1 匿名函数 匿名函数是指不带函数名称函数。C语言中,函数是怎样的呢?类似这样: int func(int count); 调用的时候: int result = func(10); func就是它的函数名。也可以通...