Проблема задержки WM_LBUTTONDOWN в WinAPI

Это продолжение моего предыдущего вопроса.

Как обрабатывать удержание кнопки в WinAPI?

Основываясь на полученных комментариях, мне удалось заставить кнопку постоянно обновлять счетчик, пока она нажата, но теперь у меня возникла новая проблема.

Если я нажму кнопку, счетчик увеличится и обновится элемент управления редактированием. Если я отпущу кнопку, а затем снова нажму кнопку, она не увеличится и не обновится.

Кажется, что существует задержка, связанная с сообщением WM_LBUTTONDOWN, независимая от задержки, которую я применяю при обработке WM_TIMER. Как решить эту проблему?

#include <Windows.h>

HINSTANCE g_hInst;

HWND hEdit;
HWND hButton;
WNDPROC btnProc;
int counter = 0;
int t = 0;

static LRESULT CALLBACK StaticButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_LBUTTONDOWN:
        // increment counter & update Edit Control
        counter++;
        wchar_t buf[40];
        wsprintf(buf, L"%d", counter);
        SetWindowText(hEdit, buf);

        // start the timer
        SetTimer(GetParent(hWnd), 1, 100, 0);

        return btnProc(hWnd, uMsg, wParam, lParam);
    case WM_LBUTTONUP:
        // reset t
        t = 0;

        // stop the timer
        KillTimer(GetParent(hWnd), 1);

        return btnProc(hWnd, uMsg, wParam, lParam);
    default:
        return btnProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_CREATE:
        hEdit = CreateWindow(L"EDIT", L"0", WS_CHILD | WS_VISIBLE | ES_CENTER | ES_READONLY, 100, 100, 100, 20, hWnd, (HMENU)1, g_hInst, NULL);
        hButton = CreateWindow(L"BUTTON", L"▴", WS_CHILD | WS_VISIBLE | BS_LEFT, 200 + 4, 100, 20, 20, hWnd, (HMENU)2, g_hInst, NULL);

        // subclass the button control
        btnProc = (WNDPROC)SetWindowLongPtr(hButton, GWLP_WNDPROC, (LONG_PTR)StaticButtonProc);
        break;
    case WM_TIMER:
        // 300ms delay
        if (t < 300) {
            t += 100;
        }
        else {
            // increment counter & continuously update Edit Control while button is depressed
            counter += 1;
            wchar_t buf[32];
            wsprintf(buf, L"%d", counter);
            SetWindowText(hEdit, buf);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(EXIT_SUCCESS);
        break;
    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(
    HINSTANCE hInst,
    HINSTANCE hPrevInst,
    LPSTR lpCmdLine,
    int iCmdShow)
{
    g_hInst = hInst;

    WNDCLASS wndClass = {
        .style          = CS_HREDRAW | CS_VREDRAW,
        .lpfnWndProc    = WindowProc,
        .hInstance      = hInst,
        .hIcon          = LoadIcon(NULL, IDI_APPLICATION),
        .hCursor        = LoadCursor(NULL, IDC_ARROW),
        .hbrBackground  = (HBRUSH)GetStockObject(LTGRAY_BRUSH),
        .lpszMenuName   = NULL,
        .lpszClassName  = L"app",
    };
    if (!RegisterClass(&wndClass)) {
        OutputDebugString(L"Failed to register window class\n");
        return EXIT_FAILURE;
    }
    if (!CreateWindow(
        L"app",
        L"Counter",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        0, 0,
        1280, 720,
        NULL, NULL,
        hInst, NULL))
    {
        OutputDebugString(L"Failed to create window\n");
        return EXIT_FAILURE;
    }
    MSG msg = {};
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}

Кстати: вы отметили C++, но на самом деле ваш код C.

Jabberwocky 08.07.2024 10:56
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
79
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы нажмете мышь, а затем сразу же отпустите ее и нажмете еще раз, вместо WM_LBUTTONDBLCLK сработает WM_LBUTTONDOWN.

Например, StaticButtonProc вы не обрабатываете это сообщение, ничего не происходит.

Просто обращайтесь с WM_LBUTTONDBLCLK так же, как и с WM_LBUTTONDOWN:

static LRESULT CALLBACK StaticButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  switch (uMsg) {
  case WM_LBUTTONDOWN:
  case WM_LBUTTONDBLCLK:  // <<<<<<<<<< add this line
    // increment counter & update Edit Control
    counter++;
    ...

Ого, я не думал, что исправить это будет так просто. Спасибо!

machine_1 08.07.2024 10:56

Также см. GetDoubleClickTime()

Remy Lebeau 08.07.2024 18:05

Другие вопросы по теме