#include "stdafx.h"
#include "Win32ListCtrl.h"
#include <CommCtrl.h>
#define MAX_LOADSTRING 100
HINSTANCE
hInst;
TCHAR
szTitle[MAX_LOADSTRING];
TCHAR
szWindowClass[MAX_LOADSTRING];
ATOM
MyRegisterClass(
HINSTANCE
hInstance);
BOOL
InitInstance(
HINSTANCE
,
int
);
LRESULT
CALLBACK WndProc(
HWND
,
UINT
,
WPARAM
,
LPARAM
);
INT_PTR
CALLBACK About(
HWND
,
UINT
,
WPARAM
,
LPARAM
);
struct
OWNER_ITEM
{
TCHAR
subItem[3][16];
};
#define ITEM_COUNT 100000
struct
OWNER_ITEM g_owner_data[ITEM_COUNT];
HWND
g_hListControl = 0;
int
APIENTRY _tWinMain(_In_
HINSTANCE
hInstance,
_In_opt_
HINSTANCE
hPrevInstance,
_In_
LPTSTR
lpCmdLine,
_In_
int
nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
for
(
int
i = 0; i < ITEM_COUNT; i++)
{
_stprintf_s(g_owner_data[i].subItem[0], 16, _T(
"%d.col0"
), i);
_stprintf_s(g_owner_data[i].subItem[1], 16, _T(
"%d.col1"
), i);
_stprintf_s(g_owner_data[i].subItem[2], 16, _T(
"%d.col2"
), i);
}
MSG msg;
HACCEL
hAccelTable;
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WIN32LISTCTRL, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
if
(!InitInstance (hInstance, nCmdShow))
{
return
FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32LISTCTRL));
while
(GetMessage(&msg, NULL, 0, 0))
{
if
(!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return
(
int
) msg.wParam;
}
ATOM
MyRegisterClass(
HINSTANCE
hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize =
sizeof
(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32LISTCTRL));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (
HBRUSH
)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WIN32LISTCTRL);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return
RegisterClassEx(&wcex);
}
BOOL
InitInstance(
HINSTANCE
hInstance,
int
nCmdShow)
{
HWND
hWnd;
hInst = hInstance;
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if
(!hWnd)
{
return
FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return
TRUE;
}
LRESULT
CALLBACK WndProc(
HWND
hWnd,
UINT
message,
WPARAM
wParam,
LPARAM
lParam)
{
int
wmId, wmEvent;
PAINTSTRUCT ps;
HDC
hdc;
switch
(message)
{
case
WM_CREATE:
{
g_hListControl = CreateWindow(WC_LISTVIEW, _T(
""
),
WS_CHILD | WS_VISIBLE | WS_BORDER |
LVS_OWNERDATA | LVS_REPORT | LVS_SHOWSELALWAYS,
50, 50,
300, 300,
hWnd,
(
HMENU
)IDC_LIST_1,
NULL,
NULL);
ListView_SetExtendedListViewStyle(g_hListControl, LVS_EX_FULLROWSELECT);
LVCOLUMN colInfo_0 = { 0 };
colInfo_0.mask |= LVCF_WIDTH | LVCF_TEXT;
colInfo_0.cx = 100;
colInfo_0.pszText = (
LPTSTR
)_T(
"第0列"
);
SendMessage(g_hListControl, LVM_INSERTCOLUMN, 0, (
LPARAM
)&colInfo_0);
LVCOLUMN colInfo_1 = { 0 };
colInfo_1.mask |= LVCF_WIDTH | LVCF_TEXT;
colInfo_1.cx = 100;
colInfo_1.pszText = (
LPTSTR
)_T(
"第1列"
);
SendMessage(g_hListControl, LVM_INSERTCOLUMN, 1, (
LPARAM
)&colInfo_1);
LVCOLUMN colInfo_2 = { 0 };
colInfo_2.mask |= LVCF_WIDTH | LVCF_TEXT;
colInfo_2.cx = 100;
colInfo_2.pszText = (
LPTSTR
)_T(
"第2列"
);
ListView_InsertColumn(g_hListControl, 2, (
LPARAM
)&colInfo_2);
ListView_SetItemCount(g_hListControl, ITEM_COUNT);
}
case
WM_NOTIFY:
switch
(((LPNMHDR)lParam)->code)
{
case
LVN_GETDISPINFO:
if
(((LPNMHDR)lParam)->idFrom == IDC_LIST_1)
{
NMLVDISPINFO* plvdi = (NMLVDISPINFO*)lParam;
plvdi->item.pszText = g_owner_data[plvdi->item.iItem].subItem[plvdi->item.iSubItem];
return
TRUE;
}
break
;
case
LVN_ODFINDITEM:
if
(((LPNMHDR)lParam)->idFrom == IDC_LIST_1)
{
NMLVFINDITEM* pFindInfo = (NMLVFINDITEM*)lParam;
int
result = -1;
if
((pFindInfo->lvfi.flags & LVFI_STRING) == 0)
{
return
result;
}
int
total_count = ListView_GetItemCount(pFindInfo->hdr.hwndFrom);
const
TCHAR
* searchstr = pFindInfo->lvfi.psz;
DWORD
searchLen = _tcslen(searchstr);
int
startPos = pFindInfo->iStart;
if
(startPos >= total_count)
startPos = 0;
int
currentPos = startPos;
do
{
if
(_tcsnicmp(g_owner_data[currentPos].subItem[0], searchstr, searchLen) == 0)
{
result = currentPos;
break
;
}
currentPos++;
if
(currentPos >= total_count)
currentPos = 0;
}
while
(currentPos != startPos);
return
result;
}
break
;
}
break
;
case
WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch
(wmId)
{
case
IDM_ABOUT:
{
LVFINDINFO info;
int
nIndex;
int
total_count = ListView_GetItemCount(g_hListControl);
info.flags = LVFI_PARTIAL | LVFI_STRING;
info.psz = _T(
"98765"
);
nIndex = ListView_FindItem(g_hListControl, 0, &info);
if
(nIndex != -1)
{
for
(
int
n = nIndex; n < total_count; n++)
{
ListView_EnsureVisible(g_hListControl, n, FALSE);
if
(ListView_GetTopIndex(g_hListControl) == nIndex)
break
;
}
}
ListView_SetItemState(g_hListControl, nIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
}
break
;
case
IDM_EXIT:
DestroyWindow(hWnd);
break
;
default
:
return
DefWindowProc(hWnd, message, wParam, lParam);
}
break
;
case
WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break
;
case
WM_DESTROY:
PostQuitMessage(0);
break
;
default
:
return
DefWindowProc(hWnd, message, wParam, lParam);
}
return
0;
}
INT_PTR
CALLBACK About(
HWND
hDlg,
UINT
message,
WPARAM
wParam,
LPARAM
lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch
(message)
{
case
WM_INITDIALOG:
return
(
INT_PTR
)TRUE;
case
WM_COMMAND:
if
(LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return
(
INT_PTR
)TRUE;
}
break
;
}
return
(
INT_PTR
)FALSE;
}