Как обнаружить перетаскивание в процедуре подключения мыши - PullRequest
0 голосов
/ 15 февраля 2020

Я успешно настроил хук мыши для окна, и я хотел бы обнаружить операцию перетаскивания при нажатии левой кнопки мыши. Я пытался использовать DragDetect, как показано ниже, но он никогда не возвращает TRUE и никогда не подавляет последующее событие при наведении курсора мыши (в этом коде hwnd - целевое окно) :

LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < 0)
    {
        return CallNextHookEx(NULL, nCode, wParam, lParam);
    }

    switch (wParam)
    {
        case WM_LBUTTONDOWN:
        {
            // Get the click point
            LPMOUSEHOOKSTRUCT pMouseHookStruct = reinterpret_cast<LPMOUSEHOOKSTRUCT>(lParam);
            CPoint ptClick = pMouseHookStruct->pt;

            // Drag detect
            BOOL fDrag = DragDetect(hwnd, ptClick);
            if (fDrag)
            {
                MessageBox(NULL, L"Drag", NULL, MB_OK);
            }
        break;
        }
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

Не работает ли DragDetect в процедурах подключения или я просто что-то не так делаю?

1 Ответ

0 голосов
/ 17 февраля 2020

Как отмечалось в комментариях, DragDetect не предсказывает будущее. Но вы можете сравнить POINT из WM_LBUTTONDOWN и WM_MOUSEMOVE в одно нажатие.

Пример:

#include <windows.h>
#include <iostream>
using namespace std;
typedef BOOL(*SETHOOK)(HWND hWnd);
typedef BOOL(*UNHOOK)();
LRESULT CALLBACK WndProcFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}
int main(int argc, char* argv[])
{
    WNDCLASS wc{};
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProcFunc;
    wc.hInstance = GetModuleHandle(NULL);
    wc.lpszClassName = L"Class_Name";
    wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
    RegisterClass(&wc);

    HWND hWnd = CreateWindow(L"Class_Name", L"Test", WS_OVERLAPPEDWINDOW, 0, 0, 1000, 500, NULL, NULL, GetModuleHandle(NULL), NULL);

    SETHOOK SetHook;
    UNHOOK UnHook;
    HMODULE h = LoadLibraryA("PATH\\DLL4.dll");
    SetHook = (SETHOOK)GetProcAddress(h, "SetHook");
    UnHook = (UNHOOK)GetProcAddress(h, "UnHook");
    BOOL i = SetHook(hWnd);

    ShowWindow(hWnd, 1);
    UpdateWindow(hWnd);

    MSG Msg;
    while (GetMessage(&Msg, NULL, 0, 0))
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }

    UnHook();
    return 0;
}

DLL:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#define PRESS TRUE
#define RELEASE FALSE
HHOOK tHook;
HMODULE hinstDLL;
BOOL button = RELEASE;
BOOL Drag = FALSE;
HWND hWnd;
POINT pt = { 0 };
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode < 0)
    {
        return CallNextHookEx(NULL, nCode, wParam, lParam);
    }
    LPMOUSEHOOKSTRUCT pMouseHookStruct = reinterpret_cast<LPMOUSEHOOKSTRUCT>(lParam);
    if (pMouseHookStruct->hwnd != hWnd)
    {
        button = RELEASE;
        Drag = FALSE;
    }
    else {
        switch (wParam)
        {
        case WM_LBUTTONDOWN:
        {
            button = PRESS;
            Drag = FALSE;
            printf("WM_LBUTTONDOWN\n");
            printf("%d , %d\n", pMouseHookStruct->pt.x, pMouseHookStruct->pt.y);
            pt.x = pMouseHookStruct->pt.x;
            pt.y = pMouseHookStruct->pt.y;
            break;
        }
        case WM_LBUTTONUP:
        {
            button = RELEASE;
            Drag = FALSE;
            printf("WM_LBUTTONUP\n");
            break;
        }
        case WM_MOUSEMOVE:
        {
            if (button == PRESS)
            {
                printf("%d , %d\n", pMouseHookStruct->pt.x, pMouseHookStruct->pt.y);
                if (Drag == FALSE && (abs(pt.x - pMouseHookStruct->pt.x) >= GetSystemMetrics(SM_CXDRAG) || abs(pt.y - pMouseHookStruct->pt.y) >= GetSystemMetrics(SM_CYDRAG)))
                {
                    printf("Drag\n");
                    Drag = TRUE;
                }
            }
            break;
        }
        }
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}
extern "C" __declspec(dllexport) BOOL SetHook(HWND hwnd)
{
    hWnd = hwnd;
    tHook = SetWindowsHookEx(WH_MOUSE, MouseProc, hinstDLL, 0);

    if (tHook == NULL)
        return FALSE;
    else
        return TRUE;
}
extern "C" __declspec(dllexport) BOOL UnHook()
{
    return UnhookWindowsHookEx(tHook);
}


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        hinstDLL = hModule;
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
...