Windows中的变量类型

时间:2016-09-28 22:57:06

标签: c++ windows winapi

只要存在不同大小的不同变量类型,为什么windows使用宏和移位运算符将2个值映射到一个变量中,例如:

这是win32 windows过程的示例:

//...
case WM_COMMAND:
{
    switch(LOWORD(wParam))
    {
        case IDC_LISTBOX:
        {
            switch(HIWORD(wParam))
            {
                //handle message
            }
        }
        break;
    }
}
break;

为什么Windows不使用两个类型的短变量? 或者这有特权?

谢谢你们

2 个答案:

答案 0 :(得分:5)

窗口消息只能传递2个整数(wParamlParam参数)。

整数值本身不需要跨模块/进程边界进行任何特殊编组,它们可以按原样传递。它们也非常小,可以存储在消息队列中等等。

特别针对WM_COMMANDlParam可能包含HWND值,因此其他消息值(通知代码和标识符)只能在wParam中传递。它们足够小,可以直接填入wParam,因此可以轻松传递3个值,只允许2个值。

替代方法需要为包含单独整数的结构分配内存,然后在其中一个消息参数中传递指向该结构的指针。许多窗口消息都是这样做的,但通常只有当发送方和接收方处于同一个进程时,否则它需要跨模块/进程边界封送结构数据,这对简单消息传递来说是很多开销。

它还使接收器的负担释放分配的内存,因为WM_COMMAND是通过接收窗口的消息队列的发布消息。发件人不等待处理消息,因此在发布消息后将无法释放结构内存。分配的内存必须在内存中保持活动状态,直到消息最终由接收窗口过程处理。

另一方面,发送的邮件直接进入窗口过程并阻止发件人处理,因此他们不必担心这一点,发件人可以在邮件发送后释放内存。但是,制作所有多值消息(尤其是状态消息)会对系统造成很大的瓶颈。

一般情况下,尽可能将较短的整数填充到较大的整数中会更容易,也更少开销,尤其是在发布的消息中(尽管发送的消息当然也可以这样做)。

答案 1 :(得分:2)

您的示例显示了在窗口messages上处理message queue的代码段。

可以在windows和windows对象之间发送大量different object types,并且消息结构必须处理所有这些不同的消息传递要求。例如

  • 对于工具栏通知NM_CHAR,Windows必须通过lParam中的其他信息传递某个结构的地址。
  • 要使用WM_SETHOTKEY设置热键,窗口只需要一个键值,而wParam的下半部分就足够了
  • 为了处理WM_COMMAND的命令,Windows根据命令需要更少的信息。

在理想的C ++世界中,我们可以为消息实现多态数据结构,只需要所需数据的相关字段。但是winapi不是C ++:它是为C而设计的,与大量语言的兼容性可以与C语言互操作。

在一个理想的C世界中,我们可以使用一个union,它需要在进行进一步处理之前首先对消息类型(在所有union成员之间共享)进行测试。例如,在WM_COMMAND处理中,您首先要检查公共消息类型。

此外,如果您使用工会,如果您必须重新发布邮件,则重复使用其参数,则复制完整工会。所以你可以复制不需要的东西。这是一个很小的开销,但消息循环(以及一般的OS功能)是执行大量时间的事情。所以每纳秒都很重要。只使用所需的数据并将其打包成单词和双字,32位和64位处理器可以以最高速度处理这些数据,效率更高。