我目前正在为一个拥有自己GUI的现有应用程序编写包装器。我无法访问原始应用程序的源代码(不幸的是)。我正在编写的程序是用C++编写的,我正在使用WinAPI。我通过模拟按钮时钟、勾选复选框等操作目标应用程序。
我目前面临的问题如下:
我需要在实现为WinAPI ComboBox的下拉列表中进行选择。我使用宏ComboBox_SetCurSel来完成此操作。下拉列表中的选择更改正确。但是,在原始应用程序中有一个只读文本框,它根据组合框中的选择更改值。当我执行ComboBox_SetCurSel时,这个不会改变。
我假设CBN_SELENDOK和/或CBN_SELCHANGE是在手动选择ComboBox中的条目时发送的,这是我在使用ComboBox_SetCurSel宏设置选择时不执行的位。
然而,由于缺乏经验,我不知道如何解决这个问题。谁通常在监听CBN_SELENDOK和CBN_SELCHANGE。它是主应用程序窗口、组合框的父元素还是主应用程序线程?我该如何发现。
有没有一个宏可以完成整个任务?喜欢在组合框中更改所选项目并发送所有必要的通知吗?有什么聪明的变通办法吗?
欢迎在这个问题上提供任何帮助,或任何有助于使情况更加清楚的其他问题。
更新:感谢乔纳森·波特的评论。我现在正试图明确地发送消息。这是我正在做的代码的一部分:
int res = ComboBox_SetCurSel(this->handle, index);
if (res == CB_ERR)
{
return false;
}
PostMessage(GetParent(this->handle),WM_COMMAND, MAKEWPARAM(0,CBN_SELENDOK),0);
PostMessage(GetParent(this->handle),WM_COMMAND, MAKEWPARAM(0,CBN_SELCHANGE),0);
注意,this->handle
只是ComboBox
本身的句柄,因为为了方便起见,我已经将其打包到结构中。GetParent(this->handle)
应获得ComboBox
的直接父级
仍然没有结果。消息的顺序重要吗?此外,我如何获得需要进入与WM_COMMAND一起发送的WPARAM的LOWORD的标识符?
答案:
感谢AlwaysLearningNewStuff我找到了答案。我一直在用0作为LPARAM发送消息。显然,ComboBox本身的句柄需要作为LPARAM发送,以便解决方案正常工作。这需要我很长时间才能弄清楚。@AlwaysLearningNewStuff,您应该将此作为回答而非评论发布。
此外,使用GetDlgCtrlID()获取组合框的ControlID也非常有用。这使得代码更加可靠。
谢谢所有参与的人。
这是我的最终代码:
if (this->handle == NULL)
{
return false;
}
int res = ComboBox_SetCurSel(this->handle, index);
if (res == CB_ERR)
{
return false;
}
PostMessage(GetParent(this->handle), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID( this->handle ),CBN_SELENDOK),
(LPARAM)(this->handle));
PostMessage(GetParent(this->handle), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID( this->handle ),CBN_SELCHANGE),
(LPARAM)(this->handle));
return true;
使用ComboBox_SetCurSel()
时没有发送CBN_SELCHANGE
是正确的,文档中也有这样的说明:
当使用CB_SETCURSEL消息设置当前选择时,CBN_SELCHANGE通知代码是而不是发送的。
因此,您必须手动发送通知。但是,您的消息中缺少关键元素-组合框的控件ID和HWND。父窗口使用这些消息来标识哪个子控件正在向其发送消息,以便它可以相应地执行操作。
试试这个:
int res = ComboBox_SetCurSel(this->handle, index);
if (res == CB_ERR)
{
return false;
}
HWND hParent = GetParent(this->handle);
int iCtrlId = GetDlgCtrlID(this->handle);
if (GetWindowLong(this->handle, GWL_STYLE) & CBS_SIMPLE)
PostMessage(hParent, WM_COMMAND, MAKEWPARAM(iCtrlId,CBN_SELENDOK), LPARAM(this->handle));
PostMessage(hParent, WM_COMMAND, MAKEWPARAM(iCtrlId,CBN_SELCHANGE), LPARAM(this->handle));