DP_*_*DP_ 3 delphi winapi delphi-2009
我有一个 Delphi 应用程序 A,我需要从 .NET 应用程序 B 控制它。
除此之外,我需要自动化这个过程:
如果我手动执行此操作,效果很好。
但是,当应用程序 B 选择组合框值时,不会显示任何面板。
这就是问题。
其潜在原因:
CB_SETCURSELDelphi 应用程序似乎忽略它。因此我认为我可以解决这个问题,如果我
OnChange)和因此我的问题是:什么是Windows消息,它们的发生OnChange(以及通知Delphi应用程序更改组合框选择的其他事件)被触发?
更新1:开始实施David Heffernan提出的解决方案
private const int CB_SETCURSEL = 0x14E;
private const int WM_COMMAND = 0x0111;
private const int CBN_SELCHANGE = 0x001;
private const int CN_COMMAND = 0xBD11;
private int MakeWParam(int l, int h)
{
return (l & 0xFFFF) | (h << 16);
}
...
IntPtr comboBoxHandle = new IntPtr(comboBox.Current.NativeWindowHandle);
SendMessage(comboBoxHandle, CB_SETCURSEL, (Int32)myIndexInComboBox, 0);
SendMessage(comboBoxHandle, CN_COMMAND, MakeWParam(0, CBN_SELCHANGE), 0);
Run Code Online (Sandbox Code Playgroud)
目前,它不起作用。
更新2:
我注意到一件非常奇怪的事情。
CB_SETCURSEL仅调用,则在组合框中选择所需的项目。CB_SETCURSELand then (5 秒后)CN_COMMAND,则组合框中不会选择任何内容。这意味着 -CB_SECURSEL选择该项目并CN_COMMAND撤消它。
更新 3:根据 Spy++ 的组合框样式:
扩展样式:
班级风格:
更新 4:当我手动选择组合框项目时,我在 Spy++ 输出中看到以下消息:
<00177> 0195085E S message:0xBD33 [Custom:WM_APP+15667] wParam:6801164A lParam:0195085E
<00178> 0195085E R message:0xBD33 [Custom:WM_APP+15667] lResult:4610165A
Run Code Online (Sandbox Code Playgroud)
不幸的是,我找不到此消息的文档。
更新 5:我注意到对组合框选择更改的反应确实发生,但只是在相对较长的时间(30 秒到 1 分钟)之后。当我手动做同样的事情时,反应会立即发生。
此行为的潜在原因:.NET 应用程序的线程使 Delphi 应用程序的线程等待它。请注意,.NET 应用程序中的 UI 交互代码是在单独的线程(而不是 UI 线程)中执行的。
您应该按照该CB_SETCURSEL消息向组合框发送一条等于 的WM_COMMAND消息。这是触发事件的。NotifyCodeCBN_SELCHANGECBN_SELCHANGEOnChange
在 Delphi 中,代码如下所示:
SendMessage(ComboHandle, CB_SETCURSEL, NewSelectionIndex, 0);
SendMessage(ComboHandle, WM_COMMAND, MakeWParam(0, CBN_SELCHANGE), ComboHandle);
Run Code Online (Sandbox Code Playgroud)
或者您可以使用该CN_COMMAND消息,这可能会更直接一些:
SendMessage(ComboHandle, CB_SETCURSEL, NewSelectionIndex, 0);
SendMessage(ComboHandle, CN_COMMAND, MakeWParam(0, CBN_SELCHANGE), 0);
Run Code Online (Sandbox Code Playgroud)
您需要将其翻译成您正在使用的任何 .net 语言,但我相信这对您来说很容易。