VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 415|回复: 2

[扩展阅读] 窗口函数 WindowProc 和 默认窗口函数 DefWindowProc

[复制链接]
51_avatar_middle
最佳答案
82 
online_admins 发表于 2019-12-15 21:33:29 | 显示全部楼层 |阅读模式
在Windows操作系统里,当窗口显示之后,它就可以接收到系统源源不断地发过来的消息,然后窗口就需要处理这些消息,因此就需要一个函数来处理这些消息。
在API里定义了一个函数为回调函数,当系统需要向窗口发送消息时,就会调用窗口给出的回调函数WindowProc,如果WindowProc函数不处理这个消息,就可以把它转向DefWindowProc函数来处理,这是系统的默认消息处理函数。当你按下菜单,或者点击窗口时,窗口需要运行这个消息处理函数。

窗口函数 WindowProc 声明如下:
  1. LRESULT CALLBACK WindowProc(
  2.     HWND hwnd,
  3.     UINT uMsg,
  4.     WPARAM wParam,
  5.     LPARAM lParam
  6. );
复制代码


hwnd 是当前窗口的句柄;
uMsg 是系统发过来的消息;
wParam 是消息参数;
lParam 是消息参数。

这个函数一定是静态函数,也就是全局函数,在编译时已经确定了地址。由于它需要设置在注册的窗口类型里,如下:
注册窗口类,指定窗口类的名称与窗口回调函数
  1. WNDCLASSEX wcex = { 0 };
  2. wcex.cbSize = sizeof(WNDCLASSEX);
  3. wcex.lpfnWndProc = WindowProc;
  4. wcex.lpszClassName = szWindowClass;

  5. if (!RegisterClassEx(&wcex))
  6. {
  7.         MessageBox(NULL, _T("注册窗口类失败"), _T("Tip"), NULL);
  8.         return 1;
  9. }
复制代码


默认窗口函数 DefWindowProc 声明如下:
  1. LRESULT DefWindowProc(
  2.     HWND hWnd,
  3.     UINT Msg,
  4.     WPARAM wParam,
  5.     LPARAM lParam
  6. );
复制代码


这个函数参数跟上面那个函数是一样的。只不过,它是处理所有默认的消息。

调用这两个函数的实例如下:
  1. #include <windows.h>
  2. #include <tchar.h>

  3. static TCHAR szWindowClass[] = _T("WindowClass");
  4. static TCHAR szTitle[] = _T("我在VC驿站的第一个窗口程序");

  5. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  6. {
  7.         PAINTSTRUCT ps;
  8.         HDC hdc;
  9.         TCHAR greeting[] = _T("你好,世界!");

  10.         switch (uMsg)
  11.         {
  12.         case WM_PAINT:
  13.                 hdc = BeginPaint(hwnd, &ps);
  14.                 TextOut(hdc, 5, 5, greeting, _tcslen(greeting));
  15.                 EndPaint(hwnd, &ps);
  16.                 break;
  17.         case WM_DESTROY:
  18.                 PostQuitMessage(0);
  19.                 break;
  20.         default:
  21.                 return DefWindowProc(hwnd, uMsg, wParam, lParam);
  22.                 break;
  23.         }
  24.         return 0;
  25. }
复制代码

  1. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  2. {
  3.         //第一步:注册窗口类,指定窗口类的名称与窗口回调函数
  4.         WNDCLASSEX wcex = { 0 };
  5.         wcex.cbSize = sizeof(WNDCLASSEX);
  6.         wcex.lpfnWndProc = WindowProc;
  7.         wcex.lpszClassName = szWindowClass;

  8.         if (!RegisterClassEx(&wcex))
  9.         {
  10.                 MessageBox(NULL, _T("注册窗口类失败"), _T("Tip"), NULL);
  11.                 return 1;
  12.         }

  13.         //第二步:创建窗口,指定注册窗口类,窗口标题,窗口的大小
  14.         HWND hWnd = CreateWindow(
  15.                 szWindowClass,
  16.                 szTitle,
  17.                 WS_OVERLAPPEDWINDOW,
  18.                 CW_USEDEFAULT, CW_USEDEFAULT,
  19.                 500, 300,
  20.                 NULL,
  21.                 NULL,
  22.                 hInstance,
  23.                 NULL
  24.                 );

  25.         if (!hWnd)
  26.         {
  27.                 MessageBox(NULL, _T("创建窗口失败!"), _T("Tip"), NULL);
  28.                 return 1;
  29.         }

  30.         //第三步:显示窗口
  31.         ShowWindow(hWnd, nCmdShow);

  32.         //第四步:开始消息循环
  33.         MSG msg = { 0 };
  34.         while (GetMessage(&msg, NULL, 0, 0))
  35.         {
  36.                 TranslateMessage(&msg);
  37.                 DispatchMessage(&msg);
  38.         }

  39.         return (int)msg.wParam;
  40. }
复制代码






上一篇:RegisterClassEx 函数说明
下一篇:ShowWindow 函数说明
51_avatar_middle
最佳答案
2 
在线会员 发表于 2020-3-1 08:44:49 | 显示全部楼层
祝VC驿站越办越好!...
72_avatar_middle
最佳答案
2 
在线会员 发表于 2020-4-25 22:59:29 | 显示全部楼层
祝VC驿站越办越好
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )|网站地图wx_jqr

GMT+8, 2020-9-30 01:07

Powered by CcTry.CoM

© 2009-2020 cctry.com

快速回复 返回顶部 返回列表