Я провожу некоторые исследования и хотел бы узнать, как я могу реализовать фильтр столбцов в ListView, используя чисто win32 API.
Примерно так:
Я написал простой тестовый код, чтобы сгенерировать представление списка для отображения содержимого CSV.
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <commctrl.h>
#include <string.h>
#define WND_CLASS_NAME "CSVVIEW"
char* filename;
HWND hList;
int rgb(int r, int g, int b) { return r + (g << 8) + (b << 16); }
void onCreate(HWND hWnd, LPARAM lParam) {
LVCOLUMN col;
LVITEM item;
int iCol, iCount, dwStyle;
CREATESTRUCT* lp = (CREATESTRUCT*)lParam;
FILE* fp;
char buf[256];
char* field;
memset(&item, 0, sizeof(item));
hList = CreateWindowEx(0, WC_LISTVIEW, 0,
WS_CHILD | WS_VISIBLE | LVS_REPORT,
0, 0, 100, 100, hWnd, (HMENU)1, lp->hInstance, NULL);
dwStyle = SendMessage(hList, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
dwStyle = dwStyle | LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT |
LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP;
SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);
col.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
fp = fopen(filename, "r");
if (fp == NULL) {
sprintf(buf, "Fail to open the file...", filename);
MessageBox(hWnd, buf, "Error", MB_OK);
exit(1);
}
fgets(buf, 255, fp);
field = strtok(buf, ",");
for (iCol = 0; field != NULL; iCol++) {
if (field[1] != ':') { col.fmt = LVCFMT_LEFT; }
else if (field[0] == 'l') { col.fmt = LVCFMT_LEFT; field += 2; }
else if (field[0] == 'c') { col.fmt = LVCFMT_CENTER; field += 2; }
else if (field[0] == 'r') { col.fmt = LVCFMT_RIGHT; field += 2; }
col.cx = strlen(field) * 13;
col.iSubItem = iCol;
col.pszText = field;
SendMessage(hList, LVM_INSERTCOLUMN, iCol, (LPARAM)&col);
field = strtok(NULL, ",\n");
}
item.mask = LVIF_TEXT;
for (iCount = 0; fgets(buf, 255, fp) != NULL; iCount++) {
item.pszText = strtok(buf, ",");
item.iItem = iCount;
item.iSubItem = 0;
SendMessage(hList, LVM_INSERTITEM, 0, (LPARAM)&item);
for (iCol = 1; (field = strtok(NULL, ",\n")) != NULL; iCol++) {
item.pszText = field;
item.iItem = iCount;
item.iSubItem = iCol;
SendMessage(hList, LVM_SETITEM, 0, (LPARAM)&item);
}
}
}
void onSize(HWND hwnd, WPARAM wp, LPARAM lp) {
RECT rc;
GetClientRect(hwnd, &rc);
MoveWindow(hList, 0, 0, rc.right - rc.left, rc.bottom - rc.top, TRUE);
}
int onNotify(HWND hwnd, WPARAM wp, LPARAM lp) {
NMHDR* pnmhdr = (NMHDR*)lp;
if (pnmhdr->code == NM_CUSTOMDRAW) {
NMLVCUSTOMDRAW* lpCustomDraw = (NMLVCUSTOMDRAW*)pnmhdr;
switch (lpCustomDraw->nmcd.dwDrawStage) {
case CDDS_PREPAINT:
return CDRF_NOTIFYITEMDRAW;
case CDDS_ITEMPREPAINT:
if (lpCustomDraw->nmcd.dwItemSpec % 2 == 1)
lpCustomDraw->clrTextBk = rgb(209, 240, 179);
else
lpCustomDraw->clrTextBk = rgb(250, 250, 250);
return CDRF_NEWFONT;
}
}
return DefWindowProc(hwnd, WM_NOTIFY, wp, lp);
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_CREATE: onCreate(hWnd, lParam); break;
case WM_SIZE: onSize(hWnd, wParam, lParam); break;
case WM_NOTIFY: return onNotify(hWnd, wParam, lParam);
case WM_DESTROY: PostQuitMessage(0); break;
default: return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
char buf[256];
HWND hWnd;
WNDCLASS wcl;
MSG msg;
filename = lpCmdLine;
if (filename == NULL) return FALSE;
InitCommonControls();
memset(&wcl, 0, sizeof(wcl));
wcl.hInstance = hInstance;
wcl.lpszClassName = WND_CLASS_NAME;
wcl.lpfnWndProc = WindowProc;
wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
wcl.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
if (!RegisterClass(&wcl)) return FALSE;
wsprintf(buf, "%s - %s", "CSV View", lpCmdLine);
hWnd = CreateWindowEx(0, WND_CLASS_NAME, buf,
WS_OVERLAPPEDWINDOW | WS_VISIBLE, 10, 10, 900, 300, NULL, NULL, hInstance, NULL);
if (!hWnd) return FALSE;
while (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
Файл теста CSV:
COL 1,COL 2,COL 3,COL 4
CA_002,CB_002,CB_002,CB_002
CA_003,CB_003,CB_003,CB_003
Что необходимо изменить в коде, чтобы можно было создавать поля поиска в заголовке представления списка?
Как захватить события для каждого текстового поля в заголовке?