当鼠标悬停在 ListView(ownerdata,customdraw) 上时,消息 WM_MOUSEMOVE 没有出现。但是来自形式。
这里是代码:
#define _CRT_SECURE_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#pragma comment(lib, "comctl32.lib")
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include "commctrl.h"
HINSTANCE hInst;
static HWND hwndListView;
const wchar_t szClassName[] = L"ListViewExampleClass";
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
#ifdef _DEBUG
AllocConsole();AttachConsole(GetCurrentProcessId());HWND Handle = GetConsoleWindow();freopen("CON", "w", stdout);
#endif
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
InitCommonControls();
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc)) { MessageBox(NULL, L"Failed to register window!", L"Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
szClassName,
L"ListViewExample",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 440, 460,
NULL, NULL, hInstance, NULL);
if (!hwnd) { MessageBox(NULL, L"Failed to create window!", L"Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
HWND CreateListView(HINSTANCE hInstance, HWND hwndParent)
{
hwndListView = CreateWindowEx(
WS_EX_CLIENTEDGE, // ex style
L"SysListView32", // class name - defined in commctrl.h
TEXT(""), // dummy text
WS_TABSTOP | WS_CHILD | WS_BORDER | WS_VISIBLE | LVS_REPORT | LVS_OWNERDATA, // style
0, // x position
0, // y position
400, // width
400, // height
hwndParent, // parent
(HMENU)2000, // ID
hInst, // instance
NULL); // no extra data
if (!hwndListView) return NULL;
//ResizeListView
RECT rc;
GetClientRect(hwndParent, &rc);
MoveWindow(hwndListView, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
return hwndListView;
}
BOOL InitListColumns(HWND hwndListView) {
LV_COLUMN lvColumn;
int i;
WCHAR szString[5][20] = { L"Main Column", L"Column 1", L"Column 2", L"Column 3", L"Column 4" };
lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvColumn.fmt = LVCFMT_LEFT;
lvColumn.cx = 120;
for (i = 0; i < 5; i++) {
lvColumn.pszText = szString[i];
ListView_InsertColumn(hwndListView, i, &lvColumn);
}
return TRUE;
}
bool toggle = false;
WNDPROC original_procedure;
LRESULT CALLBACK ListViewWndProc(HWND ws, UINT Message, WPARAM wParam, LPARAM lParam) {
switch (Message) {
case WM_MOUSEMOVE: printf("LV Mouse move\n"); if (!toggle) { toggle = true; } break;
case WM_MOUSELEAVE: if (toggle) printf("LV Mouse Leave\n"); break;
case WM_MOUSEHOVER: if (toggle) printf("LV Mouse hOver\n"); break;
}
return CallWindowProc(original_procedure, ws, Message, wParam, lParam);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static bool Tracking = false;
switch (message)
{
case WM_CREATE:
CreateListView(hInst, hWnd);
InitListColumns(hwndListView);
ListView_SetItemCount(hwndListView, 5);
//Edit 01 - SubClass Attempt - Worked
original_procedure = (WNDPROC)SetWindowLongPtr(hwndListView, GWLP_WNDPROC, (LONG_PTR)ListViewWndProc);
//Edit 02 - Get/Set Capture; worked only until min/max window
//SetCapture(hWnd);
break;
case WM_MOUSEMOVE:
printf("Mouse Move %d\n", GET_X_LPARAM(lParam));
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_NOTIFY:
if (((LPNMHDR)lParam)->code == LVN_GETDISPINFO) {
LV_DISPINFO* lpdi = (LV_DISPINFO*)lParam;
if (lpdi->item.mask & LVIF_TEXT) {
WCHAR szString[7] = L"TEXT0\0";
szString[3] = (wchar_t)(L'0' + lpdi->item.iSubItem);
szString[4] = (wchar_t)(L'0' + lpdi->item.iItem);
wcsncpy_s(lpdi->item.pszText, lpdi->item.cchTextMax, szString, _TRUNCATE);
}
}
//case NM_CUSTOMDRAW:
// custom draw code
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
编辑01 尝试 subclassing;
bool toggle = false;
WNDPROC original_procedure;
LRESULT CALLBACK ListViewWndProc(HWND ws, UINT Message, WPARAM wParam, LPARAM lParam) {
switch (Message) {
case WM_MOUSEMOVE: if (!toggle) { printf("LV Mouse move\n"); toggle = true; } break;
case WM_MOUSELEAVE: if (toggle) printf("LV Mouse Leave\n"); break;
case WM_MOUSEHOVER: if (toggle) printf("LV Mouse hOver\n"); break;
}
return CallWindowProc(original_procedure, ws, Message, wParam, lParam);
}
和
original_procedure = (WNDPROC)SetWindowLong(hwndListView, -4/*GWL_WNDPROC*/, (long)ListViewWndProc);
在WM_CREATE
使用 ListView 它不起作用...子类化 是旧的/不正确的例子;
SetWindowLongPtr
工作正常;
编辑02 而不是子类化,尝试
SetCapture(hWnd)
在
WM_CREATE
在 WM_MOUSEMOVE
中给我正确的 wWndProc
消息,但只有在我最小化/最大化主窗口之前;