我的 MFC 应用程序中有一个选项对话框,我是这样创建的。 左侧有一个带有树视图的父对话框,根据所选元素,右侧会显示不同的子窗口。全部都是在VS 2022设计器中设计的。
生成的父代码:
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
生成的子代码:
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
然后,在每个子项的
OnInitDialog()
上,我使用 MoveWindow()
定位子窗口
BOOL CGlobalOptionsConfigPaths::OnInitDialog()
{
CDialogEx::OnInitDialog();
//CWnd *pWnd = CGlobalOptionsConfigPaths::GetParent();
CGlobalOptionsConfigPaths::MoveWindow(173, 30, 450, 480, true);
...
当我在外接显示器上运行应用程序时,一切看起来都很好,但当我切换到笔记本电脑屏幕时,它就崩溃了。
我已经输入了一些代码来获取父对话框和子对话框的 RECT,相信不知何故我会看到笔记本电脑和外部显示器之间的一些差异。 不幸的是(!?)事实并非如此,所以我已经无计可施了。
在这两种情况下,孩子都会遵循
MoveWindow(173, 30, 450, 480, true)
,这是理所当然的。
外部显示器上的家长 RECT:{LT(305, 170) RB(941, 757) [636 x 587]}
外部显示器上的子 RECT:{LT(478, 200) RB(928, 680) [450 x 480]}
笔记本电脑上的家长 RECT:{LT(306, 177) RB(1047, 898) [741 x 721]}
笔记本电脑上的儿童 RECT:{LT(479, 207) RB(929, 687) [450 x 480]}
在这两种情况下,child_left/top = Parent_left/top + MoveWindow 参数。 那为什么我会得到这个?
我怀疑您的其他显示器具有不同的 DPI,并且当您使用固定坐标定位子对话框时,这是行不通的。
让您了解坐标 DPI:
在 OnInitDialog 中使用以下内容
const int ppix = GetDeviceCaps(hdc, LOGPIXELSX);
const float scale = ppix / 96.0;
CGlobalOptionsConfigPaths::MoveWindow(173*scale, 30*scale, 450*scale, 480*scale, true);