切换显示器时子对话框相对于父对话框错位

问题描述 投票:0回答:1

我的 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);
...

当我在外接显示器上运行应用程序时,一切看起来都很好,但当我切换到笔记本电脑屏幕时,它就崩溃了。

External monitor screenshot

Laptop screen screenshot

我已经输入了一些代码来获取父对话框和子对话框的 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 参数。 那为什么我会得到这个?

c++ mfc
1个回答
0
投票

我怀疑您的其他显示器具有不同的 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);
© www.soinside.com 2019 - 2024. All rights reserved.