Windows桌面应用程序(1-2-2-3rd) 编写窗口过程

DispatchMessage函数调用作为消息目标的窗口的窗口过程。窗口过程有以下签名。

LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);

有四个参数:

  • hwnd是窗口的句柄。
  • uMsg是消息代码;例如,WM_SIZE消息指示窗口被调整大小。
  • wParamlParam包含与消息有关的附加数据。确切的含义取决于消息代码。

LRESULT是您的程序返回到Windows的整数值。它包含您的程序对特定消息的响应。这个值的含义取决于消息代码。CALLBACK是函数的调用约定。
一个典型的窗口过程只是一个大的switch语句,用来处理消息代码。为每个要处理的消息添加”case”。

switch(uMsg){
    case WM_SIZE: // Handle window resizing
        // etc
}

消息的其他数据包含在lParamwParam参数中。这两个参数都是指针宽度(32位或64位)大小的整数值。每个的含义取决于消息代码(uMsg)。对于每条消息,您将需要在MSDN上查找消息代码,并将参数转换为正确的数据类型。通常数据是一个数值或者一个指向结构体的指针。有些消息没有任何数据。
例如WM_SIZE消息的文档指出:

  • wParam是一个标志,指示窗口是最小化,最大化还是调整大小。
  • lParam将窗口的新宽度和高度作为16位值打包到一个32位或64位数中。您将需要执行一些位移来获取这些值。幸运的是,头文件WinDef.h包含了帮助程序宏。

一个典型的窗口过程处理数十条消息,所以它可以长得很长。让代码更加模块化的一种方法是将处理每条消息的逻辑放在一个单独的函数中。在窗口过程中,将wParamlParam参数转换为正确的数据类型,并将这些值传递给函数。例如,要处理WM_SIZE消息,窗口过程将如下所示:

LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam){
    switch(uMsg){
        case WM_SIZE:
            {
                int width=LOWORD(lParam);// Macro to get the low-order word.
                int height=HIWORD(lParam);// Macro to get the high-order word.
                // Respond to the message:
                OnSize(hwnd,(UINT)wParam,width,height);
            }
            break;
    }
}
void OnSize(HWND hwnd,UINT flag,int width,int height){
    // Handle resizing
}

LOWORDHIWORD宏从lParam获得16位宽度和高度值。(您可以在MSDN文档中为每个消息代码查找这些类型的细节。)窗口过程提取宽度和高度,然后将这些值传递给OnSize函数。
默认消息处理
如果在窗口过程中不处理特定的消息,则将消息参数直接传递给DefWindowProc函数。此函数执行消息的默认操作,该操作因消息类型而异。

return DefWindowProc(hwnd,uMsg,wParam,lParam);

避免窗口过程中的瓶颈
当您的窗口过程执行时,它会阻止在同一线程上创建的任何其他窗口消息。因此,避免在窗口过程中进行冗长的处理。例如,假设你的程序打开一个TCP连接并且无限等待服务器响应。如果在窗口过程中执行该操作,则在请求完成之前,您的UI将不会响应。在此期间,窗口无法处理鼠标或键盘输入,重新绘制,甚至关闭。
相反,您应该使用内置于Windows中的多任务处理工具之一将工作移至另一个线程:

  • 创建一个新的线程。
  • 使用线程池。
  • 使用异步I/O调用。
  • 使用异步过程调用。

下一个
绘画窗口


原文链接:Writing the Window Procedure

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值