Joshua_0101
Joshua_0101

Reputation: 57

Mouse cursor always get the wrong hwnd due to tab order - MFC Application

I tried to get the window handle developed in MFC Application by using mouse cursor and print it out.

This is the code I used to get the window handle.

#include<windows.h>
#include<iostream>
using namespace std;

int main() {

        POINT pt;
        Sleep(5000);
        GetCursorPos(&pt);
        SetCursorPos(pt.x,pt.y);
        Sleep(100);

        HWND hPointWnd = WindowFromPoint(pt);
        SendMessage(hPointWnd, WM_LBUTTONDOWN, MK_LBUTTON,MAKELONG(pt.x,pt.y));
        SendMessage(hPointWnd, WM_LBUTTONUP, 0, MAKELONG(pt.x,pt.y));

        char class_name[100];
        char title[100];
        GetClassNameA(hPointWnd,class_name, sizeof(class_name));
        GetWindowTextA(hPointWnd,title,sizeof(title));
        cout <<"Window name : "<<title<<endl;
        cout <<"Class name  : "<<class_name<<endl;
        cout <<"hwnd        : " <<hPointWnd<<endl<<endl;

        system("PAUSE");
        return 0;

}

I placed my mouse cursor on the button which inside a groupbox, then the result always show me the handle of groupbox instead of button. I found that the tab order is the reason that caused I can't get the handle of button

Is there any other ways or other windows function can be used to counter the tab order issues?

Any helps will be appreciate. Thanks a lot!

Upvotes: 0

Views: 301

Answers (1)

Sergey Shevchenko
Sergey Shevchenko

Reputation: 570

At first you need to call WindowFromPoint to get the most heavily nested window handle, then you need to call RealChildWindowFromPoint to get the "real" one and avoid groupboxes. But it also avoids static text so you need to continue looking for child windows using ChildWindowFromPointEx and CWP_ALL flag.

The implementation will be like this:

POINT pt;
GetCursorPos(&pt);
// Get the window from point
HWND hWnd = WindowFromPoint(pt);    
// map cursor position to window's client coordinates
MapWindowPoints(NULL, hWnd, &pt, 1); 

while (true)
{   
    // Now let's look for real child window
    HWND hWndChild = RealChildWindowFromPoint(hWnd, pt);
    if (hWndChild == hWnd)
    {
        // There's no "real" child but we still need to look
        // for Disabled/Transparent/Invisible windows
        hWndChild = ChildWindowFromPointEx(hWnd, pt, CWP_ALL); 
    }

    if (hWndChild == NULL || hWndChild == hWnd)
        break; // we haven't found any child, stop search

    // Continue search within child window
    MapWindowPoints(hWnd, hWndChild, &pt, 1);
    hWnd = hWndChild;
}

// At this point hWnd variable should contain the handle that you're looking for

Upvotes: 2

Related Questions