GetWindowRect坐标与屏幕无关

GetWindowRect coordinates not screen-relative

本文关键字:屏幕 坐标 GetWindowRect      更新时间:2023-10-16

我在Visual Studio 2008 C++中工作。我有一个MFC对话框,里面有一个控件。我正试图在控件中定位另一个对话框。

第二个对话框上的SetWindowPos()显然使用了屏幕坐标,所以我需要获得控件或父对话框的屏幕坐标。MSDN文档说GetWindowRect()提供了"相对于显示屏左上角的屏幕坐标",但这不是我得到的。在控件上,它给出相对于父对象的坐标。在父对象上,它给出left=0和top=0。我也尝试过GetWindowPlacement()中的矩形,它给出了相同的结果。一切都是相对于父对象的。

为什么GetWindowRect()不返回屏幕相对坐标?还有别的办法吗?

我对编程并不陌生,但对Windows编程、Visual Studio和MFC相当陌生,所以我可能缺少一些明显的东西。

以下是我在OnInitDialog中为父对话框所做的操作:

// 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=%lin",winRect.left,winRect.top,winRect.right,winRect.bottom); fflush(pFile);
    fclose(pFile);
    return TRUE;  // return TRUE  unless you set the focus to a control
}

运行时,对话框不会出现在屏幕的左上角,但out.txt包含:

left=0 top=0 right=297 bottom=400

OnInitDialog在显示对话框之前由框架调用。在这一点上,无论是最终的大小还是位置都不知道:

在显示对话框之前立即进行的Create、CreateIndirect或DoModal调用期间,Windows会向对话框发送WM_INITDIALOG消息。

对话框的最终大小和位置是窗口定位协商的结果。发送到该信息可用的对话框的第一条消息是WM_WINDOWPOSCHANGED。使用MFC,此消息通过CWnd::OnWindowPosChanged进行处理。自定义处理代码可以通过重写CDialog派生类中的OnWindowPosChanged来实现。

如另一个答案所示:

在窗口移动到其最终位置之前,调用OnInitDialog。如果稍后调用GetWindowRect,您会看到它返回正确的坐标。

只需将PostMessage与WM_APP+n消息一起使用即可。当消息泵运行时,此消息将到达,当窗口定位并显示在屏幕上时,消息将到达。

或者使用计时器。这也有同样的效果。

OnInitDialog在窗口移动到其最终位置之前被调用。如果稍后调用GetWindowRect,您会看到它返回正确的坐标。