The dialog is being repositioned after OnInitDialog has been called but before it becomes visible. That is why the coordinates returned by GetWindowRect inside the OnInitDialog function are out of sync with what you see when the dialog becomes visible.
You can implement the solution discussed at Waiting until the dialog box is displayed before doing something
For an MFC dialog based application -
Header -
// MFCDlgPosDlg.h : header file
//
#pragma once
// CMFCDlgPosDlg dialog
class CMFCDlgPosDlg : public CDialogEx
{
// Construction
public:
CMFCDlgPosDlg(CWnd* pParent = nullptr); // standard constructor
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MFCDLGPOS_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
bool m_bDialogShown{ false }; // Added by RLWA32
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnWindowPosChanged(WINDOWPOS* lpwndpos);
protected:
afx_msg LRESULT OnDialogShown(WPARAM wParam, LPARAM lParam);
};
Implementation -
// MFCDlgPosDlg.cpp : implementation file
//
#include "pch.h"
#include "framework.h"
#include "MFCDlgPos.h"
#include "MFCDlgPosDlg.h"
#include "afxdialogex.h"
// Custom message added
#define WM_DIALOG_SHOWN WM_APP + 42
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CMFCDlgPosDlg dialog
CMFCDlgPosDlg::CMFCDlgPosDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_MFCDLGPOS_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMFCDlgPosDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CMFCDlgPosDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_WINDOWPOSCHANGED()
ON_MESSAGE(WM_DIALOG_SHOWN, &CMFCDlgPosDlg::OnDialogShown)
END_MESSAGE_MAP()
// CMFCDlgPosDlg message handlers
BOOL CMFCDlgPosDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CMFCDlgPosDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CMFCDlgPosDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMFCDlgPosDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CMFCDlgPosDlg::OnWindowPosChanged(WINDOWPOS* lpwndpos)
{
CDialogEx::OnWindowPosChanged(lpwndpos);
// TODO: Add your message handler code here
if ((lpwndpos->flags & SWP_SHOWWINDOW) && !m_bDialogShown)
{
m_bDialogShown = true;
PostMessage(WM_DIALOG_SHOWN);
}
}
afx_msg LRESULT CMFCDlgPosDlg::OnDialogShown(WPARAM wParam, LPARAM lParam)
{
CRect rc;
GetWindowRect(&rc);
TRACE("left: %d, top: %d, right: %d, bottom: %d\n",
rc.left, rc.top, rc.right, rc.bottom);
return 0;
}
The OnDialogShown function is called the very first time that the dialog becomes visible and prints its coordinates to the output pane.