在 win32 api 中使用 c++ 我想跟踪双击和三次点击等等

In win32 api using c++ i want to track double click and triple click and so on

LRESULT handleDoubleClicks(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, POINT ptLastClickPos, DWORD dwLastClickTime)
{
    DWORD dwClickTime = GetMessageTime();
    POINT ptClickPos = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
    switch(message)
    {
    case  WM_LBUTTONDOWN:
        if (dwLastClickTime + GetDoubleClickTime() > dwClickTime
            && abs(ptLastClickPos.x - ptClickPos.x) < GetSystemMetrics(SM_CXDOUBLECLK)
            && abs(ptLastClickPos.y - ptClickPos.y) < GetSystemMetrics(SM_CYDOUBLECLK))
        {
            MessageBox(hWnd, TEXT("Double click"), TEXT("I appear when double clicked"), MB_OKCANCEL);

        }
        else
        {
            dwLastClickTime = dwClickTime;
            ptLastClickPos = ptClickPos;
            wchar_t waCoord[20];
            wsprintf(waCoord, _T("(%i,%i)"), ptLastClickPos.x, ptLastClickPos.y);
            MessageBox(hWnd, waCoord, _T("Left mouse button click"), MB_OK);
        }
        break;
     default:
         return DefWindowProc(hWnd, message, wParam, lParam);
    }
}

这是我用来处理双击的函数: 当 windows 收到 WM_LBUTTONDOWN 时调用此函数,它将占用消息的时间和点击的坐标,并将其传输到此处的函数 我希望函数接收另一条消息 WM_LBUTTONDOWN并判断消息的时间,与上次点击时间和坐标进行比较,判断是否为双击。 但这不起作用。可能是我的方法有误,我是新手请帮助我解决这个问题。

 case WM_LBUTTONDOWN:
   {
        dwLastClickTime= GetMessageTime();
        // SetTimer(hWnd,0,GetDoubleClickTime(),0);
        ptLastClickPos.x = LOWORD(lParam);
        ptLastClickPos.y = HIWORD(lParam);
        handleDoubleClicks(hWnd, message, wParam, lParam, ptLastClickPos, dwLastClickTime);

   }

可以使用SetTimer,点击一次后,不是立即判断为点击,而是启动定时器,检查定时器范围内是否还有点击,如果有则判断为双击,如果没有,则上次判定为单击。

#define TIMER_ID 10
static int click_count = 0;
static POINT point = { 0 };
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_TIMER:
    {
        KillTimer(hWnd, TIMER_ID);
        if (click_count == 1)
        {
            wchar_t waCoord[20];
            wsprintf(waCoord, _T("(%i,%i)"), point.x, point.y);
            MessageBox(hWnd, waCoord, _T("Left mouse button click"), MB_OK);
        }
        else if(click_count == 2)
        {
            MessageBox(hWnd, TEXT("Double click"), TEXT("I appear when double clicked"), MB_OKCANCEL);
        }
        else if (click_count == 3)
        {
            MessageBox(hWnd, TEXT("Triple click"), TEXT("I appear when triple clicked"), MB_OKCANCEL);
        }
        click_count = 0;
        return 0;
    }
    break;
    case WM_LBUTTONDOWN:
    {
        if (click_count == 0)
        {
            SetTimer(hWnd, TIMER_ID, GetDoubleClickTime(), NULL);
        }
        click_count++;
        return 0;
    }
    break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: Add any drawing code that uses hdc here...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

并确保您的 window 没有 CS_DBLCLKS 样式。否则,根据文档,通常生成的第二条 WM_LBUTTONDOWN 消息将变为 WM_LBUTTONDBLCLK 消息:Double Clicks