Создайте событие для кнопки мыши, даже если приложение свернуто

#c #windows #winapi #mouseevent

Вопрос:

Я хочу создать приложение, которое реагирует на кнопку мыши, поэтому я сделал это:

 case WM_LBUTTONDOWN:
        MessageBox(
            NULL,
            (LPCWSTR)L"HALLOOOO",
            (LPCWSTR)L"Worked",
            MB_ICONASTERISK | MB_OK | MB_DEFBUTTON2
        );
        break;
 

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

 GetKeyState(VK_LBUTTON);
 

но если я включу это в цикл, если я нажму его один раз, он обнаружит 1 миллион раз, потому что он просто проверит, нажата ли клавиша, и если я добавлю задержку Sleep(250) , это может сработать, но иногда он ничего не обнаружит, даже если пользователь нажал клавишу
Я хочу, чтобы мое приложение могло определять, нажата ли клавиша, даже если она свернута, как я могу это сделать?

Ответ №1:

Поскольку у вас уже есть окно, позвоните SetWindowsHookEx с WH_MOUSE_LL помощью .

Здесь задокументирован API и описаны параметры.

 HHOOK SetWindowsHookExW(
  [in] int       idHook,
  [in] HOOKPROC  lpfn,
  [in] HINSTANCE hmod,
  [in] DWORD     dwThreadId
);
 

Процедура lpfn подключения может быть определена следующим образом:

 HWND hmain_window;
HHOOK hhook;
LRESULT CALLBACK mouse_proc(int code, WPARAM wparam, LPARAM lparam)
{
    if (code == HC_ACTION amp;amp; lparam) 
    {
        if (wparam == WM_LBUTTONDOWN)
        {
            //MOUSEHOOKSTRUCT* mstruct = (MOUSEHOOKSTRUCT*)lparam;
            static int i = 0;
            std::wstring str = L"mouse down "   std::to_wstring(i  );
            SetWindowText(hmain_window, str.c_str());
        }
    }
    return CallNextHookEx(hhook, code, wparam, lparam);
}

int APIENTRY wWinMain(HINSTANCE hinst, HINSTANCE, LPWSTR, int)
{
    ...
    RegisterClassEx(...);
    hmain_window = CreateWindow(...);
    hhook = SetWindowsHookEx(WH_MOUSE_LL, mouse_proc, hinst, 0);
    MSG msg;
    while (GetMessage(amp;msg, NULL, 0, 0) > 0) 
    {
        TranslateMessage(amp;msg);
        DispatchMessage(amp;msg);
    }
    UnhookWindowsHookEx(hhook);
    return 0;
}
 

Комментарии:

1. Спасибо, что это сработало, в visual studio по умолчанию хинст был назван Хинстансом, а что, если я его не отцеплю?

2. Вы должны освобождать ресурсы, когда они вам больше не нужны, иначе вы получите утечку ресурсов. Это то же самое, что утечка памяти, но это хуже, потому что ресурсы Windows более ограничены. Когда программа завершает работу, ресурсы и память автоматически освобождаются. Поэтому в данном конкретном примере это может не иметь значения, но возьмите за привычку отменять запросы ресурсов.

Ответ №2:

Вы можете попробовать SetWindowsHookEx с параметром WH_MOUSE_LL или WH_MOUSE.

В этой статье показано, как установить крючок для клавиатуры. Вы можете заменить WH_KEYBOARD на WH_MOUSE для установки крючка мыши и использовать этот документ для обработки обратного вызова.

Комментарии:

1. извините, но я новичок в c и ничего не понимаю в этой функции, я ищу несколько примеров, но я не знаю, что такое LRESULT, ОБРАТНЫЙ вызов, WPARAM, LPARAM могу ли я что-то сделать с GetKeyState(VK_LBUTTON); чтобы это работало сейчас? и тогда я смогу изучить win32 API, но сейчас я просто изучаю c самостоятельно

2. @ali Если вы не можете убедиться, что ответ решает вашу проблему, не принимайте его. Типы данных Windows описаны здесь .

3. @IInspectable Извините, я искал информацию о SetWindowsHook, и это было то, что я хотел, но я не смог заставить его работать (моя программа остановила правильную работу мыши, и мой компьютер сильно запаздывал) спасибо за документ, я, возможно, смогу заставить его работать сейчас

4. В этой статье показано, как установить крючок для клавиатуры. Вы можете заменить WH_KEYBOARD на WH_MOUSE для установки крючка мыши и использовать этот документ для обработки обратного вызова.