为什么在 WIN32 项目中需要 MyRegisterClass() 函数?

无技能

在 Visual Studio 在创建 Win32 项目时生成的默认代码中,有一个名为MyRegisterClass的函数,带有注释:

//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;
    ...
    return RegisterClassEx(&wcex);
}

但是这个函数使用了在 Windows 95 之前不存在的 RegisterClassEx。我真的不明白这个评论。他们是什么意思?

拥有MyRegisterClass函数的主要目的是什么,为什么它对与早期版本的 Windows 兼容如此必要?

科迪格雷

MyRegisterClass函数是一个辅助函数。封装了对 API 函数的调用RegisterClass[Ex],因为为了进行调用需要完成很多杂乱的参数设置。完整的函数定义如下所示:

ATOM MyRegisterClass(HINSTANCE hInstance)
{
  WNDCLASSEX wcex;

  wcex.cbSize         = sizeof(WNDCLASSEX);
  wcex.style          = CS_HREDRAW | CS_VREDRAW;
  wcex.lpfnWndProc    = WndProc;
  wcex.cbClsExtra     = 0;
  wcex.cbWndExtra     = 0;
  wcex.hInstance      = hInstance;
  wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYAPP));
  wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
  wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
  wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_MYAPP);
  wcex.lpszClassName  = szWindowClass;
  wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

  return RegisterClassEx(&wcex);
}

将它提取到一个辅助函数中——而不是内联它——使您的代码保持干净和更具可读性。就性能而言,如果合适,编译器将自动内联它。

将此作为辅助函数有意义的另一个原因是历史性的,这就是评论中所描述的:

//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.

您会看到,ExAPI 上后缀表示“扩展”。RegisterClassEx函数是在 32 位 Windows(API v4.0,Windows 95)中引入的。回到 16 位 Windows,只有RegisterClass. 32 位 Windows 支持这两种变体,以实现向后兼容性,但RegisterClassEx添加的“扩展”是设置小图标的能力。如果你想要漂亮的小图标(而不是丑陋的,由大图标的低质量拉伸算法生成),你需要调用RegisterClassEx. 但是如果你想以 16 位 Windows 为目标,你不能调用RegisterClassEx; 你需要坚持RegisterClass因此,如果您将调用封装RegisterClass[Ex]在一个辅助函数中,您可以轻松修改代码,更改它调用的 API 函数,从而更改您的应用程序可以定位的 Windows 版本。

评论试图传达此信息,但在表达自己方面做得相对较差。

今天你可以完全忽略这一点。没有人再以 16 位 Windows 为目标。总是调用RegisterClassEx,忘记它RegisterClass甚至存在。这并没有消除将此代码封装在函数中以提高可读性的优势。

此外,请注意,与 Visual Studio 捆绑在一起的默认 Win32 项目模板将小图标和大图标分开在单独的 ICO 文件中,从而为它们分配单独的资源 ID。这可能是出于相同的历史原因完成的,因此您可以为 16 位 Windows 编译而不会受到小图标的阻碍,但今天再次完全没有必要。您可以将两个图标组合成一个 ICO 文件,并有选择地加载它们:

ATOM MyRegisterClass(HINSTANCE hInstance)
{
  WNDCLASSEX wcex;

  wcex.cbSize         = sizeof(wcex);
  wcex.style          = CS_HREDRAW | CS_VREDRAW;
  wcex.lpfnWndProc    = WndProc;
  wcex.cbClsExtra     = 0;
  wcex.cbWndExtra     = 0;
  wcex.hInstance      = hInstance;
  wcex.hIcon          = (HICON)LoadImage(hInstance,
                                         MAKEINTRESOURCE(IDI_MYAPP),
                                         IMAGE_ICON,
                                         GetSystemMetrics(SM_CXICON),
                                         GetSystemMetrics(SM_CYICON),
                                         LR_DEFAULTCOLOR | LR_SHARED);
  wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
  wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_MYAPP);
  wcex.lpszClassName  = szWindowClass;
  wcex.hIconSm        = (HICON)LoadImage(hInstance,
                                         MAKEINTRESOURCE(IDI_MYAPP),
                                         IMAGE_ICON,
                                         GetSystemMetrics(SM_CXSMICON),
                                         GetSystemMetrics(SM_CYSMICON),
                                         LR_DEFAULTCOLOR);

  return RegisterClassEx(&wcex);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我的win32程序需要提升?

来自分类Dev

即使使用cmath include也无法在Win32 C ++项目中找到round函数

来自分类Dev

Win32 API函数GetExplicitEntriesFromAcl()的对应项是什么?

来自分类Dev

当我使用参数调用Win32函数时,为什么GCC使用帧指针?

来自分类Dev

为什么在用Win32 GDI绘图时需要将句柄保存到旧的位图?

来自分类Dev

为什么在用Win32 GDI绘图时需要将句柄保存到旧的位图?

来自分类Dev

GetMenuBarInfo()Win32函数

来自分类Dev

调用dll函数,该函数需要从python指向句柄(win32)的指针

来自分类Dev

从LLVM调用Win32 / 64函数的正确方法是什么?

来自分类Dev

什么是TCHAR字符串以及Win32 API函数的“ A”或“ W”版本?

来自分类Dev

从Julia调用Win32函数

来自分类Dev

为什么Win32没有僵尸线程问题?

来自分类Dev

为什么Win32没有僵尸线程问题?

来自分类Dev

为什么需要构造函数?

来自分类Dev

什么是Win32消息编组?

来自分类Dev

为什么在Delphi项目中需要midas.dll?

来自分类Dev

调用win32 API并回调类函数

来自分类Dev

C中的win32 FillRect()函数问题

来自分类Dev

C中的win32 FillRect()函数问题

来自分类Dev

嵌套的构造函数。为什么需要它?

来自分类Dev

为什么在OOP中需要构造函数?

来自分类Dev

为什么wait()函数需要更多参数?

来自分类Dev

为什么ObjectDataSource需要函数的可选参数?

来自分类Dev

为什么调用函数需要返回“未来”?

来自分类Dev

嵌套的构造函数。为什么需要它?

来自分类Dev

为什么内联函数需要传递参数?

来自分类Dev

为什么文件更改时Perl的Win32 :: ChangeNotify会引发两个事件?

来自分类Dev

为什么单击编辑框关闭Win32窗口(C ++)?

来自分类Dev

为什么不能在Win32中启用unicode编辑控件?

Related 相关文章

  1. 1

    为什么我的win32程序需要提升?

  2. 2

    即使使用cmath include也无法在Win32 C ++项目中找到round函数

  3. 3

    Win32 API函数GetExplicitEntriesFromAcl()的对应项是什么?

  4. 4

    当我使用参数调用Win32函数时,为什么GCC使用帧指针?

  5. 5

    为什么在用Win32 GDI绘图时需要将句柄保存到旧的位图?

  6. 6

    为什么在用Win32 GDI绘图时需要将句柄保存到旧的位图?

  7. 7

    GetMenuBarInfo()Win32函数

  8. 8

    调用dll函数,该函数需要从python指向句柄(win32)的指针

  9. 9

    从LLVM调用Win32 / 64函数的正确方法是什么?

  10. 10

    什么是TCHAR字符串以及Win32 API函数的“ A”或“ W”版本?

  11. 11

    从Julia调用Win32函数

  12. 12

    为什么Win32没有僵尸线程问题?

  13. 13

    为什么Win32没有僵尸线程问题?

  14. 14

    为什么需要构造函数?

  15. 15

    什么是Win32消息编组?

  16. 16

    为什么在Delphi项目中需要midas.dll?

  17. 17

    调用win32 API并回调类函数

  18. 18

    C中的win32 FillRect()函数问题

  19. 19

    C中的win32 FillRect()函数问题

  20. 20

    嵌套的构造函数。为什么需要它?

  21. 21

    为什么在OOP中需要构造函数?

  22. 22

    为什么wait()函数需要更多参数?

  23. 23

    为什么ObjectDataSource需要函数的可选参数?

  24. 24

    为什么调用函数需要返回“未来”?

  25. 25

    嵌套的构造函数。为什么需要它?

  26. 26

    为什么内联函数需要传递参数?

  27. 27

    为什么文件更改时Perl的Win32 :: ChangeNotify会引发两个事件?

  28. 28

    为什么单击编辑框关闭Win32窗口(C ++)?

  29. 29

    为什么不能在Win32中启用unicode编辑控件?

热门标签

归档