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. Mouse event singleton Question.
QtWS25 Last Chance

Mouse event singleton Question.

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 2 Posters 3.0k Views
  • 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.
  • J Offline
    J Offline
    Jeronimo
    wrote on last edited by Jeronimo
    #1

    Hi i'm trying to do with singleton one program to show mouse events. But i want sometimes stop this hook so i need use this sentence:

    UnhookWindowsHookEx(mouseHook);
    

    But i'm little lost and i dont know how to add to my code;

    Code.h file:

    #ifndef MOUSELOGGER_H
    #define MOUSELOGGER_H
     
    #include <QObject>
    #include <windows.h>
     
    class MouseLogger : public QObject
    {
        Q_OBJECT
        Q_DISABLE_COPY(MouseLogger)
    public:
        static MouseLogger &instance();
        explicit MouseLogger(QObject *parent = nullptr);
        virtual ~MouseLogger(){}
     
        // Static method that will act as a callback-function   
        static LRESULT CALLBACK mouseProc(int Code, WPARAM wParam, LPARAM lParam);
     
    signals:
        // The signal, which will report the occurrence of an event
        void mouseEvent();
     
    public slots:
     
    private:
        // hook handler
        HHOOK   mouseHook;
    };
     
    #endif // MOUSELOGGER_H
    

    Code.cpp:

    #include "mouselogger.h"
    #include <QDebug>
     
    MouseLogger &MouseLogger::instance()
    {
        static MouseLogger _instance;
        return _instance;
    }
     
    MouseLogger::MouseLogger(QObject *parent) : QObject(parent)
    {
        HINSTANCE hInstance = GetModuleHandle(NULL);
     
        // Set hook
        mouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouseProc, hInstance, 0);
        // Check hook is correctly
        if (mouseHook == NULL) {
            qWarning() << "Mouse Hook failed";
        }
    }
     
    LRESULT CALLBACK MouseLogger::mouseProc(int Code, WPARAM wParam, LPARAM lParam)
    {
        Q_UNUSED(Code)
     
        // Having an event hook, we nned to cast argument lParam 
        // to the structure of the mouse is the hook.
        MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
     
        // Next, we check to see what kind of event occurred, 
        // if the structure is not a pointer to nullptr
        if(pMouseStruct != nullptr) {
            switch (wParam) {
            case WM_MOUSEMOVE:
                qDebug() << "WM_MOUSEMOVE";
                break;
            case WM_LBUTTONDOWN:
                qDebug() << "WM_LBUTTONDOWN";
                break;
            case WM_LBUTTONUP:
                qDebug() << "WM_LBUTTONUP";
                break;
            case WM_RBUTTONDOWN:
                qDebug() << "WM_RBUTTONDOWN";
                break;
            case WM_RBUTTONUP:
                qDebug() << "WM_RBUTTONUP";
                break;
            case WM_MBUTTONDOWN:
                qDebug() << "WM_MBUTTONDOWN";
                break;
            case WM_MBUTTONUP:
                qDebug() << "WM_MBUTTONUP";
                break;
            case WM_MOUSEWHEEL:
                qDebug() << "WM_MOUSEWHEEL";
                break;
            default:
                break;
            }
            emit instance().mouseEvent();
        }
     
        // After that you need to return back to the chain hook event handlers
        return CallNextHookEx(NULL, Code, wParam, lParam);
    }
    

    Main function where i want to deactivate this hook:

    #include <QCoreApplication>
    #include <QDebug>
    #include "mouselogger.h"
     
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
     
        QObject::connect(&MouseLogger::instance(), &MouseLogger::mouseEvent,
                         [](){
            qDebug() << "Mouse Event";
        });
     
        return a.exec();
    }
    
    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      hi
      you should/could make a function of our class
      like stoplogging()

      and there call
      UnhookWindowsHookEx(mouseHook);

      so in main , you can say

      MouseLogger::instance().stoplogging();

      J 2 Replies Last reply
      1
      • mrjjM mrjj

        hi
        you should/could make a function of our class
        like stoplogging()

        and there call
        UnhookWindowsHookEx(mouseHook);

        so in main , you can say

        MouseLogger::instance().stoplogging();

        J Offline
        J Offline
        Jeronimo
        wrote on last edited by
        #3

        @mrjj the member must be static?

        mrjjM 1 Reply Last reply
        0
        • mrjjM mrjj

          hi
          you should/could make a function of our class
          like stoplogging()

          and there call
          UnhookWindowsHookEx(mouseHook);

          so in main , you can say

          MouseLogger::instance().stoplogging();

          J Offline
          J Offline
          Jeronimo
          wrote on last edited by Jeronimo
          #4

          @mrjj Ok worked but i have some questions why sometimes it's useful use static method? What is the utility? If for example i want to include one signal and slot i need to do the same?
          It's useful to use qobject when and why.
          thx overall i use in databases and events games.

          mrjjM 1 Reply Last reply
          0
          • J Jeronimo

            @mrjj the member must be static?

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

            @Jeronimo
            No need to make it static as you call via an instance.
            You use static function to be able to call them WITHOUT an instance.

            Signals and slots have notning to do with static use.

            Example:

            Say we have class Printer and it has a name() function.

            If NOT static we must do
            Printer myp; // instance
            myp.name();

            if we make it static, its a not needed
            you can say
            Printer::name(); // to call it with no instance.

            Qt Example is
            QFileDialog::getOpenFileName(this,
            tr("Open Image"), "/home/jana", tr("Image Files (*.png *.jpg *.bmp)"));

            here we use a static getOpenFileName without an instance of QFileDialog

            So static is good for utility functions but should NOT be used a lot.

            1 Reply Last reply
            4
            • J Jeronimo

              @mrjj Ok worked but i have some questions why sometimes it's useful use static method? What is the utility? If for example i want to include one signal and slot i need to do the same?
              It's useful to use qobject when and why.
              thx overall i use in databases and events games.

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

              @Jeronimo
              Oh, the reason for
              static LRESULT CALLBACK mouseProc(int Code, WPARAM wParam, LPARAM lParam);
              is static here is that Windows cannot get an instance of an Object to call so it has to be plain function or
              a static function for it to call it back.

              So the reason for static here , is that the callback CANNOT live as normal function in a class and be called from outside
              from code that cannot know class types. (from your app)

              J 1 Reply Last reply
              3
              • mrjjM mrjj

                @Jeronimo
                Oh, the reason for
                static LRESULT CALLBACK mouseProc(int Code, WPARAM wParam, LPARAM lParam);
                is static here is that Windows cannot get an instance of an Object to call so it has to be plain function or
                a static function for it to call it back.

                So the reason for static here , is that the callback CANNOT live as normal function in a class and be called from outside
                from code that cannot know class types. (from your app)

                J Offline
                J Offline
                Jeronimo
                wrote on last edited by
                #7

                @mrjj Ok thx one little question if i connect the instance with qobject::connect is necessary or not?¿ because it's very using too sorry to late .

                mrjjM 1 Reply Last reply
                0
                • J Jeronimo

                  @mrjj Ok thx one little question if i connect the instance with qobject::connect is necessary or not?¿ because it's very using too sorry to late .

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

                  @Jeronimo said in Mouse event singleton Question.:

                  i connect the instance with qobject::connect is necessary or not?

                  Its not necessary for the call back ?
                  but if you want MouseLogger to emit signal , then yes you must use the Instance to connect.
                  Connect need a real object and cannot use static member functions.

                  J 1 Reply Last reply
                  1
                  • mrjjM mrjj

                    @Jeronimo said in Mouse event singleton Question.:

                    i connect the instance with qobject::connect is necessary or not?

                    Its not necessary for the call back ?
                    but if you want MouseLogger to emit signal , then yes you must use the Instance to connect.
                    Connect need a real object and cannot use static member functions.

                    J Offline
                    J Offline
                    Jeronimo
                    wrote on last edited by Jeronimo
                    #9

                    @mrjj But if for example i want to use signals and slots:
                    connect(MouseLogger::Instance(),SIGNAL(testSignal()), this,SLOT(testSlot()));

                    I can include this code to my program to use different signal and slots? but i' dont know how.

                    When you say this:
                    Signals and slots have notning to do with static use.

                    So i dont need to use static functions for this.

                    mrjjM 1 Reply Last reply
                    1
                    • J Jeronimo

                      @mrjj But if for example i want to use signals and slots:
                      connect(MouseLogger::Instance(),SIGNAL(testSignal()), this,SLOT(testSlot()));

                      I can include this code to my program to use different signal and slots? but i' dont know how.

                      When you say this:
                      Signals and slots have notning to do with static use.

                      So i dont need to use static functions for this.

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

                      @Jeronimo
                      Yes that would be the way, but one note
                      connect(MouseLogger::Instance(),SIGNAL(testSignal()), this,SLOT(testSlot()));

                      When you are in main, there is no this pointer. That have to be inside a class, say mainwindow.

                      So you would have to use the new syntax and a lambda as you already did with
                      QObject::connect(&MouseLogger::instance(), &MouseLogger::mouseEvent,
                      {
                      qDebug() << "Mouse Event";
                      });

                      The []() makes it the lamba thing and then you dont need another instance of a class for the THIS part.
                      Remember what we say is
                      connect( some instance, that signal, to this other/same instance, to this slot (function)

                      But the c+11 feature called lambda makes it possible to create function RIGHT there so to speak
                      and can be used in main - to add slots that can respond (in main) to your Logger.

                      A common design is called Producers / Consumers and it would not be a bad design
                      if anyone using the Logger would be another class ( and not main) as
                      it's very flexible as you can then just swap the Consumer (main) with some other
                      consumer and do other stuff. Or have mutiple consumers to same Producer (logger).
                      This is vastly simplified version of the design. so take it as "overall" concept.
                      https://dzone.com/articles/producer-consumer-pattern

                      Final note is:
                      Always/please do
                      qDebug << "con1:" << connect(xxx);
                      when using the SLOT() , SIGNAL() version and check it says "true" in Application output.
                      Its very helpful and takes the guessing away :)

                      J 1 Reply Last reply
                      2
                      • mrjjM mrjj

                        @Jeronimo
                        Yes that would be the way, but one note
                        connect(MouseLogger::Instance(),SIGNAL(testSignal()), this,SLOT(testSlot()));

                        When you are in main, there is no this pointer. That have to be inside a class, say mainwindow.

                        So you would have to use the new syntax and a lambda as you already did with
                        QObject::connect(&MouseLogger::instance(), &MouseLogger::mouseEvent,
                        {
                        qDebug() << "Mouse Event";
                        });

                        The []() makes it the lamba thing and then you dont need another instance of a class for the THIS part.
                        Remember what we say is
                        connect( some instance, that signal, to this other/same instance, to this slot (function)

                        But the c+11 feature called lambda makes it possible to create function RIGHT there so to speak
                        and can be used in main - to add slots that can respond (in main) to your Logger.

                        A common design is called Producers / Consumers and it would not be a bad design
                        if anyone using the Logger would be another class ( and not main) as
                        it's very flexible as you can then just swap the Consumer (main) with some other
                        consumer and do other stuff. Or have mutiple consumers to same Producer (logger).
                        This is vastly simplified version of the design. so take it as "overall" concept.
                        https://dzone.com/articles/producer-consumer-pattern

                        Final note is:
                        Always/please do
                        qDebug << "con1:" << connect(xxx);
                        when using the SLOT() , SIGNAL() version and check it says "true" in Application output.
                        Its very helpful and takes the guessing away :)

                        J Offline
                        J Offline
                        Jeronimo
                        wrote on last edited by Jeronimo
                        #11
                        This post is deleted!
                        1 Reply Last reply
                        0

                        • Login

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