MFC opening dialog, find starting position

Bryan Kelly 516 Reputation points
2025-07-24T19:47:16.2833333+00:00

Windows 11, Visual Studio 2022, C++ MFC

This line is in OnInitDialog() of the class that starts when the app is started in debug mode.

CWnd::GetWindowRect( &m_dialog_location_size );``  ``// Get the window rectangle           

The .left and .top items are zero.  But the dialog is in the middle of the monitor, definitely not the zero position.  Move the main VS development dialog to the left monitor, the dialog still pops up in the middle of the development dialog, but the value for the left side does not change.

The code can set positions in m_dialog_location_size and place the dialog where desired.

What is the code to get the actual position of the dialog?  Is it different when using two monitors?

Developer technologies | Visual Studio | Debugging
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. RLWA32 50,066 Reputation points
    2025-07-24T20:51:51.0766667+00:00

    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.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.