We help IT Professionals succeed at work.

Get hWnd of window from right-click.

deadice
deadice asked
on
Using a simple dialog-based app, I would like to get the window title of any running window if the window's title bar is right-clicked.

I beleive I can simply call WindowFromPoint() (as well as a few other API calls), but I need to know how to trap mouse events outside of the running CDialog-derived class. Basically, all system enevts, filtering mouse events.
Comment
Watch Question

Commented:
U can use the
SetWindowsHookEx ,
CallNextHook
UnhookWindowsHookEx
functions for traping system events.

Author

Commented:
Here's the DLL I'm using:

HEADER
#ifdef MOUSEMSG_EXPORTS
#define MOUSEMSG_API __declspec(dllexport)
#else
#define MOUSEMSG_API __declspec(dllimport)
#endif

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);
extern "C"
{
     MOUSEMSG_API void SetHandle(HWND hWnd);
     MOUSEMSG_API BOOL MouseHook( void );
     MOUSEMSG_API BOOL MouseUnHook( void );
}



SOURCE
#include "stdafx.h"
#include "mousemsg.h"

#pragma comment(linker, "-section:.shared,rws")
#pragma data_seg(".shared")

HHOOK _hMouseHook = NULL;

#pragma data_seg()

HWND _hWnd = NULL;
HINSTANCE g_hInst = NULL;

BOOL APIENTRY DllMain( HINSTANCE hInstance,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                          )
{
    switch (ul_reason_for_call)
     {
          case DLL_PROCESS_ATTACH:
          case DLL_THREAD_ATTACH:  g_hInst = hInstance; break;
          case DLL_THREAD_DETACH: break;
          case DLL_PROCESS_DETACH:break;
               break;
    }
     
    return TRUE;
}

MOUSEMSG_API void SetHandle(HWND hWnd) { _hWnd = hWnd; }

MOUSEMSG_API BOOL MouseHook( void )
{
     _hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, g_hInst, 0);
     return (_hMouseHook != NULL);
}

MOUSEMSG_API BOOL MouseUnHook( void )
{
     return UnhookWindowsHookEx(_hMouseHook);
}

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < 0)  // do not process the message
        return CallNextHookEx(_hMouseHook, nCode, wParam, lParam);      
     
     if (wParam == WM_LBUTTONUP)
     {    
          LPMOUSEHOOKSTRUCT hook = (LPMOUSEHOOKSTRUCT)lParam;
          POINT point = hook->pt;
          HWND hWnd = WindowFromPoint(point);
          char chBuff[1024];
          ZeroMemory(chBuff, 1024);

          GetWindowText(hWnd, chBuff, 1024);
          if (_hWnd != NULL) SendMessage(_hWnd, WM_USER + 1, NULL, (LPARAM)chBuff);
     }
     
     return CallNextHookEx(_hMouseHook, nCode, wParam, lParam);
}


This seems to hook only the dialogs events, not the entire system. Is there something missing?

Author

Commented:
In my test app, i have (in CWinApp::InitInstance()):

     typedef BOOL (*MOUSEHOOK) (VOID);
     MOUSEHOOK MouseHook;
     
     m_hMouseDll = LoadLibrary("mousemsg.dll");
     MouseHook = (MOUSEHOOK)GetProcAddress(m_hMouseDll, "MouseHook");
     SetHandle = (SETHANDLE)GetProcAddress(m_hMouseDll, "SetHandle");

     MouseHook();
Commented:
Dear deadice,

I think you should put MouseHook( void )in you application (not in dll).

Then, your code should be (in your app. not in dll):

...
typedef long (__stdcall *MOUSE_PROC)(int nCode, WPARAM wParam, LPARAM lParam);

void MouseHook()
{
    HANDLE  dllHandle;
    dllHandle = LoadLibrary("mousemsg.dll");
    MOUSE_PROC ProcAdd;

    ProcAdd = (MOUSE_PROC) GetProcAddress((HINSTANCE)
       dllHandle, "MouseProc"); //name of mouse method
                                //in dll

    prevHandle = SetWindowsHookEx(
                            WH_KEYBOARD,
                            ProcAdd,
                            (HINSTANCE) dllHandle, 0);
     
}

...
Then you call this function from your CWinApp::OnInitInstannce()


Cheers,

MGlobal
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
You'll have to move the window handle declaration into the shared data seg:

pragma comment(linker, "-section:.shared,rws")
#pragma data_seg(".shared")

HHOOK _hMouseHook = NULL;
HWND _hWnd = NULL;

#pragma data_seg()

and it should work...