简体   繁体   中英

How to disable keys in windows (globally) using Qt?

Is it possible to disable or block a key such as the Print Screen key?

my event filter:

bool EventFilter::eventFilter(QObject *object, QEvent *event)
{
    qDebug() << "object:" << object << "type:" << event->type();
    return false;
}

I tried use in qApp :

ui->setupUi(this);

EventFilter *evt = new EventFilter;

qApp->installEventFilter(evt);

But return only events from application widgets:

object: QWidgetWindow(0x175bae50, name = "QWidgetClassWindow") type: QEvent::Type(PlatformSurface)
object: QWidget(0x175b02c0) type: QEvent::Type(PlatformSurface)
object: QWidget(0x175b02c0) type: QEvent::Type(WinIdChange)
object: QWidget(0x175b02c0) type: QEvent::Type(Create)
...

And:

ui->setupUi(this);

EventFilter *evt = new EventFilter;

QDesktopWidget *c = new QDesktopWidget;
c->installEventFilter(evt);

But return only 2 events:

object: QDesktopWidget(0x174e0260, name = "desktop") type: QEvent::Type(PolishRequest)
object: QDesktopWidget(0x174e0260, name = "desktop") type: QEvent::Type(Polish)

Can not intercept and / or block events? Thanks

You can install a low-level keyboard hook to intercept and block all Print Screen presses. The following is tested on my windows 7 machine.

Here is a minimal example that shows how to do this:

截图

#include <QtWidgets>
#include <windows.h>
//link against user32.lib when compiling in MSVC
#ifdef _MSC_VER
#pragma comment(lib, "User32.lib")
#endif

class GlobalPrintScreenBlocker {
public:
    GlobalPrintScreenBlocker():mHKeyboardHook(NULL) {}
    //to avoid leaking the hook procedure handle
    ~GlobalPrintScreenBlocker(){ unblock(); }
    //hook callback function (called on every system-wide key press)
    static LRESULT CALLBACK LowLevelKeyboardProc(int nCode,
                                                 WPARAM wParam, LPARAM lParam) {
        if(nCode == HC_ACTION) {
            PKBDLLHOOKSTRUCT p = reinterpret_cast<PKBDLLHOOKSTRUCT>(lParam);
            if(p->vkCode == VK_SNAPSHOT) return 1; //block print-screen key
        }
        //this is not a message we are interested in
        return CallNextHookEx(NULL, //ignored paramater
                              nCode,
                              wParam,
                              lParam);
    }
    void block(){
        mHKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, //low-level keyboard hool
                                          &LowLevelKeyboardProc, //callback
                                          GetModuleHandle(NULL), 
                                          0);
    }
    void unblock(){
        if(mHKeyboardHook) UnhookWindowsHookEx(mHKeyboardHook);
        mHKeyboardHook = NULL;
    }

private:
    HHOOK mHKeyboardHook;
};

int main(int argc, char* argv[]) {
    QApplication a(argc, argv);

    GlobalPrintScreenBlocker blocker;
    QPushButton button("Disable ScreenShot");
    button.setCheckable(true);
    QObject::connect(&button, &QPushButton::toggled, [&](bool isChecked){
        if(isChecked)
            blocker.block();
        else
            blocker.unblock();
    });
    button.show();

    return a.exec();
}

The hook gets called in the thread that installed it. This has the advantages of not having to worry about thread-safety issues in your callback function, and that there would be no difference between 32-bit processes and 64-bit processes (all processes will end up calling the hook function indirectly by posting a message to the event loop of the thread that installed the hook). However, this also has the disadvantage that if your thread was busy (executing anything else) the callback hook might not get called:

The hook procedure should process a message in less time than the data entry specified in the LowLevelHooksTimeout value ... The value is in milliseconds. If the hook procedure times out, the system passes the message to the next hook. However, on Windows 7 and later, the hook is silently removed without being called. There is no way for the application to know whether the hook is removed.

You can get around this limitation by allocating a separate thread for installing/executing the hook. Also, note that your hook's callback function should be as minimum as possible in order for it to be able to finish within the time constraints.

PS: I had to use the snipping tool to create the screen shot above. . .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM