2
votes

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
3
Never! GetWindowRect never returns any relative coordinates. You get always screen coordinates. Show us your code to clarify this!xMRi
Instead of describing, show your code. Too many times a poster will claim they are doing "this and that" and turns out they're not doing what they claim.PaulMcKenzie
If you are new to Windows programming, don't use a framework that requires intimate knowledge of the Windows API (like MFC does). Instead, get to know the Windows API first. It's both easier to learn and understand, as well as more direct in its effects. Learn to Program for Windows in C++ is a good starting point.IInspectable

3 Answers

2
votes

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.

1
votes

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.

1
votes

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.