3

使用CB_SETCURSEL消息时,不发送CBN_SELCHANGE消息。

如何通知控件选择已更改?

附言

我在Sexchange网站上发现了一个非常丑陋的hack:

SendMessage( hwnd, 0x014F/*CB_SHOWDROPDOWN*/, 1, 0 );
SendMessage( hwnd, 0x014E/*CB_SETCURSEL*/, ItemIndex, 0 );
SendMessage( hwnd, 0x0201/*WM_LBUTTONDOWN*/, 0, -1 );
SendMessage( hwnd, 0x0202/*WM_LBUTTONUP*/, 0, -1 );

现在会做......不是真的。

PS2

为了解决我的问题,我将在评论中遵循 Ken 的建议。

4

3 回答 3

4

这可能会帮助下一个人:

[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hwnd, int msg, int wParam, int lParam);

[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
private static extern IntPtr GetWindowLongPtr32(IntPtr hWnd, int nIndex);

[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
private static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);

public static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex)
{
   if (IntPtr.Size == 8)
        return GetWindowLongPtr64(hWnd, nIndex);
   else
        return GetWindowLongPtr32(hWnd, nIndex);
}

static int MakeWParam(int loWord, int hiWord)
{
     return (loWord & 0xFFFF) + ((hiWord & 0xFFFF) << 16);
}

public const int CB_SETCURSEL = 0x014E;
public const int CBN_SELCHANGE = 0x0001;

public enum GWL
{
            GWL_WNDPROC = (-4),
            GWL_HINSTANCE = (-6),
            GWL_HWNDPARENT = (-8),
            GWL_STYLE = (-16),
            GWL_EXSTYLE = (-20),
            GWL_USERDATA = (-21),
            GWL_ID = (-12)
}

public static IntPtr Hwnd_select_control_parent = IntPtr.Zero;
public static IntPtr Hwnd_select_control = IntPtr.Zero;

static void changeit()

{

// Google WinSpy for tips on how to figure out how to get window handles from known ctrl_id

   Hwnd_select_control = 14298; // or whatever the handle of the combo box is

// Get the parent of the selectbox control

   Hwnd_select_control_parent = GetWindowLongPtr(service_window_control, (int)GWL.GWL_HWNDPARENT);

// Get the control id of the selectbox if you don't already have it

   IntPtr nID = GetWindowLongPtr(Hwnd_select_control, (int)GWL.GWL_ID);
   int ctrl_id = nID.ToInt32();

// Change the combo box to the value "My Value"

   SendMessage(Hwnd_select_control, CB_SETCURSEL, "My Value", null);

// low ID is the ctrl_id of the combo box, high id is CBN_SELCHANGE

   int send_cbn_selchange = MakeWParam(ctrl_id, CBN_SELCHANGE); 

// Send the WM_COMMAND to the parent, not the control itself

   SendMessage(Hwnd_serviceselect_control_parent, 0x111 /* WM_COMMAND */, send_cbn_selchange, Hwnd_serviceselect_control.ToInt32()); 


}
于 2009-10-26T17:50:58.940 回答
3

您不应该使用 CBN_SELCHANGE 除非用户更改了选择。

您没有说明您使用的是什么语言;如果您这样做,它将更容易为您提供解决方法。

在 Delphi 中,OnChange() 将与组合框相关联,您只需直接调用事件方法:

// Send the CB_SETCURSEL message to the combobox
PostMessage(ComboBox1.Handle, CB_SETCURSEL, Whatever, WhateverElse);

// Directly call the OnChange() handler, which is the equivalent to CBN_SELCHANGE
ComboBox1Change(nil);
于 2009-09-23T19:58:45.377 回答
0

我刚刚发现将这些 SendMessages 调用到 Combobox 两次有效……我知道它并不完美,但它对我有用。(用VB6编写)

    For looper = 1 To 2

        bVal = SendMessage(inHandle, COMBO.CB_SHOWDROPDOWN, True, 0)
        count = SendMessage(inHandle, COMBO.CB_SETCURSEL, 1, 0)
        count = SendMessage(inHandle, WIND.WM_LBUTTONDOWN, 0, -1)

    Next
于 2017-09-22T21:10:10.777 回答