具有固定字符串列表和自定义数据的 WinAPI ComboBox

WinAPI ComboBox with fixed list of strings and custom data

有一个问题让我困惑了好几次,我总是不得不求助于 owner-drawn 解决方案 - 然而,这是我这次不想参与的问题。我的问题正如标题所说,这是代码中的模型情况:

HWND hComboBox=::CreateWindow(WC_COMBOBOX,NULL,WS_VISIBLE | WS_CHILD | CBS_HASSTRINGS | CBS_DROPDOWN,10,10,100,100,hWnd,0,hInstance,NULL);
ComboBox_SetItemData(   hComboBox,
                        ComboBox_AddString(hComboBox,"My item 1"),
                        1234
                    );
ComboBox_SetItemData(   hComboBox,
                        ComboBox_AddString(hComboBox,"My item 2"),
                        5678
                    );
int i=ComboBox_FindString(hComboBox,0,1234); // <-- crash
ComboBox_SetCurSel(hComboBox, i );

显然,我想通过关联的自定义数据(在本例中为 1234 和 5678)来识别每个项目。我知道我能够在 Delphi 中做到这一点,但还没有说服纯 WinAPI 做同样的事情(显而易见的问题是 Delphi 的 out-of-the-box 功能背后隐藏着什么)。

感谢回复。

CBS_HASSTRINGS 在非所有者绘制组合框中毫无意义。在非所有者绘制组合框中,每个项目都有一个字符串和一个可选的数据项,并且 ComboBox_FindString 总是使用字符串查找项目。当然,1234 不是有效的字符串指针。您基本上是在给控件一个无效的指针,它崩溃也就不足为奇了:)

没有内置消息可以让您在非所有者抽奖组合中按项目数据搜索,因此您需要自己编写,例如:

int iCount = ComboBox_GetCount(hComboBox), iFound = -1;
for (int i = 0; i < iCount; i++)
{
    if (ComboBox_GetItemData(hComboBox, i) == 1234)
    {
        iFound = i;
        break;
    }
}