Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C DTM_GETIDEALSIZE的正确用法是什么?将返回的大小视为像素会给我提供非常大的高度,有时是可变的_C_Winapi_Comctl32 - Fatal编程技术网

C DTM_GETIDEALSIZE的正确用法是什么?将返回的大小视为像素会给我提供非常大的高度,有时是可变的

C DTM_GETIDEALSIZE的正确用法是什么?将返回的大小视为像素会给我提供非常大的高度,有时是可变的,c,winapi,comctl32,C,Winapi,Comctl32,我正在尝试使用DTM\u GETIDEALSIZE自动调整一些日期时间选择器控件的大小,但我不太明白如何正确使用此消息。如果将返回的宽度视为像素,则看起来不错,但高度似乎不仅相差很远,有时还会随时间而变化 下面的示例程序创建三个日期时间选择器。第一个使用自定义格式显示日期和时间,第二个仅使用DTS\u SHORTDATECENTURYFORMAT显示日期,第三个仅使用DTS\u TIMEFORMAT显示时间。调整窗口大小使用DTM\u GETIDEALSIZE调整所有三个选择器的大小。宽度看起来

我正在尝试使用DTM\u GETIDEALSIZE自动调整一些日期时间选择器控件的大小,但我不太明白如何正确使用此消息。如果将返回的宽度视为像素,则看起来不错,但高度似乎不仅相差很远,有时还会随时间而变化

下面的示例程序创建三个日期时间选择器。第一个使用自定义格式显示日期和时间,第二个仅使用
DTS\u SHORTDATECENTURYFORMAT
显示日期,第三个仅使用
DTS\u TIMEFORMAT
显示时间。调整窗口大小使用
DTM\u GETIDEALSIZE
调整所有三个选择器的大小。宽度看起来不错。但是,前两个的高度始终为100,最后一个(时间选择器)的高度似乎从98左右开始,并随着每次调整大小减少2,直到达到16,此时它保持在16

这在Windows Vista和Windows 7中都进行了测试。下面程序中的错误检查是不一致的(但是为了保持这是一个简单的测试示例,没有检查一些错误)。但是,我要注意的是,MSDN明确地记录了
DTM_GETIDEALSIZE
,因为它只返回
TRUE
,没有指定错误条件

谢谢

// 3 june 2015
#define UNICODE
#define _UNICODE
#define STRICT
#define STRICT_TYPED_ITEMIDS
#define CINTERFACE
#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
#define _WIN32_WINDOWS 0x0600
#define _WIN32_IE 0x0700
#define NTDDI_VERSION 0x06000000
#include <windows.h>
#include <commctrl.h>
#include <stdint.h>
#include <uxtheme.h>
#include <string.h>
#include <wchar.h>
#include <windowsx.h>
#include <vsstyle.h>
#include <vssym32.h>
#include <stdarg.h>
#include <oleacc.h>
#include <stdio.h>

void die(char *s)
{
    // TODO
}

HWND mainwin;
HWND dtp1, dtp2, dtp3;

void idealsize(HWND dtp, char *n, int *x, int *y)
{
    SIZE s;

    s.cx = 0;
    s.cy = 0;
    printf("%s | %I32d ", n, SendMessageW(dtp, DTM_GETIDEALSIZE, 0, (LPARAM) (&s)));
    printf("%I32d %I32d\n", s.cx, s.cy);
    MoveWindow(dtp, *x, *y, s.cx, s.cy, TRUE);
    *y += s.cy;
}

LRESULT CALLBACK wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    int x, y;
    SIZE s;

    switch (uMsg) {
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    case WM_SIZE:
        x = 10;
        y = 10;
        idealsize(dtp1, "1", &x, &y);
        idealsize(dtp2, "2", &x, &y);
        idealsize(dtp3, "3", &x, &y);
        break;
    }
    return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}

static HWND makedtp(DWORD style, WCHAR *format)
{
    HWND hwnd;

    hwnd = CreateWindowExW(WS_EX_CLIENTEDGE,
        DATETIMEPICK_CLASSW, L"",
        style | WS_TABSTOP | WS_CHILD | WS_VISIBLE,
        0, 0, 100, 100,
        mainwin, NULL, GetModuleHandle(NULL), NULL);
    if (format != NULL)
        if (SendMessageW(hwnd, DTM_SETFORMAT, 0, (LPARAM) format) == 0)
            die("error applying format string to date/time picker in finishNewDateTimePicker()");
    return hwnd;
}

#define GLI(what, buf, n) GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, what, buf, n)

HWND makeDateTimePicker(void)
{
    WCHAR *date, *time, *datetime;
    int ndate, ntime;
    int n;
    HWND hwnd;

    // TODO verify that this always returns a century year
    ndate = GLI(LOCALE_SSHORTDATE, NULL, 0);
    if (ndate == 0)
        die("error getting date string length in uiNewDateTimePicker()");
    date = (WCHAR *) malloc(ndate * sizeof (WCHAR));
    if (GLI(LOCALE_SSHORTDATE, date, ndate) == 0)
        die("error geting date string in uiNewDateTimePicker()");

    ntime = GLI(LOCALE_STIMEFORMAT, NULL, 0);
    if (ndate == 0)
        die("error getting time string length in uiNewDateTimePicker()");
    time = (WCHAR *) malloc(ntime * sizeof (WCHAR));
    if (GLI(LOCALE_STIMEFORMAT, time, ntime) == 0)
        die("error geting time string in uiNewDateTimePicker()");

    n = _scwprintf(L"%s %s", date, time);
    datetime = (WCHAR *) malloc((n + 1) * sizeof (WCHAR));
    snwprintf(datetime, n + 1, L"%s %s", date, time);
    hwnd = makedtp(0, datetime);

    free(datetime);
    free(time);
    free(date);

    return hwnd;
}

HWND makeDatePicker(void)
{
    return makedtp(DTS_SHORTDATECENTURYFORMAT, NULL);
}

HWND makeTimePicker(void)
{
    return makedtp(DTS_TIMEFORMAT, NULL);
}

static void makeWindows(void)
{
    mainwin = CreateWindowExW(0,
        L"mainwin", L"Full Window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 500,
        NULL, NULL, GetModuleHandle(NULL), NULL);

    dtp1 = makeDateTimePicker();
    dtp2 = makeDatePicker();
    dtp3 = makeTimePicker();
}

void initCommonControls(BOOL);

int main(int argc, char *argv[])
{
    WNDCLASSW wc;
    MSG msg;
    HBRUSH b;

    initCommonControls(TRUE);

    ZeroMemory(&wc, sizeof (WNDCLASSW));
    wc.lpszClassName = L"mainwin";
    wc.lpfnWndProc = wndProc;
    wc.hInstance = GetModuleHandle(NULL);
    wc.hIcon = LoadIconW(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
    RegisterClassW(&wc);

    makeWindows();

    ShowWindow(mainwin, SW_SHOWDEFAULT);
    UpdateWindow(mainwin);

    while (GetMessageW(&msg, NULL, 0, 0) > 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

static const char manifest[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n<assemblyIdentity\n    version=\"1.0.0.0\"\n    processorArchitecture=\"*\"\n    name=\"CompanyName.ProductName.YourApplication\"\n    type=\"win32\"\n/>\n<description>Your application description here.</description>\n<dependency>\n    <dependentAssembly>\n        <assemblyIdentity\n            type=\"win32\"\n            name=\"Microsoft.Windows.Common-Controls\"\n            version=\"6.0.0.0\"\n            processorArchitecture=\"*\"\n            publicKeyToken=\"6595b64144ccf1df\"\n            language=\"*\"\n        />\n    </dependentAssembly>\n</dependency>\n</assembly>\n";

static ULONG_PTR comctlManifestCookie;
static HMODULE comctl32;

void initCommonControls(BOOL comctl6)
{
    WCHAR temppath[MAX_PATH + 1];
    WCHAR filename[MAX_PATH + 1];
    HANDLE file;
    DWORD nExpected, nGot;
    ACTCTX actctx;
    HANDLE ac;
    INITCOMMONCONTROLSEX icc;
    FARPROC f;
    // this is listed as WINAPI in both Microsoft's and MinGW's headers, but not on MSDN for some reason
    BOOL (*WINAPI ficc)(const LPINITCOMMONCONTROLSEX);

    if (comctl6) {
        if (GetTempPathW(MAX_PATH + 1, temppath) == 0)
            die("getting temporary path for writing manifest file");
        if (GetTempFileNameW(temppath, L"manifest", 0, filename) == 0)
            die("getting temporary filename for writing manifest file");
        file = CreateFileW(filename, GENERIC_WRITE,
            0,          // don't share while writing
            NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (file == NULL)
            die("creating manifest file");
        nExpected = (sizeof manifest / sizeof manifest[0]) - 1;     // - 1 to omit the terminating null character)
        if (WriteFile(file, manifest, nExpected, &nGot, NULL) == 0)
            die("writing manifest file");
        if (nGot != nExpected)
            die("short write to manifest file");
        if (CloseHandle(file) == 0)
            die("closing manifest file (this IS an error here because not doing so will prevent Windows from being able to use the manifest file in an activation context)");

        ZeroMemory(&actctx, sizeof (ACTCTX));
        actctx.cbSize = sizeof (ACTCTX);
        actctx.dwFlags = ACTCTX_FLAG_SET_PROCESS_DEFAULT;
        actctx.lpSource = filename;
        ac = CreateActCtx(&actctx);
        if (ac == INVALID_HANDLE_VALUE)
            die("creating activation context for synthesized manifest file");
        if (ActivateActCtx(ac, &comctlManifestCookie) == FALSE)
            die("activating activation context for synthesized manifest file");
    }

    ZeroMemory(&icc, sizeof (INITCOMMONCONTROLSEX));
    icc.dwSize = sizeof (INITCOMMONCONTROLSEX);
    icc.dwICC = ICC_STANDARD_CLASSES | ICC_PROGRESS_CLASS | ICC_TAB_CLASSES | ICC_LISTVIEW_CLASSES | ICC_UPDOWN_CLASS | ICC_BAR_CLASSES | ICC_DATE_CLASSES;

    comctl32 = LoadLibraryW(L"comctl32.dll");
    if (comctl32 == NULL)
        die("loading comctl32.dll");
    f = GetProcAddress(comctl32, "InitCommonControlsEx");
    if (f == NULL)
        die("loading InitCommonControlsEx()");
    ficc = (BOOL (*WINAPI)(const LPINITCOMMONCONTROLSEX)) f;
    if ((*ficc)(&icc) == FALSE)
        die("initializing Common Controls (comctl32.dll)");
}
//2015年6月3日
#定义UNICODE
#定义UNICODE
#定义严格
#定义严格的\u类型的\u项目ID
#定义接口
#定义WINVER 0x0600
#定义_WIN32_WINNT 0x0600
#定义_WIN32_WINDOWS 0x0600
#定义_WIN32_IE 0x0700
#定义NTDDI_版本0x06000000
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
空模(字符*s)
{
//待办事项
}
HWND mainwin;
HWND dtp1、dtp2、dtp3;
void idealsize(HWND dtp,char*n,int*x,int*y)
{
大小s;
s、 cx=0;
s、 cy=0;
printf(“%s |%I32d”,n,SendMessageW(dtp,DTM_GETIDEALSIZE,0,(LPARAM)(&s));
printf(“%I32d%I32d\n”,s.cx,s.cy);
移动窗口(dtp、*x、*y、s.cx、s.cy、TRUE);
*y+=s.cy;
}
LRESULT回调wndProc(HWND HWND、UINT uMsg、WPARAM WPARAM、LPARAM LPARAM)
{
int x,y;
大小s;
开关(uMsg){
案例WM_结束:
PostQuitMessage(0);
返回0;
案例WM_大小:
x=10;
y=10;
理想尺寸(dtp1,“1”、&x和&y);
理想尺寸(dtp2,“2”、&x和&y);
理想尺寸(dtp3、3英寸、x和y);
打破
}
返回DefWindowProcW(hwnd、uMsg、wParam、lParam);
}
静态HWND makedtp(DWORD样式,WCHAR*格式)
{
HWND-HWND;
hwnd=CreateWindowExW(WS_EX_CLIENTEDGE,
DATETIMEPICK_CLASSW,L“”,
样式| WS|u TABSTOP | WS|u CHILD | WS|u可见,
0, 0, 100, 100,
mainwin,NULL,GetModuleHandle(NULL),NULL);
if(格式!=NULL)
如果(SendMessageW(hwnd,DTM_SETFORMAT,0,(LPRAM)格式)==0)
die(“将格式字符串应用于finishNewDateTimePicker()中的日期/时间选择器时出错”);
返回hwnd;
}
#定义GLI(what,buf,n)getLocaleInfo(LOCALE\u NAME\u USER\u默认值,what,buf,n)
HWND makeDateTimePicker(无效)
{
WCHAR*日期,*时间,*日期时间;
内特内特,内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特内特;
int n;
HWND-HWND;
//TODO验证这始终返回百年
ndate=GLI(LOCALE\u SSHORTDATE,NULL,0);
如果(数据=0)
die(“在uiNewDateTimePicker()中获取日期字符串长度时出错”);
日期=(WCHAR*)malloc(ndate*sizeof(WCHAR));
如果(GLI(地区、日期、日期)==0)
die(“在uiNewDateTimePicker()中获取日期字符串时出错”);
ntime=GLI(LOCALE_STIMEFORMAT,NULL,0);
如果(数据=0)
die(“在uiNewDateTimePicker()中获取时间字符串长度时出错”);
时间=(WCHAR*)malloc(ntime*sizeof(WCHAR));
if(GLI(LOCALE_STIMEFORMAT,time,ntime)=0)
die(“在uiNewDateTimePicker()中获取时间字符串时出错”);
n=_scwprintf(L“%s%s”,日期,时间);
datetime=(WCHAR*)malloc((n+1)*sizeof(WCHAR));
snwprintf(日期时间,n+1,L“%s%s”,日期,时间);
hwnd=makedtp(0,日期时间);
免费(日期时间);
自由(时间);
免费(日期);
返回hwnd;
}
HWND makeDatePicker(无效)
{
返回makedtp(DTS_SHORTDATECENTURYFORMAT,NULL);
}
HWND makeTimePicker(无效)
{
返回makedtp(DTS_TIMEFORMAT,NULL);
}
静态void生成窗口(void)
{
mainwin=CreateWindowExW(0,
L“mainwin”,L“全窗口”,
WS_重叠窗口,
CW_USEDEFAULT,CW_USEDEFAULT,
500, 500,
NULL,NULL,GetModuleHandle(NULL),NULL);
dtp1=makeDateTimePicker();
dtp2=makeDatePicker();
dtp3=makeTimePicker();
}
无效控制(BOOL);
int main(int argc,char*argv[])
{
WNDCLASSW wc;
味精;
hbb;
initCommonControls(TRUE);
零内存(&wc,sizeof(WNDCLASSW));
wc.lpszClassName=L“mainwin”;
wc.lpfnWndProc=wndProc;
wc.hInstance=GetModuleHandle(NULL);
wc.hIcon=LoadIconW(空,IDI_应用程序);
wc.hCursor=LoadCursorW(空,IDC_箭头);
wc.hbrBackground=(HBRUSH)(颜色+1);
注册分类(&wc);
makeWindows();
ShowWindow(mainwin、SW_SHOWDEFAULT);
更新窗口(mainwin);
while(GetMessageW(&msg,NULL,0,0)>0){
翻译信息(&msg);
发送消息(&msg);
}
返回0;
}
静态常量字符清单[]=“\n\n\n此处是您的应用程序描述。\n\n\n\n\n\n\n\n”;
静态ULONG_PTR comctly;
静态HMODULE comctl32;
void initCommonControls(BOOL comctl6)
{
WCHAR temppath[最大路径+1];
WCHAR文件名[最大路径+1];
处理文件;
德沃德·奈斯佩德,恩戈特;
ACTCTX ACTCTX;
手柄ac;
国际刑事法院;
FARPROC f;
//这在Microsoft和MinGW的标题中都被列为WINAPI,但由于某些原因没有出现在MSDN上
BOOL(*WINAPI ficc)(常量LPINITCOMMONCONTROLSEX);
如果(comctl6){
if(GetTempPathW(最大路径+1,临时路径)==0)
死亡(“获得临时pa