c++ - 从父级的 wndproc 访问特定子窗口的最佳实践
问题描述
我经常遇到这样的情况,从父窗口的 wndproc 函数,我必须修改子窗口(例如:单击子按钮添加到同级组合框;向父级发送消息,然后将其转发给相应的子级)。据我所知,这意味着以某种方式获取孩子的 HWND 引用并使用该引用调用孩子的 wndproc。
在这种情况下,我有孩子的子窗口标识符,我有父窗口的 HWND 引用,但没有别的。
从各种教程中,看起来我唯一的选择是将子的 HWND 引用保存为全局,以便我可以从父的 wndproc 函数访问它,或者调用 EnumChildWindows() 并在开头有一个 switch 语句,如果当前孩子不是目标孩子:前者似乎不能很好地扩展,因为我正在为每个我需要说话的孩子保存一个全局;后者似乎旨在向所有儿童广播,而不是与单个特定儿童交谈。
我觉得必须有一个函数接受父母的 HWND 和孩子的子窗口标识符并返回孩子的 HWND,但无论我如何谷歌,似乎都不存在这样的函数。
简而言之,我知道几种解决问题的方法,但我有一种直觉,我做错了什么。给定父窗口的 HWND 引用,在子窗口上执行操作的最佳实践方法是什么?
解决方案
大多数基于WM_NOTIFY
or的通知WM_COMMAND
,包括BN_CLICKED
,都带有HWND
孩子的 ID 以及孩子的 ID,例如:
WM_NOTIFY
参数
发送消息的公共控件的标识符。不保证此标识符是唯一的。应用程序应使用结构的
hwndFrom
oridFrom
成员NMHDR
(作为lParam
参数传递)来标识控件。参数
指向
NMHDR
包含通知代码和附加信息的结构的指针。对于某些通知消息,此参数指向一个较大的结构,该NMHDR
结构作为其第一个成员。
WM_COMMAND
参数
LOWORD 包含按钮的控件标识符。HIWORD 指定通知代码。
参数
按钮的句柄。
因此,在父窗口的消息过程中,它确切地知道哪个子窗口正在向它发送通知,并且可以直接访问那个子窗口。
如果您希望父级的消息处理程序作用于另一个子级(即,从按钮的单击处理程序中将字符串添加到组合框),则应该HWND
在您最初创建子级时已经具有该其他子级的 ID 或 ID。
在前一种情况下,您可以按原样使用保存HWND
的内容,例如:
HWND hwndCB;
HWND hwndBtn;
...
case WM_CREATE:
hwndCB = CreateWindow(WC_COMBOBOX, ..., hWnd, ...);
hwndBtn = CreateWindow(WC_BUTTON, ..., hWnd, ...);
break;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED) &&
HWND(lParam) == hwndBtn)
{
SendMessage(hwndCB, CB_ADDSTRING, 0, ...);
}
break;
在后一种情况下,您可以使用在父窗口GetDlgItem()
中获取孩子的ID,例如:HWND
case WM_CREATE:
CreateWindow(WC_COMBOBOX, ..., hWnd, (MENU)ID_MY_COMBO, ...);
CreateWindow(WC_BUTTON, ..., hWnd, (HMENU)ID_MY_BTN, ...);
break;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED) &&
LOWORD(wParam) == ID_MY_BTN)
{
HWND hwndCB = GetDlgItem(hWnd, ID_MY_COMBO);
SendMessage(hwndCB, CB_ADDSTRING, 0, ...);
}
break;
推荐阅读
- f# - 我的绑定属性之一和我的 ActivityIndicator 之间的问题
- python - 反转数组python中的最后一个i元素
- python - 在 Python 中为多边形创建圆边
- bit-manipulation - 如何简化这个“一次清除多个位”功能?
- php - WordPress子、孙、曾孙类别必须使用父类别模板
- java - ANDROID_SDK_ROOT=undefined(推荐设置)JDK 8 需求检查失败
- python - Python:对列表进行排序,使 5.10 在 5.9 之后
- java - Gradle:无法通知构建侦听器
- botframework - 我可以合并现有的 Bot 构建以在 Bot Composer 中运行吗
- git - Git 在单次提交中从 master 获取快照