了解 SendMessage wparam
Understanding SendMessage wparam
我正在开发一个 MFC 项目,它有以下代码:
NMHDR pNMHDR;
pNMHDR.hwndFrom = GetSafeHwnd();
pNMHDR.idFrom = GetDlgCtrlID();
pNMHDR.code = EN_CHANGE;
GetParent()->SendMessage(WM_NOTIFY, (EN_CHANGE << 16) | GetDlgCtrlID(), ( LPARAM ) &pNMHDR);
请帮助我理解 (EN_CHANGE << 16) | GetDlgCtrlID()
的作用。
根据标准 EDIT 控件的 EN_CHANGE
文档:
wParam
The LOWORD contains the identifier of the edit control. The HIWORD specifies the notification code.
因此,代码采用常量 EN_CHANGE
,将其位向左移动 16 位,然后对控件 ID 的位进行“或”运算。因此,EN_CHANGE
以位 16-31 结束,控制 ID 以位 0-15 结束:
WPARAM
-----------------------------------------------------------------
| EN_CHANGE | CtrlID |
-----------------------------------------------------------------
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
但是,代码 应该 使用 MAKEWPARAM()
宏而不是手动移位 + OR'ing 位,例如:
GetParent()->SendMessage(WM_NOTIFY, MAKEWPARAM(GetDlgCtrlID(), EN_CHANGE), (LPARAM) &pNMHDR);
话虽如此,标准的 EDIT 控件通过 WM_COMMAND
而不是 WM_NOTIFY
发送 EN_CHANGE
。但是标准的 windowless RICHEDIT 控件通过 WM_NOTIFY
发送 EN_CHANGE
,它在 wParam
参数中仅携带控件 ID。命令ID携带在lParam
参数指向的NMHDR
结构中(除了RICHEDIT使用CHANGENOTIFY
结构,与NMHDR
无关)。
所以,这段代码对EN_CHANGE
的使用显然是non-standard用法,使用自定义的参数方案。
我正在开发一个 MFC 项目,它有以下代码:
NMHDR pNMHDR;
pNMHDR.hwndFrom = GetSafeHwnd();
pNMHDR.idFrom = GetDlgCtrlID();
pNMHDR.code = EN_CHANGE;
GetParent()->SendMessage(WM_NOTIFY, (EN_CHANGE << 16) | GetDlgCtrlID(), ( LPARAM ) &pNMHDR);
请帮助我理解 (EN_CHANGE << 16) | GetDlgCtrlID()
的作用。
根据标准 EDIT 控件的 EN_CHANGE
文档:
wParam
The LOWORD contains the identifier of the edit control. The HIWORD specifies the notification code.
因此,代码采用常量 EN_CHANGE
,将其位向左移动 16 位,然后对控件 ID 的位进行“或”运算。因此,EN_CHANGE
以位 16-31 结束,控制 ID 以位 0-15 结束:
WPARAM
-----------------------------------------------------------------
| EN_CHANGE | CtrlID |
-----------------------------------------------------------------
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
但是,代码 应该 使用 MAKEWPARAM()
宏而不是手动移位 + OR'ing 位,例如:
GetParent()->SendMessage(WM_NOTIFY, MAKEWPARAM(GetDlgCtrlID(), EN_CHANGE), (LPARAM) &pNMHDR);
话虽如此,标准的 EDIT 控件通过 WM_COMMAND
而不是 WM_NOTIFY
发送 EN_CHANGE
。但是标准的 windowless RICHEDIT 控件通过 WM_NOTIFY
发送 EN_CHANGE
,它在 wParam
参数中仅携带控件 ID。命令ID携带在lParam
参数指向的NMHDR
结构中(除了RICHEDIT使用CHANGENOTIFY
结构,与NMHDR
无关)。
所以,这段代码对EN_CHANGE
的使用显然是non-standard用法,使用自定义的参数方案。