首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有控件的DialogEx :调整大小?

带有控件的DialogEx :调整大小?
EN

Stack Overflow用户
提问于 2016-02-27 12:21:41
回答 2查看 1.4K关注 0票数 0

其目的是调整DialogEx窗口的大小,以便最适合对象机器上配置的系统度量、屏幕高度和屏幕深度:

代码语言:javascript
复制
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    return DialogBoxW(hInstance, MAKEINTRESOURCEW(IDD_MAIN), nullptr, DlgProc);
}

IDD_MAIN是768 p中的默认设置。让我们将其命名为IDD_760P,并使用它的资源文件配置作为工作的基础。

代码语言:javascript
复制
IDD_768P DIALOGEX 0, 0, 701, 191
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "MahProject"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
    LTEXT           "Add",IDC_STATIC,506,10,14,8
    EDITTEXT        IDC_TEXT,528,7,120,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_NUMBER,647,7,21,14,ES_NUMBER
    LTEXT           "times.",IDC_STATIC,671,10,23,8
    LISTBOX         IDC_LIST,7,22,641,148,LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP //principal, main, or chief control on form
    PUSHBUTTON      "&Add",IDC_ADD,650,30,46,14
    PUSHBUTTON      "&Up",IDC_UP,650,47,47,14
    PUSHBUTTON      "&Down",IDC_DOWN,650,63,47,14
    PUSHBUTTON      "&Sideways",IDC_CREATE,650,80,47,14
    PUSHBUTTON      "&UpsideDown",IDC_REMOVE,650,97,47,14
    PUSHBUTTON      "&Less",IDC_CLEAR,650,114,47,14
    PUSHBUTTON      "&More",IDC_LOGON,650,131,47,14
    PUSHBUTTON      "&NoMore",IDC_NOLOGON,650,148,47,14
    LTEXT           "Great",IDC_STATIC_ONE,530,180,70,8
    CTEXT           "-",IDC_SHOWCOUNT,600,180,25,8
    LTEXT           "Fantastic",IDC_STATIC_TWO,625,180,30,8
END

根据这个CreateWindow,这些控件可以单独地用帖子重新校准,但这是很多代码。

是否有一种方法对表单进行子类化,以使用基于以上内容的额外资源文件预置,用于IDD_1080PIDD_2160P, IDD_4320P和beyond?在代码中,我们将把GetSystemMetrics(SM_CXSCREEN)GetSystemMetrics(SM_CYSCREEN)函数放在哪里?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-27 17:00:03

您可以在WM_INITDIALOG中调整对话框的大小

GetSystemMetrics(SM_CXSCREEN)/GetSystemMetrics(SM_CYSCREEN)提供全屏宽度/高度。这将尝试重叠工具栏。你可能不想那样。

SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcDesktop, NULL);将获得桌面的矩形,或者只显示最大化的窗口。

代码语言:javascript
复制
BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    if (msg == WM_INITDIALOG)
    {
        ShowWindow(hwnd, SW_MAXIMIZE);
        return 0;
    }
    ...
    return FALSE;
}

您应该将对话框样式更改为:

STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MAXIMIZEBOX | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME

注意,您必须移动/调整所有子控件的大小。在移动子控件时,不必将其在屏幕坐标中的位置转换为父窗口的客户端坐标。

示例

代码语言:javascript
复制
#include <Windows.h>
#include "resource.h"

#define rcwidth(rc) (rc.right - rc.left)
#define rcheight(rc) (rc.bottom - rc.top)

void move_resize(HWND child, int dx, int dy, int dw, int dh)
{
    if (!child) return;
    if (!IsWindow(child)) return;
    if (!GetParent(child)) return;

    //find child window's coordinates relative to top-left of parent:

    RECT rc;
    GetWindowRect(child, &rc);
    //rc is now child control's rectangle in screen coordinates

    POINT pt = { 0 };
    ScreenToClient(GetParent(child), &pt);
    OffsetRect(&rc, pt.x, pt.y);
    //rc is now child control's rectangle relative to parent window

    //prevent negative size
    if ((rcwidth(rc) + dw) < 0) dw = -rcwidth(rc);
    if ((rcheight(rc) + dh) < 0) dh = -rcheight(rc);

    MoveWindow(child, rc.left + dx, rc.top + dy, rcwidth(rc) + dw, rcheight(rc), TRUE);
}

BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static RECT save_rect;

    switch (msg)
    {
    case WM_INITDIALOG:
        GetClientRect(hwnd, &save_rect);
        ShowWindow(hwnd, SW_MAXIMIZE);
        break;

    case WM_SIZE:
        if (lParam)
        {
            int cx = LOWORD(lParam);
            int cy = HIWORD(lParam);
            int dx = cx - save_rect.right;
            int dy = cy - save_rect.bottom;

            //change x/y position of OK/Cancel button
            move_resize(GetDlgItem(hwnd, IDCANCEL), dx, dy, 0, 0);
            move_resize(GetDlgItem(hwnd, IDOK), dx, dy, 0, 0);

            //change width/height of listbox:
            move_resize(GetDlgItem(hwnd, IDC_LIST1), 0, 0, dx, dy);

            GetClientRect(hwnd, &save_rect);
        }
        break;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK)
            EndDialog(hwnd, wParam);

        if (LOWORD(wParam) == IDCANCEL)
            EndDialog(hwnd, wParam);
        break;

    }

    return FALSE;
}

int WINAPI wWinMain(HINSTANCE hinst, HINSTANCE, LPTSTR, int)
{
    DialogBox(hinst, MAKEINTRESOURCE(IDD_DIALOG1), 0, DlgProc);
    return 0;
}
票数 1
EN

Stack Overflow用户

发布于 2016-02-28 00:10:35

在“过去”的日子里,人们对在资源文件中使用静态数据进行了热烈的讨论,而不是当时“有限”的处理能力。这些天似乎不是这样的问题,但是在这种情况下,处理巨大的DPI可能是一个问题。

我相信Barmak的回答是可行的,但我补充说,这是一种权宜之计,但更便宜,更不精确。

不幸的是,我们不能为不同的预置使用预处理器,所以我们的想法是在入口点之后枚举LPCDLGTEMPLATE的lpTemplate值:

代码语言:javascript
复制
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
Create_Temporary_hwnd_here
...
lpTemplate = DoSystemParametersInfoStuff(hwnd);
...
Destroy__Temporary_hwnd
...
return DialogBoxW(hInstance, MAKEINTRESOURCEW(lpTemplate), nullptr, DlgProc);
}

DoSystemParametersInfostuff返回适当的字符串IDD_1080P、IDD_2160P等。如果资源文件中的每个模板的模板结构和相关数据没有更改,那么就不会出现问题。

Edit1:如果在使用Barmak的可选方法为DlgProc窗口获取句柄之前调用函数MonitorFromWindow,那么检查主/次要显示可能会有点麻烦。好吧,一旦离开了wWinMain例程,就不可能再回到wWinMain例程,所以下一个选择是从wWinMain创建另一个短暂的“廉价”hwnd,以获得适当的模板。

编辑2:由于AOO,不同分辨率的表单模板都是在一个可下载的电子表格这里中设置的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35669717

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档