Delphi使用哪些Windows消息来注意组合框中的更改? [英] What windows messages are used by Delphi to notice changes in a combo box?

查看:58
本文介绍了Delphi使用哪些Windows消息来注意组合框中的更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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:

  1. 用户从组合框中选择项目X.
  2. 应用程序A注意到更改并通过显示特定面板来做出反应.

如果我手动进行,那么效果很好.

This works fine, if I do it manually.

但是,当应用程序B选择一个组合框值时,则不会显示任何面板.

But when the application B selects a combo box value, no panel is displayed.

这是问题所在.

潜在原因:

  1. 当我选择组合框项目时,将触发某些Windows消息.一些Delphi例程对此消息做出反应.
  2. 当我以编程方式选择一个组合框项目时,我发送的唯一消息是 CB_SETCURSEL ,而Delphi应用程序似乎忽略了它.
  1. When I select a combo box item, a certain windows message is fired. Some Delphi routine reacts to this message.
  2. 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

  1. 了解哪些Windows消息用作有关组合框值更改的通知的基础(例如 OnChange )和
  2. 从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.

  1. 如果仅调用 CB_SETCURSEL ,则会在组合框中选择所需的项目.
  2. 如果我先调用 CB_SETCURSEL ,然后(在5秒钟后)调用 CN_COMMAND ,则在组合框中没有选择任何内容.
  1. If I invoke CB_SETCURSEL only, the desired item is selected in the combo box.
  2. 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++:

  1. WS_CHILDWINDOW
  2. WS_VISIBLE
  3. WS_CLIPSIBLINGS
  4. 00000243

扩展样式:

  1. WS_EX_LEFT
  2. WS_EX_LTRREADING
  3. WS_EX_RIGHTSCROLLBAR

类样式:

  1. CS_VREDRAW
  2. CS_HREDRAW
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆