C SetWindowPos()在转换对话框单位时设置了错误的大小?

C SetWindowPos()在转换对话框单位时设置了错误的大小?,c,windows,winapi,C,Windows,Winapi,我正试着将我的头脑从对话单元(DLU)转换成像素,但我没有做到 我附带了一个示例程序来演示这个问题,一个只有一个按钮的对话框。我先解释一下: My.rc文件将对话框定义为“IDD_DIALOG1 dialog 0、0、320、240”,因此DLU中的大小为320x240 我在调用MapDialogRect()时输入了这个大小,并返回rec.right为480,rec.bottom为390 如果我截图窗口并删除边框,我得到的客户区正好是480x390像素。胡萨!然而,转换是有效的 当我使用480x

我正试着将我的头脑从对话单元(DLU)转换成像素,但我没有做到

我附带了一个示例程序来演示这个问题,一个只有一个按钮的对话框。我先解释一下: My.rc文件将对话框定义为“IDD_DIALOG1 dialog 0、0、320、240”,因此DLU中的大小为320x240

我在调用MapDialogRect()时输入了这个大小,并返回rec.right为480,rec.bottom为390

如果我截图窗口并删除边框,我得到的客户区正好是480x390像素。胡萨!然而,转换是有效的

当我使用480x390的固定值或返回的rec.right和rec.bottom调用SetWindowPos()时,窗口会变小,客户端区域为474x362

我错过什么了吗?客户机区域不应该保持480×390像素吗

.c文件:

#include <windows.h>
#include "resource.h" 

BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch(Message)
    {
        case WM_INITDIALOG:
        break;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case ID_RSZ:
                {
                    RECT rec;
                    rec.left = 0;
                    rec.top = 0;
                    rec.right = 320;
                    rec.bottom = 240;
                    MapDialogRect(hwnd, &rec);
                    SetWindowPos(hwnd, NULL, 0, 0, rec.right, rec.bottom, SWP_NOMOVE);
                    //SetWindowPos(hwnd, NULL, 0, 0, 480, 390, SWP_NOMOVE);
                }
                break;
            }
        break;
        case WM_CLOSE:
            EndDialog(hwnd, 0);
        break;
        default:
            return FALSE;
    }
    return TRUE;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    return DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
}
#包括
#包括“resource.h”
BOOL回调DlgProc(HWND-HWND,UINT消息,WPARAM-WPARAM,LPARAM-LPARAM)
{
开关(信息)
{
案例WM_初始化对话框:
打破
case WM_命令:
开关(LOWORD(wParam))
{
案件编号(RSZ):
{
RECT rec;
rec.left=0;
rec.top=0;
右记录=320;
记录底部=240;
MapDialogRect(hwnd和rec);
设置窗口位置(hwnd、NULL、0、0、右记录、下记录、SWP_NOMOVE);
//设置窗口位置(hwnd、NULL、0、0、480、390、SWP_NOMOVE);
}
打破
}
打破
案例WM_结束:
EndDialog(hwnd,0);
打破
违约:
返回FALSE;
}
返回TRUE;
}
int WINAPI WinMain(HINSTANCE HINSTANCE、HINSTANCE HPPreInstance、,
LPSTR lpCmdLine,int nCmdShow)
{
返回对话框(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DlgProc);
}
.rc文件:

// Generated by ResEdit 1.6.6
// Copyright (C) 2006-2015
// http://www.resedit.net

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"




//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG1 DIALOG 0, 0, 320, 240
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "Ms Shell Dlg"
{
    PUSHBUTTON      "Resize!", ID_RSZ, 144, 102, 35, 21, 0, WS_EX_LEFT
}
//由ResEdit 1.6.6生成
//版权所有(C)2006-2015
// http://www.resedit.net
#包括
#包括
#包括
#包括“resource.h”
//
//对话资源
//
语言语言中性,次语言中性
IDD_对话框1对话框0、0、320、240
样式DS|U 3DLOOK | DS|U中心| DS|U模块框架| DS|U外壳字体| WS|U标题| WS|U可见| WS|U弹出| WS|U系统菜单
标题“对话”
字体8,“Ms Shell Dlg”
{
按钮“调整大小!”,ID_RSZ,144、102、35、21、0,左前
}

[编辑]尝试使用AdjustWindowRectEx():

[Edit2]5月23日,更正了我的复制粘贴错误:

    case ID_RSZ:
        {
            RECT rec;
            rec.left = 0;
            rec.top = 0;
            rec.right = 320;
            rec.bottom = 240;
            MapDialogRect(hwnd, &rec);
            AdjustWindowRectEx(&rec, DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU, FALSE, 0);
            if(rec.left < 0) rec.right += (rec.left*-1);
            if(rec.top < 0) rec.bottom += (rec.top*-1);
            SetWindowPos(hwnd, NULL, 0, 0, rec.right, rec.bottom, SWP_NOMOVE);
        }
        break;
case ID\u RSZ:
{
RECT rec;
rec.left=0;
rec.top=0;
右记录=320;
记录底部=240;
MapDialogRect(hwnd和rec);
调整WindowRectex(&rec,DS|U 3DLOOK | DS|U CENTER | DS|U MODALFRAME | DS|U SHELLFONT | WS|U字幕| WS|U可见| WS|U弹出| WS| U系统菜单,FALSE,0);
如果(rec.left<0)rec.right+=(rec.left*-1);
如果(rec.top<0)rec.bottom+=(rec.top*-1);
设置窗口位置(hwnd、NULL、0、0、右记录、下记录、SWP_NOMOVE);
}
打破
[编辑3]-5月29日

我最初的问题是关于SetWindowPos()及其行为的,我得到了一个有效的答案

然而,在设计调整大小的窗口、复制每个大小和位置、用代码编写并以编程方式进行转换的艰难过程中,我意识到自己是个哑巴


我所要做的就是在我的资源编辑器中为每个所需大小创建另一个对话框,当用户更改大小时,我只需使用EndDialog()销毁窗口,并使用DialogBox()再次调用该进程为所选大小提供相应对话框窗口的名称。

SetWindowPos
设置窗口外缘的大小,包括窗口的非客户区部分,如标题栏和边框。如果您的应用程序不可用,则Windows可能会对您的窗口应用缩放。DWM阴影也可能在感知大小中起作用,但不应包含在计算中


可用于根据客户端矩形的所需大小计算窗口矩形的所需大小。

SetWindowPos
设置窗口外缘的大小,包括窗口的非客户端区域部分,如标题栏和边框。如果您的应用程序不可用,则Windows可能会对您的窗口应用缩放。DWM阴影也可能在感知大小中起作用,但不应包含在计算中


可用于根据客户端矩形的所需大小计算窗口矩形的所需大小。

SetWindowPos
设置整个窗口的大小,包括由框架和窗口标题组成的非客户端区域。但这不意味着如果我截屏整个窗口(alt+PrtScn)在设置WindowPos之后,我会得到一张480x390的图像吗?因为我没有。我得到490x400。AdjustWindowRect使用窗口样式标志,而不是对话框样式标志。
SetWindowPos
设置整个窗口的大小,包括由框架和窗口标题组成的非客户端区域。但这难道不意味着如果我在SetWindowPos之后截屏整个窗口(alt+PrtScn),我会得到480x390图像吗?因为我没有。我得到490x400。AdjustWindowRect使用窗口样式标志,而不是对话框样式标志。谢谢Anders,但我仍然无法使它工作。您能看一下我对问题所做的编辑,并告诉我是否正确使用了AdjustWindowRectEx吗?使用GetWindowLongPtr获取样式和exstyle。@C4L计算:客户端区域的位置始终为(0,0)。我不确定我是否理解您提出的问题。@C4lculated:子控件的位置总是相对于其父控件的客户端区域。如果更改窗口的大小,子控件将保持不变(相对于左上角)。如果你还活着