Вопрос

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. User selects item X from a combo box.
  2. Application A notices the change and reacts by displaying a certain panel.

This works fine, if I do it manually.

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

This is the problem.

Potential cause of it:

  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. get to know what windows messages are used as a basis for notification about combo box value changes (e. g. OnChange) and
  2. send that windows message from C# application.

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?

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);

At the moment, it doesn't work.

Update 2:

I noticed a very strange thing.

  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.

This means - CB_SECURSEL selects the item and CN_COMMAND undoes it.

Update 3: Styles of the combo box according to Spy++:

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

Extended styles:

  1. WS_EX_LEFT
  2. WS_EX_LTRREADING
  3. WS_EX_RIGHTSCROLLBAR

Class styles:

  1. CS_VREDRAW
  2. CS_HREDRAW
  3. CS_DBLCLKS

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.

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.

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).

Это было полезно?

Решение

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.

In Delphi the code would look like this:

SendMessage(ComboHandle, CB_SETCURSEL, NewSelectionIndex, 0);
SendMessage(ComboHandle, WM_COMMAND, MakeWParam(0, CBN_SELCHANGE), ComboHandle);

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);

You'll want to translate that into whichever .net language you are using, but I'm sure that's easy for you.

Другие советы

When the user selects a ComboBox item by hand, the control receives a CBN_SELCHANGE notification, which then triggers the TComboBox.OnChange event. When you select a ComboBox item programmably, no CBN_SELCHANGE notification is sent. This is documented behavior:

http://msdn.microsoft.com/en-us/library/windows/desktop/bb775821.aspx

The CBN_SELCHANGE notification code is not sent when the current selection is set using the CB_SETCURSEL message.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top