没有 WM_MOUSEMOVE 消息

问题描述 投票:0回答:0

当鼠标悬停在 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
消息,但只有在我最小化/最大化主窗口之前;

c++ listview winapi onmouseover
© www.soinside.com 2019 - 2024. All rights reserved.