Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Getting key press event for any key
Qt 6.11 is out! See what's new in the release blog

Getting key press event for any key

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 4 Posters 4.9k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • hskoglundH Offline
    hskoglundH Offline
    hskoglund
    wrote on last edited by
    #4

    It's all a throwback to the 80's (think Madonna etc.) WPARAM and LPARAM are the generic names for passing around stuff in Windows messages.
    To convert a LPARAM back to a Windows Virtual Key code:

    UINT vk = (UINT) HIWORD(msg->lParam);
    if ('E' == vk)
    // e key
    if (VK_RETURN == vk)
    // return key
    

    Note: 'ALT' key pressed by itself, i.e. not in combination with any other key, is not possible to detect using RegisterHotKey. The same goes for Left Shift or Left Control etc. To detect those guys you need to descend further into the Windows API, using SetWindowsHookEx(WH_KEYBOARD_LL,...);

    EngelardE 1 Reply Last reply
    3
    • hskoglundH hskoglund

      It's all a throwback to the 80's (think Madonna etc.) WPARAM and LPARAM are the generic names for passing around stuff in Windows messages.
      To convert a LPARAM back to a Windows Virtual Key code:

      UINT vk = (UINT) HIWORD(msg->lParam);
      if ('E' == vk)
      // e key
      if (VK_RETURN == vk)
      // return key
      

      Note: 'ALT' key pressed by itself, i.e. not in combination with any other key, is not possible to detect using RegisterHotKey. The same goes for Left Shift or Left Control etc. To detect those guys you need to descend further into the Windows API, using SetWindowsHookEx(WH_KEYBOARD_LL,...);

      EngelardE Offline
      EngelardE Offline
      Engelard
      wrote on last edited by
      #5

      @hskoglund Okay, i almost done that. Last thing is left - understand how can i put my function as a parameter to SetWindowsHookEx.

      Because this function is a class member - it gives me such an error if i try put it as a parameter:

      reference to non static member function must be called

      I even tried to do like this(myHook is my function):

      SetWindowsHookEx(WH_KEYBOARD_LL, &MainAppW::myHook, NULL, 0)
      

      But it also wrong. How should i pass my function as pointer there?

      mrjjM 1 Reply Last reply
      0
      • EngelardE Engelard

        @hskoglund Okay, i almost done that. Last thing is left - understand how can i put my function as a parameter to SetWindowsHookEx.

        Because this function is a class member - it gives me such an error if i try put it as a parameter:

        reference to non static member function must be called

        I even tried to do like this(myHook is my function):

        SetWindowsHookEx(WH_KEYBOARD_LL, &MainAppW::myHook, NULL, 0)
        

        But it also wrong. How should i pass my function as pointer there?

        mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by mrjj
        #6

        @Engelard

        Hi
        It expects the call back to be either a global ( non class function) or that memeber function be
        a static one.
        It cannot use a normal member function.

        so MainAppW::myHook must be static or you must use a global/non member function.
        https://www.learncpp.com/cpp-tutorial/812-static-member-functions/
        DO read about static before just uisng it.
        It has restrictions due to being static.
        Like the function cannot use other not non-static members variables.

        EngelardE 1 Reply Last reply
        1
        • mrjjM mrjj

          @Engelard

          Hi
          It expects the call back to be either a global ( non class function) or that memeber function be
          a static one.
          It cannot use a normal member function.

          so MainAppW::myHook must be static or you must use a global/non member function.
          https://www.learncpp.com/cpp-tutorial/812-static-member-functions/
          DO read about static before just uisng it.
          It has restrictions due to being static.
          Like the function cannot use other not non-static members variables.

          EngelardE Offline
          EngelardE Offline
          Engelard
          wrote on last edited by
          #7

          @mrjj forgot about that, tnx)

          Now when my myHook() static function is correct, everything is working. But i can't really interfere with any part of my app, since those all nonstatic.

          How can i from my static function, send any info to my ui->textBrowser for example?

          jsulmJ 1 Reply Last reply
          0
          • hskoglundH Offline
            hskoglundH Offline
            hskoglund
            wrote on last edited by hskoglund
            #8

            Hi, I had the same problem last year when I tested SetWindowsHookEx, I created a small QObject-based helper class that had the callback as a static member function. And then to make that class reachable from inside the KeyboardProc(), I created a static instance of it in my mainwindow.cpp.
            The program is here:
            https://gitlab.com/tungware/app/-/tree/main/KeyboardHookTest

            EngelardE 2 Replies Last reply
            1
            • EngelardE Engelard

              @mrjj forgot about that, tnx)

              Now when my myHook() static function is correct, everything is working. But i can't really interfere with any part of my app, since those all nonstatic.

              How can i from my static function, send any info to my ui->textBrowser for example?

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #9

              @Engelard You can always add a static method to your class which returns a pointer to the instance (see singleton pattern).

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              1
              • hskoglundH hskoglund

                Hi, I had the same problem last year when I tested SetWindowsHookEx, I created a small QObject-based helper class that had the callback as a static member function. And then to make that class reachable from inside the KeyboardProc(), I created a static instance of it in my mainwindow.cpp.
                The program is here:
                https://gitlab.com/tungware/app/-/tree/main/KeyboardHookTest

                EngelardE Offline
                EngelardE Offline
                Engelard
                wrote on last edited by Engelard
                #10

                @hskoglund Thank you for your reply, after i finished my version of this problem i viewed to yours. Frankly, it seems bit more complex then i expected) and some things like:
                alt text
                Why dont just type simple 8 in array parameters?)

                But i get the point anyway, i also tried do with signals at first, but it gave me obvious error ": call to non-static member function without an object argument" so i give up))
                Completely new for me was that thing:
                alt text
                Before i only emited signals in a simple way, like "gotKey(qc);" never had a thought that it could be called from the actual object.

                And here is how i resolved this, some might say it is foolish or dumb, but that's my first solution to this annoying STATIC issue, i get pretty perfect-looking result and i'm happy with it:

                In my worker class i created two static variables - bool eventOccured and KBDLLHOOKSTRUCT kbdStruct.
                bool initialized as FALSE, and worker class have only one function:

                void worker::threadStart()
                {
                    while(true)
                    {
                        if(eventOccured)
                        {
                            sendStruct(kbdStruct);    // <---my signal
                            eventOccured = false;
                        }
                    }
                }
                

                And here is my lovely STATIC function:

                LRESULT MainAppW::mySukaHook(int nCode, WPARAM wParam, LPARAM lParam)
                {
                    if(nCode>=0 && WM_KEYDOWN==wParam)
                    {
                        worker::kbdStruct = *(reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam));
                        worker::eventOccured = true;
                    }
                    return CallNextHookEx(MainAppW::myHook, nCode, wParam, lParam);
                }
                

                that's it folks)

                1 Reply Last reply
                0
                • mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by
                  #11

                  @Engelard said in Getting key press event for any key:

                  Why dont just type simple 8 in array parameters?)

                  If you type 8 directly. then in another place, you also type 8 directly and then someday you might want 10
                  and have to go hunt for all the 8 around in the code.
                  So its always much better to use a const named variable instead of the raw value.

                  1 Reply Last reply
                  2
                  • hskoglundH hskoglund

                    Hi, I had the same problem last year when I tested SetWindowsHookEx, I created a small QObject-based helper class that had the callback as a static member function. And then to make that class reachable from inside the KeyboardProc(), I created a static instance of it in my mainwindow.cpp.
                    The program is here:
                    https://gitlab.com/tungware/app/-/tree/main/KeyboardHookTest

                    EngelardE Offline
                    EngelardE Offline
                    Engelard
                    wrote on last edited by
                    #12

                    @hskoglund Eventually made as in your example, i only can't get one thing. What is better way to connect signals? In your program you did:

                    connect(this,&KeyboardHooker::gotKey,pMainWindow,&MainWindow::keyFromHook);
                    

                    When i always use:

                    connect(this, SIGNAL(sendStruct(tagKBDLLHOOKSTRUCT)), mWindow, SLOT(receiveStruct(tagKBDLLHOOKSTRUCT)));
                    

                    Tried to do your way, it gave me bunch of errors. What is the difference?

                    1 Reply Last reply
                    0
                    • hskoglundH Offline
                      hskoglundH Offline
                      hskoglund
                      wrote on last edited by
                      #13

                      Hi, it's called the old and new syntax and the advantage with the new syntax (without SIGNAL/SLOT) is that most of the unexpected/nasty surprises happen at compile time instead of when you run the app. Which is a good thing :-)

                      1 Reply Last reply
                      1

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved