Monitoring Caps Lock State in Qt Applications

Implementation Overview

This article demonstrates three approaches for detecting Caps Lock key state changes in Qt applications, with focus on providing real-time visual feedback to users during password entry.

Caps Lock Detection Method

The fundamental technique for determining Caps Lock state uses the Windows API:

bool KeyboardMonitor::checkCapsLockState()
{
    return LOBYTE(GetKeyState(VK_CAPITAL)) != 0;
}

This function returns true when Caps Lock is active and false when inactive.

Approach 1: Widget Event Handling

Override keyboard event handlers in a custom QLineEdit widget:

class SecureInputField : public QLineEdit
{
protected:
    void keyPressEvent(QKeyEvent* event) override
    {
        if (event->key() == Qt::Key_CapsLock) {
            updateCapsIndicator();
        }
        QLineEdit::keyPressEvent(event);
    }
    
    void keyReleaseEvent(QKeyEvent* event) override
    {
        if (event->key() == Qt::Key_CapsLock) {
            updateCapsIndicator();
        }
        QLineEdit::keyReleaseEvent(event);
    }
    
private:
    void updateCapsIndicator()
    {
        if (checkCapsLockState()) {
            indicatorWidget->showWarning();
        } else {
            indicatorWidget->hideWarning();
        }
    }
};

Limitation: This only works when the widget has keyboard focus.

Approach 2: Application-Level Event Filtering

Implement native event filtering for application-wide key monitoring:

class GlobalKeyWatcher : public QAbstractNativeEventFilter
{
public:
    bool nativeEventFilter(const QByteArray &eventType, 
                          void* message, long* result) override
    {
        if (eventType == "windows_dispatcher_MSG") {
            MSG* msg = static_cast<msg>(message);
            if (msg->message == WM_KEYDOWN || msg->message == WM_KEYUP) {
                if (static_cast<int>(msg->wParam) == VK_CAPITAL) {
                    emit capsLockStateChanged();
                    return false;
                }
            }
        }
        return false;
    }
};
</int></msg>

Limitation: Only captures events when the application is active.

Approach 3: System-Wide Keyboard Hook

Implement a low-level keyboard hook for system-wide monitoring:

class SystemKeyboardHook
{
public:
    SystemKeyboardHook()
    {
        hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, 
                                     hookCallback, 
                                     GetModuleHandle(nullptr), 
                                     0);
    }
    
    ~SystemKeyboardHook()
    {
        if (hookHandle) {
            UnhookWindowsHookEx(hookHandle);
        }
    }
    
    void setCallback(std::function<void> callback) {
        userCallback = callback;
    }

private:
    static LRESULT CALLBACK hookCallback(int code, WPARAM wParam, LPARAM lParam)
    {
        if (code >= 0 && wParam == WM_KEYDOWN) {
            KBDLLHOOKSTRUCT* keyData = reinterpret_cast<kbdllhookstruct>(lParam);
            if (keyData->vkCode == VK_CAPITAL && userCallback) {
                userCallback();
            }
        }
        return CallNextHookEx(nullptr, code, wParam, lParam);
    }
    
    static inline HHOOK hookHandle = nullptr;
    static inline std::function<void> userCallback;
};
</void></kbdllhookstruct></void>

Complete Implementation Example

Integrate the system hook with Qt widget:

class PasswordEntryField : public QLineEdit
{
public:
    PasswordEntryField(QWidget* parent = nullptr) : QLineEdit(parent)
    {
        keyboardHook.setCallback([this]() { refreshCapsDisplay(); });
        refreshCapsDisplay();
    }

private:
    void refreshCapsDisplay()
    {
        if (checkCapsLockState()) {
            setStyleSheet("background-color: #fff0f0;");
            setPlaceholderText("CAPS LOCK IS ACTIVE");
        } else {
            setStyleSheet("");
            setPlaceholderText("Enter password...");
        }
    }
    
    SystemKeyboardHook keyboardHook;
};

The system hook approach provides reliable Caps Lock monitoring regardless of application focus state.

Tags: Qt Windows-API Keyboard-Hook Event-Filtering Caps-Lock

Posted on Sun, 11 Oct 2026 16:49:39 +0000 by nagalenoj