Results 1 to 19 of 19

Thread: WM_LBUTTONDBLCLK message and global mouse hook

  1. #1
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default WM_LBUTTONDBLCLK message and global mouse hook

    I have written a DLL that globally hooks the mouse using SetWindowsHookEx function

    Qt Code:
    1. hInst = (HINSTANCE)::GetModuleHandle(ap.toStdWString().c_str());
    2. mouseHook = (HHOOK)::SetWindowsHookEx(WH_MOUSE_LL,(HOOKPROC)MouseProc,hInst,0);
    To copy to clipboard, switch view to plain text mode 

    The MouseProc function is given below

    Qt Code:
    1. static LRESULT CALLBACK MouseProc(UINT nCode, WPARAM wParam, LPARAM lParam)
    2. {
    3. if(nCode < 0)
    4. {
    5. ::CallNextHookEx(mouseHook, nCode, wParam, lParam);
    6. return 0;
    7. }
    8.  
    9. if(wParam == WM_LBUTTONDBLCLK)
    10. qDebug(QString("Double click happen...").toAscii());
    11.  
    12. //qDebug(QString("WPARAM = %1").arg(int(wParam)).toAscii());
    13.  
    14. return ::CallNextHookEx(mouseHook, nCode, wParam, lParam);
    15. }
    To copy to clipboard, switch view to plain text mode 

    I am loading the dll from a dialog based application. My problem is whenever I am double click, I am not getting WM_LBUTTONDBLCLK instead I am getting WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDOWN WM_LBUTTONUP combination.

    Please help me on how to write the dll that MouseProc get WM_LBUTTONDBLCLK message whenever I double click.

    thanks

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    This is an off topic question - its not related to Qt!

    Did you make sure that the window has CS_DBLCLKS style?

    http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx
    Only windows that have the CS_DBLCLKS style can receive WM_LBUTTONDBLCLK messages, which the system generates whenever the user presses, releases, and again presses the left mouse button within the system's double-click time limit. Double-clicking the left mouse button actually generates a sequence of four messages: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, and WM_LBUTTONUP.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  3. #3
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    Thanks high_flyer for the reply. You are right, my window may not have the CS_DBLCLKS style. Please guide me how to set CS_DBLCLKS style for my winodw.

    thanks again

  4. #4
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    . Please guide me how to set CS_DBLCLKS style for my winodw.
    Please refer to Windows specific forums for such things, and google is a good place to start.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  5. #5
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    I am writing the dll in Qt Creator using Qt. The application that loading the dll is also a Qt application. Because I dont have access to WinMain or DllMain function, I am confused how to set CS_DBLCLKS style in a Qt application.

    Sorry for not making myself clear before.

  6. #6
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    I am writing the dll in Qt Creator using Qt.
    That is all well and good, but the problem you have is not Qt problem.
    In addition, why are you using Qt at all, if your code is purely native windows?
    What is the benefit you get from Qt then, when you don't event use Qt for the windows (widgets), but crate them natively with WIN32/MFC?
    Sure you can do it, but why?

    If you would use Qt, you could just use the mouseDoubleClickEvent ().

    Since you are using native code, your problem is also native (windows) and has nothing to do with Qt.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  7. #7
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    Quote Originally Posted by high_flyer View Post
    That is all well and good, but the problem you have is not Qt problem.
    In addition, why are you using Qt at all, if your code is purely native windows?
    What is the benefit you get from Qt then, when you don't event use Qt for the windows (widgets), but crate them natively with WIN32/MFC?
    Sure you can do it, but why?
    I have written a application in Qt. That application can run on Windows as well as on Linux. The application supports plugins. Now I want to write a plugin for that application (the plugin currently runs on Windows only).

    When the application loads any plugin it searches for

    Qt Code:
    1. void initializePlugin(QString, QString, QMenu*)
    To copy to clipboard, switch view to plain text mode 

    function and calls that function. The plugin I want to write, pops up that QMenu when user doubleclicks on an empty space of the desktop. That is why I want to hook the mouse globally, to find out when user doubleclicks the mouse, is it on an empty space on the desktop or not.

    My application main window is derived from QMainWindow class. MouseProc function is receiving mouse doubleclicks event when I am hooking the mouse in thread mode i.e. by WH_MOUSE instead of WH_MOUSE_LL. Does that mean that my main window already has CS_DBLCLKS style?

  8. #8
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    That application can run on Windows as well as on Linux
    I am sorry, but the code you posted is 100% windows, and will never compile on Linux.

    My application main window is derived from QMainWindow class.
    Then just use mouseDoubleClickEvent () to capture double clicks. (the original problem you posted).
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  9. #9
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    I think if I override mouseDoubleClickEvent() of my main window, I will get all the mouse double clicks that happen when user double clicks on my application window. But I want to capture the mouse double clicks that happen when user double click on any empty space on the desktop. So that I can make the menu popup on the desktop at the point where user double clicks. That is why I want to hook the mouse globally.

    The code I posted is the code of the plugin, not the main application. The plugin currently runs on windows only. But the application can run on windows and on linux. I am sorry I didn't write it clearly before.

    The problem is that when I am using WH_MOUSE I am getting the local double clicks (like mouseDoubleClickEvent), but when I am using WH_MOUSE_LL I am getting local mouse clicks as well as mouse clicks that are outside the application main window. But I am not getting WM_LBUTTONDBLCLK instead I am getting WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDOWN WM_LBUTTONUP combination.

    So my question is whether this incident is Qt specific or I will get the same result if I write my main application purely in API?

  10. #10
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    But I want to capture the mouse double clicks that happen when user double click on any empty space on the desktop.
    I haven't tried it, but it might work:
    Try overriding the mouseDoubleClickEvent() of the QDesktopWidget.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  11. #11
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    I have tried QDesktopWidget but with no luck. Here is the code of the DLL file

    The mouseHookPlugin_global.h looks like

    Qt Code:
    1. #ifndef MOUSEHOOKPLUGIN_GLOBAL_H
    2. #define MOUSEHOOKPLUGIN_GLOBAL_H
    3.  
    4. #include <QtCore/qglobal.h>
    5.  
    6. #if defined(MOUSEHOOKPLUGIN_LIBRARY)
    7. # define MOUSEHOOKPLUGINSHARED_EXPORT Q_DECL_EXPORT
    8. #else
    9. # define MOUSEHOOKPLUGINSHARED_EXPORT Q_DECL_IMPORT
    10. #endif
    11.  
    12. #ifdef Q_OS_WIN
    13. #define MY_EXPORT __declspec(dllexport)
    14. #else
    15. #define MY_EXPORT
    16. #endif
    17.  
    18. #endif // MOUSEHOOKPLUGIN_GLOBAL_H
    To copy to clipboard, switch view to plain text mode 

    The header file looks like

    Qt Code:
    1. #ifndef MOUSEHOOKPLUGIN_H
    2. #define MOUSEHOOKPLUGIN_H
    3.  
    4. #include <QString>
    5. #include <QMenu>
    6. #include <QDesktopWidget>
    7. #include <QTimer>
    8. #include <QMouseEvent>
    9.  
    10. #include "mouseHookPlugin_global.h"
    11.  
    12. extern "C"
    13. {
    14. MY_EXPORT void initializePlugin(QString, QString, QMenu*);
    15. MY_EXPORT void uninitializePlugin();
    16. }
    17.  
    18. class MOUSEHOOKPLUGINSHARED_EXPORT MouseHookPlugin : public QDesktopWidget
    19. {
    20. Q_OBJECT
    21. public:
    22. MouseHookPlugin();
    23. ~MouseHookPlugin();
    24.  
    25. void mouseDoubleClickEvent(QMouseEvent *);
    26.  
    27. public slots:
    28. void slotShowMenu();
    29. void slotInitializePlugin(QString, QString, QMenu*);
    30. void slotUninitializePlugin();
    31.  
    32. //void slotTimerTicks();
    33.  
    34. private:
    35. QString appPath;
    36. QString setPath;
    37. QMenu* ruMenu;
    38. };
    39.  
    40. #endif // MOUSEHOOKPLUGIN_H
    To copy to clipboard, switch view to plain text mode 

    and the cpp file looks like

    Qt Code:
    1. #include "mousehookplugin.h"
    2.  
    3. namespace
    4. {
    5. MouseHookPlugin *mhp;
    6. }
    7.  
    8. void initializePlugin(QString ap, QString sp, QMenu* ru)
    9. {
    10. mhp = new MouseHookPlugin();
    11. mhp->slotInitializePlugin(ap,sp,ru);
    12. }
    13.  
    14. void uninitializePlugin()
    15. {
    16. mhp->slotUninitializePlugin();
    17. delete mhp;
    18. }
    19.  
    20. MouseHookPlugin::MouseHookPlugin()
    21. {
    22. ruMenu = NULL;
    23. }
    24.  
    25. MouseHookPlugin::~MouseHookPlugin()
    26. {
    27.  
    28. }
    29.  
    30. void MouseHookPlugin::mouseDoubleClickEvent(QMouseEvent *e)
    31. {
    32. if(e->button() == Qt::LeftButton)
    33. qDebug(QString("Mouse double clicked...").toAscii());
    34. }
    35.  
    36. void MouseHookPlugin::slotShowMenu()
    37. {
    38. if(ruMenu)
    39. {
    40. QMenu *pMenu = ruMenu->actions()[1]->menu();
    41. if(pMenu)
    42. {
    43. pMenu->popup(QCursor::pos());
    44. pMenu->activateWindow();
    45. }
    46. }
    47. }
    48.  
    49. void MouseHookPlugin::slotInitializePlugin(QString ap, QString sp, QMenu* ru)
    50. {
    51. appPath = ap;
    52. setPath = sp;
    53. ruMenu = ru;
    54.  
    55. qDebug(QString("Initialization completed...").toAscii());
    56. }
    57.  
    58. void MouseHookPlugin::slotUninitializePlugin()
    59. {
    60. qDebug(QString("Uninitialization completed...").toAscii());
    61. }
    To copy to clipboard, switch view to plain text mode 

    I am not getting any double clicks, local or global. Am I missing something?

  12. #12
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    As I said, I haven't tried it, so it might not work.
    Did you enable mouse grabbing for you widget?
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  13. #13
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    No high_flyer grabbing mouse didn't help. I am surprised, I thought QDesktopWidget is just what I am looking for.

    thanks

  14. #14
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    I can't test code at the moment, so I can't try it my self.
    If you don't get the double clicks from the desktop widget, you will have to hook natively to the mouse event on the desktop for that you will be better served on windows specific forums such as code guru.

    Wait a minute - how are you using your desktop widget?
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  15. #15
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    I have written the complete code of the dll in my last but two posts, considering this one as the last.

  16. #16
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    No, you have written the definition and implementation of your class, not its usage.
    You need to get your desktop widget from QApplicaiton.
    Now it occurs to me, that if you can't tell QApplication to use your Class (and as far as I know you can't), then what you just tried, is will not work (sorry, didn't think about it before).
    What you can do however, is write an external event filter for the desktop widget you get from QApplication, and there extract the double click events - this should work, provided Qt indeed delivers double clicks form the desktop to this widget.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  17. #17
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    Just scanned through the thread... QDesktopWidget is an artificial "read-only" widget providing QWidget-like access to the root window (desktop). It is not the desktop itself so reimplementing its methods will not yield any practical result. The approach to intercept native messages is a good one but your problem has really nothing to do with Qt. I can only suggest to reimplement QCoreApplication::winEventFilter() or use QCoreApplication::setEventFilter() after you have requested the system to pass all events to you. But whether your request was a valid one or not - this is really not Qt-related so we can't help you. You should ask on some WinAPI forum instead.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  18. #18
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    You can't intercept double clicks in a system wide mouse hook on Windows. The reason for this is because the OS will concatenate the four messages into a double click only for windows which have the class style CS_DBLCLK set (as stated above).

    However, since the WH_MOUSE_LL is triggered before the message is put on the window message queue it cannot know if it is going to be converted into a double click or not. Therefore, you will receive the four individual messages and you must do the double click management yourself.

    There is a function that will retrieve the configured timing for double clicks, it's called GetDoubleClickTime() and part of the WinAPI.

  19. #19
    Join Date
    Dec 2009
    Posts
    26
    Thanks
    3
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: WM_LBUTTONDBLCLK message and global mouse hook

    thanks high_flyer, wysota and squidge. Ok I will try to use GetDoubleClickTime(). Thanks again.

Similar Threads

  1. hook resizeEvent
    By prashant in forum Qt Programming
    Replies: 6
    Last Post: 7th September 2009, 11:35
  2. Replies: 4
    Last Post: 12th October 2008, 13:47
  3. How to know current global mouse position?
    By Teerayoot in forum Qt Programming
    Replies: 2
    Last Post: 11th May 2007, 19:25
  4. QT Keyboard Hook
    By MarcSchubert in forum Qt Programming
    Replies: 1
    Last Post: 6th May 2007, 11:28
  5. hook
    By incapacitant in forum Newbie
    Replies: 3
    Last Post: 29th August 2006, 19:53

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.