.NET アプリケーション B から制御する必要がある Delphi アプリケーション A があります。
とりわけ、このプロセスを自動化する必要があります。
- ユーザーがコンボ ボックスから項目 X を選択します。
- アプリケーション A は変化に気づき、特定のパネルを表示して反応します。
手動で行うと、これはうまく機能します。
しかし、アプリケーション B がコンボ ボックスの値を選択すると、パネルは表示されません。
これが問題です。
考えられる原因:
- コンボ ボックスの項目を選択すると、特定の Windows メッセージが表示されます。一部の Delphi ルーチンは、このメッセージに反応します。
- プログラムでコンボ ボックス項目を選択すると、送信される唯一のメッセージ
CB_SETCURSEL
が Delphi アプリで無視されるようです。
したがって、問題を解決できると思います。
OnChange
コンボ ボックスの値の変更に関する通知の基礎として使用される Windows メッセージ (例: )を理解する- その Windows メッセージを C# アプリケーションから送信します。
したがって、私の質問: 発生時にOnChange
(およびコンボ ボックスの選択が変更されたときに Delphi アプリケーションに通知するその他のイベントが) 発生する Windows メッセージは何ですか?
更新 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);
現時点では、動作しません。
更新 2:
私は非常に奇妙なことに気付きました。
- 呼び出す
CB_SETCURSEL
だけの場合、目的の項目がコンボ ボックスで選択されます。 - 呼び出し
CB_SETCURSEL
てから (5 秒後)を呼び出すとCN_COMMAND
、コンボ ボックスで何も選択されません。
これは -CB_SECURSEL
アイテムを選択してCN_COMMAND
元に戻すことを意味します。
更新 3 : 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++ 出力に次のメッセージが表示されます。
<00177> 0195085E S message:0xBD33 [Custom:WM_APP+15667] wParam:6801164A lParam:0195085E
<00178> 0195085E R message:0xBD33 [Custom:WM_APP+15667] lResult:4610165A
残念ながら、このメッセージのドキュメントは見つかりませんでした。
更新 5 : コンボ ボックスの選択の変更に対する反応が発生することに気付きましたが、比較的長い時間 (30 秒から 1 分) が経過した後でのみ発生します。同じことを手動で行うと、瞬時に反応が起こります。
この動作の潜在的な原因: .NET アプリケーションのスレッドが Delphi アプリケーションのスレッドを待機させます。.NET アプリの UI 対話コードは、(UI スレッドではなく) 別のスレッドで実行されることに注意してください。