Search code examples
winapihook

Windows low level mouse hook doesn't prevent desktop from detecting right click?


I wanted to test to see if I could stop the right click from being detected on the desktop of Windows. The test program is below, it is called and detects it correctly, but the desktop still puts up the context menu (I know there is a registry value for that, this is about the low level mouse handler not preventing detection of a mouse event).

The sample is below, what would need to happen for it to eat the right click so desktop doesn't open context menu handler?

#include <windows.h>
#include <tchar.h>
#include <shellapi.h>

// Function declarations
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);

// Global hook handle
HHOOK hHook = NULL;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    // Set the mouse hook
    hHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, hInstance, 0);
    if (!hHook) {
        MessageBox(NULL, L"Failed to install hook!", L"Error", MB_ICONERROR);
        return 1;
    }

    // Enter message loop
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    OutputDebugString(_T("Unhook\n"));
    // Unhook the mouse hook
    UnhookWindowsHookEx(hHook);
    return 0;
}

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode == HC_ACTION) {
        if (wParam == WM_RBUTTONDOWN) {
            POINT pt;
            GetCursorPos(&pt);
            HWND hwnd = WindowFromPoint(pt);
            TCHAR className[256];
            GetClassName(hwnd, className, sizeof(className));

            OutputDebugString(className);
            OutputDebugString(_T("\n"));

            if (_tcsicmp(className, _T("Progman")) == 0 || _tcsicmp(className, _T("SysListView32")) == 0) {
              // Prevent the default context menu
              return 1;
            }
        }
    }
    return CallNextHookEx(hHook, nCode, wParam, lParam);
}

Solution

  • As @RaymondChen said,

    You suppressed the WM_RBUTTONDOWN, but context menus respond to WM_RBUTTONUP.

    Also, according to MouseProc function,

    If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the target window procedure.