I have an options dialog in my MFC application which I have created like this. There is a parent dialog with a treeview on the left and depending on the selected element, a different child window is shown on the right. All of them are designed in the VS 2022 designer.
The generated parent code:
IDD_GLOBAL_OPTIONS DIALOGEX 0, 0, 413, 337
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CONTROLPARENT | WS_EX_APPWINDOW
CAPTION "Global Options"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,291,315,50,14
PUSHBUTTON "Cancel",IDCANCEL,348,315,50,14
EDITTEXT IDC_EDIT_GLOBAL_OPTIONS_NAME,123,14,275,12,ES_UPPERCASE | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_CLIENTEDGE
CONTROL "",IDC_GLOBAL_OPTIONS_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_NOHSCROLL | WS_BORDER | WS_TABSTOP,7,15,108,294
END
The generated child code:
IDD_GLOBAL_OPTIONS_CONFIGPATHS DIALOGEX 0, 0, 297, 291
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
FONT 8, "MS Shell Dlg", 400, 0, 0x0
BEGIN
GROUPBOX "Configuration directory",IDC_STATIC,10,15,279,52
LTEXT "Configuration data store location",IDC_STATIC,22,31,106,8
CONTROL "",IDC_MFCEDITBROWSE1,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,22,42,260,14
GROUPBOX "Personal data directory",IDC_STATIC,10,74,279,77
LTEXT "Personal data such as usernames, passwords and automated login information can be stored separately from all other configuration data",IDC_STATIC,22,89,260,23
CONTROL "Store personal data separately",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,116,115,10
CONTROL "",IDC_MFCEDITBROWSE2,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,32,128,250,14
END
Then, on OnInitDialog()
for each child, I position the child window using MoveWindow()
BOOL CGlobalOptionsConfigPaths::OnInitDialog()
{
CDialogEx::OnInitDialog();
//CWnd *pWnd = CGlobalOptionsConfigPaths::GetParent();
CGlobalOptionsConfigPaths::MoveWindow(173, 30, 450, 480, true);
...
Everything looks fine when I run the application on my external monitor, but when I switch to the laptop screen, it falls apart.
I have put some code to get the RECTs for both the parent dialog and the child one, believing that somehow I would see some discrepancy between laptop and external monitor. Unfortunately(!?) this is not the case, so I am at the end of my wit.
On both cases the child follows the MoveWindow(173, 30, 450, 480, true)
as it of course should.
Parent RECT on external monitor: {LT(305, 170) RB(941, 757) [636 x 587]}
Child RECT on external monitor: {LT(478, 200) RB(928, 680) [450 x 480]}
Parent RECT on laptop: {LT(306, 177) RB(1047, 898) [741 x 721]}
Child RECT on laptop: {LT(479, 207) RB(929, 687) [450 x 480]}
On both cases child_left/top = parent_left/top + MoveWindow arguments. So why I am getting this?
So, as it happens the solution from @user20716902 didn't work for me. It just shifted the window to the right side xD
However, the comment from @markransom gave me a nice tip.
So here's what worked for me:
In parent class in ::OnInitDialog()
RECT rcPos;
position1.GetWindowRect(&rcPos);
ScreenToClient(&rcPos);
POINT childLocation = { 0 };
childLocation.x = rcPos.left;
childLocation.y = rcPos.top;
The position1 is just a static text on the top left of the parent window, which I am going to hide.
Then for every child class:
->SetLocationInMotherForm(childLocation);
Each child class extends CDialogEx
void CDialogExtended::SetLocationInMotherForm(POINT p)
{
locationInMotherForm.x = p.x;
locationInMotherForm.y = p.y;
}
And finally on each child in ::OnInitDialog()
CGlobalOptionsConfigPaths::SetWindowPos(NULL, locationInMotherForm.x, locationInMotherForm.y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);