0

我主要来自 .NET 背景,但对于 Windows 控件,特别是 ComboBox,我必须完成一项小任务。

我知道 ComboBox 需要 CBS_SORT 消息才能按字母顺序对项目进行排序。当我使用 CB_ADDSTRING 标志将字符串添加到组合框时,这对我来说很好。

我试图让 ComboBox 使用反向(或其他自定义)排序顺序。

如果我CreateWindow用来制作组合框,有没有办法可以获取它返回的 HWND 并连接一个处理 WM_COMPAREITEM 消息的自定义方法?

这是来自 Microsoft 的文章,讨论了处理 WM_COMPAREITEM 消息。https://msdn.microsoft.com/en-us/library/windows/desktop/bb775791(v=vs.85).aspx

编辑: 我想一种解决方法是使用 CB_INSERTSTRING 标志进行自定义排序,但如果可以的话,我真的更喜欢在其他语言中实现类似于 CompareTo 的东西。

编辑: 值得一提的是调用 CreateWindow 的类(不使用 CBS_HASSTRINGS 标志)具有 WM_COMMAND 消息的消息处理程序。它在 HIWORD 中切换以处理诸如 CBN_SELCHANGE 之类的通知。

我查看了 Combo box 的文档,发现 CBN_SELCHANGE 和 WM_COMPAREITEM 之间存在细微差别。

当用户更改组合框列表框中的当前选择时,发送 CBN_SELCHANGE 通知代码。用户可以通过单击列表框或使用箭头键来更改选择。组合框的父窗口以 WM_COMMAND 消息的形式接收此通知,该消息在 wParam 参数的高位字中带有 CBN_SELCHANGE。

这就是关于 WM_COMPAREITEM 的内容

系统发送 WM_COMPAREITEM 消息以确定新项目在所有者绘制的组合框或列表框的排序列表中的相对位置。每当应用程序添加新项目时,系统都会将此消息发送给使用 CBS_SORT 或 LBS_SORT 样式创建的组合框或列表框的所有者。

据我所知,传递给 CreateWindow 方法的 DWORD 样式是WS_VISIBLE | WS_CHILD | WS_VSCROLL | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | CBS_SORT

也许问题是创建的组合框不是“所有者绘制的”组合框?如果是这种情况,我需要找到一种方法来做到这一点,但只处理 WM_COMPAREITEM 情况,而不处理任何其他自定义绘画代码。

更新 我创建了没有 CBS_HASSTRINGS 和 CB_OWNERDRAWFIXED 的 ComboBox(然后让我处理 WM_COMPAREITEM 消息)。

这是消息处理代码

LRESULT MyComboBoxParent::OnCompareItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    //umsg is always wm_compareitem
    COMPAREITEMSTRUCT* pCompareItemStruct = (COMPAREITEMSTRUCT*)lParam;
    ATLASSERT(pCompareItemStruct->CtlType == ODT_COMBOBOX); //this assert works

    int iItemId1 = pCompareItemStruct->itemID1;
    int iItemId2 = pCompareItemStruct->itemID2;

    LPCTSTR item1 = (LPCTSTR)pCompareItemStruct ->itemData1;
    ATLASSERT(item1 != NULL);

    LPCTSTR item2 = (LPCTSTR)pCompareItemStruct->itemData2;
    ATLASSERT(item2 != NULL);

    int iStringCompareResult = _tcscmp(item1, item2);

    //should reverse the sorting order
    int iReturn = -1 * iStringCompareResult;
    return iReturn;
}

//and the existing code snippet that adds the values to the combobox
::SendMessage(m_hwndCombo,CB_ADDSTRING,0,(LPARAM) ((wchar_t*)bstr_tDisplayedValue))

来自 COMPAREITEMSTRUCT 的数据真的很奇怪。我按顺序将以下值添加到组合框中。

  1. 啊啊啊
  2. bbbb
    • 这会触发 wm_compareitem
    • iItemId1 为 0
    • iItemId2 为 -1
    • item1 为 0x00000000(空指针)
    • item2 是 L"bbbb"
    • (这会导致字符串比较失败,所以我只是强制返回-1)
  3. cccc
    • iItemId1 为 0
    • iItemId2 为 -1
    • item1 为 0x00000000(空指针)
    • item2 是 L"cccc"
  4. zzzz
  5. 年年
  6. xxxx

z,y 和 x 都遵循相同的模式。我可能在互联网上找到了另一个有同样问题的。但很难确定。

4

0 回答 0