Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Detecting doubleclick on a desktop window - part 2.

Detecting doubleclick on a desktop window - part 2.

Scheduled Pinned Locked Moved C / C++ / MFC
questionc++help
4 Posts 2 Posters 0 Views 1 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.
  • P Offline
    P Offline
    PatrykDabrowski
    wrote on last edited by
    #1

    Hello, I have some questions about using global (system wide) hooks in Win32. I've got a simple app loading my simple DLL which sets up a WH_MOUSE hook: m_hhook=SetWindowsHookEx(WH_MOUSE,MouseProc,m_hmod,0); (inside DLL) My MouseProc is: (also inside DLL) HOOKTEST2DLL_API LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { MOUSEHOOKSTRUCT *mhs=(MOUSEHOOKSTRUCT *)lParam; if(nCode < 0) // do not process the message return CallNextHookEx(m_hhook, nCode, wParam, lParam); else { if((nCode==HC_ACTION) && (wParam==WM_LBUTTONDBLCLK)) { PostThreadMessage(m_appthreadid,WM_APP+1,0,0); m_mouseproc_counter++; } return CallNextHookEx(m_hhook, nCode, wParam, lParam); } } I have also some variables in shared section of DLL which are initialised using: HOOKTEST2DLL_API void fnInit() { m_hwnd_app=NULL; //main application window HWND m_hhook=NULL; //WH_MOUSE hook handle m_hwnd_desktop=::GetDesktopWindow(); //desktop window handle m_mouseproc_counter=0; //mouse-dblclicks counter m_appthreadid=NULL; //main application's thread ID m_hmod=GetModuleHandle("HookTest2DLL.dll"); //DLL module handle } My questions are: 1) Why PostMessage(m_hwnd_app,WM_APP+1,0,0) doesn't work? Variable m_hwnd_app is set up after DLL is loaded and points to the main window of my simple MFC app. PostThreadMessage(m_appthreadid,WM_APP+1,0,0) works fine. 2) When I detect a doubleclick on desktop screen, in my MOUSEHOOKSTRUCT structure hwnd is set to 0x10094 (::GetDesktopWindow() returns 0x10014) but even when I double-click on any desktop icon (ie My Computer) I'm getting this event. Is it possible to filter out those events connected with double-clicking on desktop icons?? 3) What is the best way of communicating between DLL and host application in case, when DLL could be injected into other threads/processes? Can I use variables in shared data section of my DLL or only PostThreadMessage() should be used? Thank for any help:) Pat.

    P N 2 Replies Last reply
    0
    • P PatrykDabrowski

      Hello, I have some questions about using global (system wide) hooks in Win32. I've got a simple app loading my simple DLL which sets up a WH_MOUSE hook: m_hhook=SetWindowsHookEx(WH_MOUSE,MouseProc,m_hmod,0); (inside DLL) My MouseProc is: (also inside DLL) HOOKTEST2DLL_API LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { MOUSEHOOKSTRUCT *mhs=(MOUSEHOOKSTRUCT *)lParam; if(nCode < 0) // do not process the message return CallNextHookEx(m_hhook, nCode, wParam, lParam); else { if((nCode==HC_ACTION) && (wParam==WM_LBUTTONDBLCLK)) { PostThreadMessage(m_appthreadid,WM_APP+1,0,0); m_mouseproc_counter++; } return CallNextHookEx(m_hhook, nCode, wParam, lParam); } } I have also some variables in shared section of DLL which are initialised using: HOOKTEST2DLL_API void fnInit() { m_hwnd_app=NULL; //main application window HWND m_hhook=NULL; //WH_MOUSE hook handle m_hwnd_desktop=::GetDesktopWindow(); //desktop window handle m_mouseproc_counter=0; //mouse-dblclicks counter m_appthreadid=NULL; //main application's thread ID m_hmod=GetModuleHandle("HookTest2DLL.dll"); //DLL module handle } My questions are: 1) Why PostMessage(m_hwnd_app,WM_APP+1,0,0) doesn't work? Variable m_hwnd_app is set up after DLL is loaded and points to the main window of my simple MFC app. PostThreadMessage(m_appthreadid,WM_APP+1,0,0) works fine. 2) When I detect a doubleclick on desktop screen, in my MOUSEHOOKSTRUCT structure hwnd is set to 0x10094 (::GetDesktopWindow() returns 0x10014) but even when I double-click on any desktop icon (ie My Computer) I'm getting this event. Is it possible to filter out those events connected with double-clicking on desktop icons?? 3) What is the best way of communicating between DLL and host application in case, when DLL could be injected into other threads/processes? Can I use variables in shared data section of my DLL or only PostThreadMessage() should be used? Thank for any help:) Pat.

      P Offline
      P Offline
      PatrykDabrowski
      wrote on last edited by
      #2

      To my question 2) Using Spy++ I have figured out, that capturing additional message LVM_HITTEST could solve my problem. When double-clicking on desktop, Windows generates LVM_HITTEST message with nIndex set to icon which we are clicking on, or -1 when we click on desktop. Messages come in this order (in case of doubleclick) 1.LVM_HITTEST (first click) 2.LVM_HITTEST (second click) 3.WM_LBUTTONDBLCLK ...so it's safe to cache last LVM_HITTEST message and when WM_LBUTTONDBLCLK happen, just check nIndex of last cached message, if it's -1 we have a double-click on desktop. Any faster/simpler solution?? (it would be nice if I could detect it based on only one message) Another question is how to capture LVM_HITTEST message? Another system-wide hook?:/ Thanks for any help:) Pat.

      P 1 Reply Last reply
      0
      • P PatrykDabrowski

        To my question 2) Using Spy++ I have figured out, that capturing additional message LVM_HITTEST could solve my problem. When double-clicking on desktop, Windows generates LVM_HITTEST message with nIndex set to icon which we are clicking on, or -1 when we click on desktop. Messages come in this order (in case of doubleclick) 1.LVM_HITTEST (first click) 2.LVM_HITTEST (second click) 3.WM_LBUTTONDBLCLK ...so it's safe to cache last LVM_HITTEST message and when WM_LBUTTONDBLCLK happen, just check nIndex of last cached message, if it's -1 we have a double-click on desktop. Any faster/simpler solution?? (it would be nice if I could detect it based on only one message) Another question is how to capture LVM_HITTEST message? Another system-wide hook?:/ Thanks for any help:) Pat.

        P Offline
        P Offline
        PatrykDabrowski
        wrote on last edited by
        #3

        Finally I've found a way to filter-out all icons connected WM_LMOUSEDBLCLK messages. My MouseProc() now looks like this: HOOKTEST2DLL_API LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { MOUSEHOOKSTRUCT *mhs=(MOUSEHOOKSTRUCT *)lParam; LVHITTESTINFO pinfo; if(nCode < 0) // do not process the message { return CallNextHookEx(m_hhook, nCode, wParam, lParam); } else { if((nCode==HC_ACTION) && (wParam==WM_LBUTTONDBLCLK)) { if(mhs->hwnd==m_hwnd_desktop) //==0x10094 { pinfo.pt=mhs->pt; if(SendMessage(m_hwnd_desktop,LVM_HITTEST,0,(LPARAM)&pinfo)==-1) { PostThreadMessage(m_appthreadid,WM_APP+1,mhs->pt.x,mhs->pt.y); m_mouseproc_counter++; } } } return CallNextHookEx(m_hhook, nCode, wParam, lParam); } } It seems to be fine, I'm getting WM_APP+1 messages only when I double-click on desktop window and not on any desktop icon:) Well, this leads me to another question: 4) How to find in a system-friendly and Windows compatible way this 'magic' window handle 0x00010094? Using Spy++ I could find out the class name and window name. My current code looks like this: HWND h1=::FindWindowEx(NULL,NULL,"Progman","Program Manager"); HWND h2=::FindWindowEx(h1,NULL,"SHELLDLL_DefView",NULL); m_hwnd_desktop=::FindWindowEx(h2,NULL,"SysListView32",NULL); ...and it's working fine, but that's strange that a single line: m_hwnd_desktop=::FindWindowEx(NULL,NULL,"SysListView32","ListView"); ...does NOT work (returns NULL). Is this method 'safe and compatible'? Pat.

        1 Reply Last reply
        0
        • P PatrykDabrowski

          Hello, I have some questions about using global (system wide) hooks in Win32. I've got a simple app loading my simple DLL which sets up a WH_MOUSE hook: m_hhook=SetWindowsHookEx(WH_MOUSE,MouseProc,m_hmod,0); (inside DLL) My MouseProc is: (also inside DLL) HOOKTEST2DLL_API LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { MOUSEHOOKSTRUCT *mhs=(MOUSEHOOKSTRUCT *)lParam; if(nCode < 0) // do not process the message return CallNextHookEx(m_hhook, nCode, wParam, lParam); else { if((nCode==HC_ACTION) && (wParam==WM_LBUTTONDBLCLK)) { PostThreadMessage(m_appthreadid,WM_APP+1,0,0); m_mouseproc_counter++; } return CallNextHookEx(m_hhook, nCode, wParam, lParam); } } I have also some variables in shared section of DLL which are initialised using: HOOKTEST2DLL_API void fnInit() { m_hwnd_app=NULL; //main application window HWND m_hhook=NULL; //WH_MOUSE hook handle m_hwnd_desktop=::GetDesktopWindow(); //desktop window handle m_mouseproc_counter=0; //mouse-dblclicks counter m_appthreadid=NULL; //main application's thread ID m_hmod=GetModuleHandle("HookTest2DLL.dll"); //DLL module handle } My questions are: 1) Why PostMessage(m_hwnd_app,WM_APP+1,0,0) doesn't work? Variable m_hwnd_app is set up after DLL is loaded and points to the main window of my simple MFC app. PostThreadMessage(m_appthreadid,WM_APP+1,0,0) works fine. 2) When I detect a doubleclick on desktop screen, in my MOUSEHOOKSTRUCT structure hwnd is set to 0x10094 (::GetDesktopWindow() returns 0x10014) but even when I double-click on any desktop icon (ie My Computer) I'm getting this event. Is it possible to filter out those events connected with double-clicking on desktop icons?? 3) What is the best way of communicating between DLL and host application in case, when DLL could be injected into other threads/processes? Can I use variables in shared data section of my DLL or only PostThreadMessage() should be used? Thank for any help:) Pat.

          N Offline
          N Offline
          Naveen
          wrote on last edited by
          #4

          PatrykDabrowski wrote:

          PostThreadMessage(m_appthreadid,WM_APP+1,0,0);

          instead of using the WM_APP+1, use RegisterWindowMessage to create a unique message.

          nave

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups