A Better CenterWindow() Function






4.57/5 (4 votes)
Aug 8, 2000

109477

778
This is a good replacement for CWnd::CenterWindow() that works.
Figure 1. The main CenterSample
sample program screen.
Introduction
Centering windows on the screen is something which you can normally do with the
CWnd::CenterWindow()
function in MFC. CenterWindow()
takes a pointer to a CWnd
as its argument, and supposedly the function
will center the window on which it's called against the window to which you pass it
a pointer:
pDlg->CenterWindow(AfxGetMainWnd()); // Centers pDlg against the main window?
Listing 1. Demonstrating a use of CWnd::CenterWindow()
to center a dialog.
However, a question posed to the MFC Mailing List
recently asked, "I have a dialog-based program, where the user can click a button and
have a sub-dialog pop up. If I call CWnd::CenterWindow()
in the sub-dialog's
OnInitDialog()
handler, the dialog will always be centered in the center
of the screen, not centered with respect to the main dialog. How do I do this?"
So I came up with a "Brute Force" centering function which actually works better
than CWnd::CenterWindow()
. It's called
CSubDialog::CenterWindowOnOwner()
, and I added to my sample program's
sub-dialog's class, CSubDialog
:
void CSubDialog::CenterWindowOnOwner(CWnd* pWndToCenterOn) { // Get the client rectangle of the window on which we want to center // Make sure the pointer is not NULL first if (pWndToCenterOn == NULL) return; CRect rectToCenterOn; pWndToCenterOn->GetWindowRect(&rectToCenterOn); // Get this window's area CRect rectSubDialog; GetWindowRect(&rectSubDialog); // Now rectWndToCenterOn contains the screen rectangle of the window // pointed to by pWndToCenterOn. Next, we apply the same centering // algorithm as does CenterWindow() // find the upper left of where we should center to int xLeft = (rectToCenterOn.left + rectToCenterOn.right) / 2 - rectSubDialog.Width() / 2; int yTop = (rectToCenterOn.top + rectToCenterOn.bottom) / 2 - rectSubDialog.Height() / 2; // Move the window to the correct coordinates with SetWindowPos() SetWindowPos(NULL, xLeft, yTop, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); }Listing 2. Our brute-force
CenterWindowOnOwner()
function.
Then I added code to CSubDialog::OnInitDialog()
to center it with respect
to the main dialog, which is the main window of the application:
BOOL CSubDialog::OnInitDialog()
{
CDialog::OnInitDialog();
...
CWnd* pMainWnd = AfxGetMainWnd();
CenterWindowOnOwner(pMainWnd);
return TRUE;
}
Listing 3.How to call CenterWindowOnOwner()
.
And voila! The sub-dialog will always center itself on the main dialog (or main application window), no matter where on the screen that window is placed.