Delphi使用哪些Windows消息来注意组合框中的更改?

时间:2012-10-08 13:16:18

标签: delphi winapi delphi-2009

我有一个Delphi应用程序A,我需要从.NET应用程序B控制。

除此之外,我需要自动化这个过程:

  1. 用户从组合框中选择项目X。
  2. 应用程序A通过显示某个面板来注意到更改并作出反应。
  3. 如果我手动完成,这样可以正常工作。

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

    这就是问题所在。

    潜在原因:

    1. 当我选择一个组合框项目时,会触发某个窗口消息。一些Delphi例程会对此消息做出反应。
    2. 当我以编程方式选择一个组合框项目时,我发送的唯一消息是CB_SETCURSEL,而Delphi应用程序似乎忽略它。
    3. 因此我假设我可以解决问题,如果我

      1. 了解哪些Windows消息用作组合框值更改通知的基础(例如OnChange)和
      2. 从C#应用程序发送该窗口消息。
      3. 因此,我的问题是:什么是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);
        

        目前,它不起作用。

        更新2:

        我注意到了一件非常奇怪的事情。

        1. 如果我仅调用CB_SETCURSEL,则在组合框中选择所需的项目。
        2. 如果我调用CB_SETCURSEL然后(5秒后)CN_COMMAND,则在组合框中未选择任何内容。
        3. 这意味着 - CB_SECURSEL选择该项目,CN_COMMAND撤消该项目。

          更新3 :根据Spy ++的组合框样式:

          1. WS_CHILDWINDOW
          2. WS_VISIBLE
          3. WS_CLIPSIBLINGS
          4. 00000243
          5. 扩展样式:

            1. WS_EX_LEFT
            2. WS_EX_LTRREADING
            3. WS_EX_RIGHTSCROLLBAR
            4. 班级风格:

              1. CS_VREDRAW
              2. CS_HREDRAW
              3. CS_DBLCLKS
              4. 更新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线程)中执行的。

2 个答案:

答案 0 :(得分:4)

您应该通过发送CB_SETCURSEL消息,WM_COMMAND消息等于NotifyCode,来跟踪CBN_SELCHANGE消息。触发CBN_SELCHANGE事件的是OnChange

在Delphi中,代码如下所示:

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

或者您可以使用CN_COMMAND消息,而这可能更直接:

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

您希望将其转换为您正在使用的任何.net语言,但我确信这对您来说很容易。

答案 1 :(得分:4)

当用户手动选择ComboBox项时,控件会收到CBN_SELCHANGE通知,然后会触发TComboBox.OnChange事件。以可编程方式选择ComboBox项目时,不会发送CBN_SELCHANGE通知。这是记录在案的行为:

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

  

使用CB_SETCURSEL消息设置当前选择时,不会发送CBN_SELCHANGE通知代码。