Delphi使用哪些Windows消息来注意组合框中的更改? [英] What windows messages are used by Delphi to notice changes in a combo box?
问题描述
我有一个Delphi应用程序A,需要从.NET应用程序B中进行控制.
I have a Delphi application A, which I need to control from a .NET application B.
除其他事项外,我需要使该过程自动化:
Among other things, I need to automate this process:
- 用户从组合框中选择项目X.
- 应用程序A注意到更改并通过显示特定面板来做出反应.
如果我手动进行,那么效果很好.
This works fine, if I do it manually.
但是,当应用程序B选择一个组合框值时,则不会显示任何面板.
But when the application B selects a combo box value, no panel is displayed.
这是问题所在.
潜在原因:
- 当我选择组合框项目时,将触发某些Windows消息.一些Delphi例程对此消息做出反应.
- 当我以编程方式选择一个组合框项目时,我发送的唯一消息是
CB_SETCURSEL
,而Delphi应用程序似乎忽略了它.
- When I select a combo box item, a certain windows message is fired. Some Delphi routine reacts to this message.
- When I select a combo box item programmatically, the only message I send is
CB_SETCURSEL
and the Delphi app seems to ignore it.
因此,我假设我可以解决问题
Hence I assume that I can fix the problem, if I
- 了解哪些Windows消息用作有关组合框值更改的通知的基础(例如
OnChange
)和 - 从C#应用程序发送该Windows消息.
因此,我的问题是:触发了哪些Windows消息,发生了 OnChange
(以及其他事件,这些事件在更改组合框选择时通知Delphi应用程序)?
Therefore my question: What are the windows messages, on whose occurrence OnChange
(and other events that notify the Delphi application on changed combo box selection) are fired?
更新1:开始实施David Heffernan提出的解决方案
Update 1: Started to implement the solution proposed by 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);
目前,它不起作用.
更新2:
我注意到一件很奇怪的事情.
I noticed a very strange thing.
- 如果仅调用
CB_SETCURSEL
,则会在组合框中选择所需的项目. - 如果我先调用
CB_SETCURSEL
,然后(在5秒钟后)调用CN_COMMAND
,则在组合框中没有选择任何内容.
- If I invoke
CB_SETCURSEL
only, the desired item is selected in the combo box. - If I invoke
CB_SETCURSEL
and then (after 5 seconds)CN_COMMAND
, then nothing is selected in the combo box.
这意味着- CB_SECURSEL
选择该项目,然后 CN_COMMAND
撤消该项目.
This means - CB_SECURSEL
selects the item and CN_COMMAND
undoes it.
更新3 :根据Spy ++的组合框样式:
Update 3: Styles of the combo box according to Spy++:
- WS_CHILDWINDOW
- WS_VISIBLE
- WS_CLIPSIBLINGS
- 00000243
扩展样式:
- WS_EX_LEFT
- WS_EX_LTRREADING
- WS_EX_RIGHTSCROLLBAR
类样式:
- CS_VREDRAW
- CS_HREDRAW
- CS_DBLCLKS
更新4 :当我手动选择组合框项目时,在Spy ++输出中看到以下消息:
Update 4: When I select the combo box item manually, I see following messages in the Spy++ output:
<00177> 0195085E S message:0xBD33 [Custom:WM_APP+15667] wParam:6801164A lParam:0195085E
<00178> 0195085E R message:0xBD33 [Custom:WM_APP+15667] lResult:4610165A
很遗憾,我找不到此消息的文档.
Unfortunately, I couldn't find documentation for this message.
更新5 :我注意到,确实发生了对组合框选择更改的反应,但只是在相对较长的时间(30秒到1分钟)之后.当我手动执行相同操作时,反应会立即发生.
Update 5: I noticed that the reaction to combo box selection change does occur, but only after a relatively long time (30 seconds to 1 minute). When I do the same thing manually, the reaction occurs instantaneously.
此行为的可能原因:.NET应用程序的线程使Delphi应用程序的线程等待它.请注意,.NET应用程序中的UI交互代码是在单独的线程(而不是UI线程)中执行的.
Potential cause of this behaviour: The thread of the .NET application makes the thread of the Delphi application wait for it. Note that the UI interaction code in the .NET app is executed in a separate thread (not the UI thread).
推荐答案
您应该通过向组合框发送带有 NotifyCode的
等于 WM_COMMAND
消息来遵循 CB_SETCURSEL
消息 CBN_SELCHANGE
.触发 OnChange
事件的是 CBN_SELCHANGE
.
You should follow the CB_SETCURSEL
message by sending the combo box a WM_COMMAND
message with NotifyCode
equal to CBN_SELCHANGE
. It's the CBN_SELCHANGE
that triggers the OnChange
event.
在Delphi中,代码如下所示:
In Delphi the code would look like this:
SendMessage(ComboHandle, CB_SETCURSEL, NewSelectionIndex, 0);
SendMessage(ComboHandle, WM_COMMAND, MakeWParam(0, CBN_SELCHANGE), ComboHandle);
或者您也可以使用 CN_COMMAND
消息代替,这可能会更直接一些:
Or you could use the CN_COMMAND
message instead which would perhaps be a little more direct:
SendMessage(ComboHandle, CB_SETCURSEL, NewSelectionIndex, 0);
SendMessage(ComboHandle, CN_COMMAND, MakeWParam(0, CBN_SELCHANGE), 0);
您将希望将其翻译为所使用的任何.net语言,但是我相信这对您来说很容易.
You'll want to translate that into whichever .net language you are using, but I'm sure that's easy for you.
这篇关于Delphi使用哪些Windows消息来注意组合框中的更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!