只要存在不同大小的不同变量类型,为什么windows使用宏和移位运算符将2个值映射到一个变量中,例如:
这是win32 windows过程的示例:
//...
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_LISTBOX:
{
switch(HIWORD(wParam))
{
//handle message
}
}
break;
}
}
break;
为什么Windows不使用两个类型的短变量? 或者这有特权?
谢谢你们答案 0 :(得分:5)
窗口消息只能传递2个整数(wParam
和lParam
参数)。
整数值本身不需要跨模块/进程边界进行任何特殊编组,它们可以按原样传递。它们也非常小,可以存储在消息队列中等等。
特别针对WM_COMMAND
,lParam
可能包含HWND
值,因此其他消息值(通知代码和标识符)只能在wParam
中传递。它们足够小,可以直接填入wParam
,因此可以轻松传递3个值,只允许2个值。
替代方法需要为包含单独整数的结构分配内存,然后在其中一个消息参数中传递指向该结构的指针。许多窗口消息都是这样做的,但通常只有当发送方和接收方处于同一个进程时,否则它需要跨模块/进程边界封送结构数据,这对简单消息传递来说是很多开销。
它还使接收器的负担释放分配的内存,因为WM_COMMAND
是通过接收窗口的消息队列的发布消息。发件人不等待处理消息,因此在发布消息后将无法释放结构内存。分配的内存必须在内存中保持活动状态,直到消息最终由接收窗口过程处理。
另一方面,发送的邮件直接进入窗口过程并阻止发件人处理,因此他们不必担心这一点,发件人可以在邮件发送后释放内存。但是,制作所有多值消息(尤其是状态消息)会对系统造成很大的瓶颈。
一般情况下,尽可能将较短的整数填充到较大的整数中会更容易,也更少开销,尤其是在发布的消息中(尽管发送的消息当然也可以这样做)。
答案 1 :(得分:2)
您的示例显示了在窗口messages上处理message queue的代码段。
可以在windows和windows对象之间发送大量different object types,并且消息结构必须处理所有这些不同的消息传递要求。例如
lParam
中的其他信息传递某个结构的地址。wParam
的下半部分就足够了在理想的C ++世界中,我们可以为消息实现多态数据结构,只需要所需数据的相关字段。但是winapi不是C ++:它是为C而设计的,与大量语言的兼容性可以与C语言互操作。
在一个理想的C世界中,我们可以使用一个union,它需要在进行进一步处理之前首先对消息类型(在所有union成员之间共享)进行测试。例如,在WM_COMMAND处理中,您首先要检查公共消息类型。
此外,如果您使用工会,如果您必须重新发布邮件,则重复使用其参数,则复制完整工会。所以你可以复制不需要的东西。这是一个很小的开销,但消息循环(以及一般的OS功能)是执行大量时间的事情。所以每纳秒都很重要。只使用所需的数据并将其打包成单词和双字,32位和64位处理器可以以最高速度处理这些数据,效率更高。