ListView_SortItemsEx之后,ListView_FindItem总是返回-1,即什么也没找到。你能告诉我为什么会有这种行为吗?
我尝试通过lParam和psz搜索,结果是一样的,只是经过标准字母排序,没有指定回调函数,结果是一样的,我不会英语,我通过翻译器写的,如果有什么不对,请见谅
一个最小可重复的例子
#include "windows.h"
#include "commctrl.h"
#include "vector"
#include "string"
#pragma comment(lib, "Comctl32.lib")
HINSTANCE hinst;
HWND hwndMain;
HWND hwndList;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int CreateColumn(HWND hwndLV, int iCol, CHAR* Text, int iWidth)
{
LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
lvc.cx = iWidth;
lvc.pszText = Text;
lvc.iSubItem = iCol;
return ListView_InsertColumn(hwndLV, iCol, &lvc);
}
int CreateItem(HWND hwndList, CHAR* text, int index)
{
LVITEM lvi = { 0 };
int res;
lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
lvi.iItem = index;
lvi.pszText = text;
lvi.lParam = 0;
res = ListView_InsertItem(hwndList, &lvi);
if (res >= 0)
{
ListView_SetItemText(hwndList, res, 0, text);
}
return res;
}
void fillListView()
{
for (int i = 0; i < 10; ++i)
{
CreateItem(hwndList, (CHAR*)std::to_string(i).c_str(), i);
}
}
// функция обратново вызова для сортировки
int CALLBACK CompareListViewFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
std::vector<CHAR> str1(MAX_PATH);
std::vector<CHAR> str2(MAX_PATH);
ListView_GetItemText(hwndList, lParam1, 0, &str1.front(), MAX_PATH);
ListView_GetItemText(hwndList, lParam2, 0, &str2.front(), MAX_PATH);
if (strcmp(&str1.front(), &str2.front()) == 0)
{
return NULL;
}
if (strcmp(&str1.front(), &str2.front()) == 1)
{
return TRUE;
}
return -1;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg;
BOOL bRet;
WNDCLASS wc;
UNREFERENCED_PARAMETER(lpszCmdLine);
// Register the window class for the main window.
if (!hPrevInstance)
{
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon((HINSTANCE)NULL,
IDI_APPLICATION);
wc.hCursor = LoadCursor((HINSTANCE)NULL,
IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "MainMenu";
wc.lpszClassName = "MainWndClass";
if (!RegisterClass(&wc))
return FALSE;
}
hinst = hInstance;
hwndMain = CreateWindow("MainWndClass", "Sample",
WS_OVERLAPPEDWINDOW, 500, 30, 700, 700, (HWND)NULL,
(HMENU)NULL, hinst, (LPVOID)NULL);
hwndList = CreateWindow(WC_LISTVIEW, "", WS_VISIBLE | WS_BORDER | WS_CHILD | LVS_REPORT |
LVS_NOCOLUMNHEADER | LVS_SORTDESCENDING, 5, 5, 470, 630, hwndMain, (HMENU)44444, 0, 0);
HWND btn = CreateWindow("Button", "Select element 2", WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, 500, 5, 150, 30, hwndMain, (HMENU)44445, 0, 0);
HWND btn2 = CreateWindow("Button", "Sorting", WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, 500, 55, 150, 30, hwndMain, (HMENU)44446, 0, 0);
ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_FULLROWSELECT | LVS_EX_FLATSB);
CreateColumn(hwndList, 1, 0, 450);
fillListView();
if (!hwndMain)
return FALSE;
ShowWindow(hwndMain, nCmdShow);
UpdateWindow(hwndMain);
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
switch (wmId)
{
case 44445:
{
LVFINDINFO lvfiInfo;
lvfiInfo.flags = LVFI_STRING;
lvfiInfo.psz = "2";
int iIndex = ListView_FindItem(hwndList, -1, &lvfiInfo);
if (iIndex != -1)
{
ListView_SetItemState(hwndList, iIndex, LVIS_SELECTED, LVIS_SELECTED);
SetFocus(hwndList);
}
else
{
MessageBox(hWnd, "Not found", "ERROR", MB_ICONINFORMATION);
}
break;
}
case 44446:
{
ListView_SortItemsEx(hwndList, CompareListViewFunc, 0);
break;
}
}
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
正如 @Luke 所说:您可以通过指定
LVS_SORTASCENDING
或 LVS_SORTDESCENDING
窗口样式来确保列表视图控件始终排序。具有这些样式的控件使用项目的标签文本按升序或降序对它们进行排序。使用这些窗口样式时无法提供比较函数。
此外,您还必须知道,仅当列表视图控件具有焦点或在窗口样式中使用
LVS_SHOWSELALWAYS
样式时,项目才会显示为选定状态。