Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetWindowRect coordinates not screen-relative

I am working in Visual Studio 2008 C++. I have an MFC dialog with a control inside it. I am trying to position another dialog in the control.

SetWindowPos() on the second dialog is clearly using screen coordinates, so I need to get the screen coordinates of the control or the parent dialog. The MSDN documentation says GetWindowRect() provides "screen coordinates relative to the upper-left corner of the display screen" but this is NOT what I am getting. On the control it gives coordinates relative to the parent. On the parent it gives left=0 and top=0. I have tried the rectangle from GetWindowPlacement() as well and it gives the same thing. Everything is relative to the parent.

Why is GetWindowRect() not returning screen-relative coordinates? Is there another way to get them?

I'm not new to programming, but fairly new to Windows programming, Visual Studio, and MFC, so I may be missing something obvious.

Here is what I am doing in OnInitDialog for the parent dialog:

// TestApp message handlers

BOOL TestApp::OnInitDialog()
{
    CDialog::OnInitDialog();

    FILE * pFile = fopen("out.txt","w");
    CRect winRect;
    GetWindowRect(&winRect);
    fprintf(pFile,"left=%li top=%li right=%li bottom=%li\n",winRect.left,winRect.top,winRect.right,winRect.bottom); fflush(pFile);
    fclose(pFile);

    return TRUE;  // return TRUE  unless you set the focus to a control
}

When run, the dialog does NOT appear at the upper-left corner of the screen, but out.txt contains:

left=0 top=0 right=297 bottom=400
like image 214
blippi Avatar asked Feb 01 '26 15:02

blippi


2 Answers

OnInitDialog is called by the framework, before the dialog is shown. At this point, neither the final size nor position are known:

Windows sends the WM_INITDIALOG message to the dialog box during the Create, CreateIndirect, or DoModal calls, which occur immediately before the dialog box is displayed.

The final size and position of a dialog are the result of window positioning negotiations. The first message sent to a dialog where this information is available is WM_WINDOWPOSCHANGED. Using MFC, this message is handled through CWnd::OnWindowPosChanged. Custom handling code can be implemented by overriding OnWindowPosChanged in your CDialog-derived class.

like image 59
IInspectable Avatar answered Feb 03 '26 04:02

IInspectable


As written in the other answer:

OnInitDialog is called before the window is moved to its final position. If you call GetWindowRect later you'll see it return the proper coordinates.

Just use PostMessage with a WM_APP+n message. This message will arrive when the message pump is running and the message will arrive when the window is positioned and shown on the screen.

Or use a timer. This has the same effect.

like image 40
xMRi Avatar answered Feb 03 '26 05:02

xMRi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!