有没有办法在日期时间选择器(DTP)中获取输入字段的句柄?

时间:2017-04-23 20:19:48

标签: winapi datetimepicker

通过发送DATETIMEPICKERINFO消息获得的DTM_GETDATETIMEPICKERINFO结构有一个字段hwndEdit,这可能就是我正在寻找的。但是,我总是NULL,所以我想知道它的实际含义是什么。如果没有,有没有办法获得输入字段的句柄?

enter image description here

2 个答案:

答案 0 :(得分:5)

hwndEdit似乎仅在控件具有DTS_APPCANPARSE样式且您用鼠标单击日期文本时才有效(我使用OutputDebugString进行了测试和计时器)。编辑控件是动态创建和销毁的。 hwndUD句柄仅在设置DTS_UPDOWNhwndDropDown仅在下拉列表可见时有效时才有效。

文档中没有调出它,但DTM_GETDATETIMEPICKERINFO标记为Vista +,这通常意味着该功能仅在ComCtl32 v6中实现,因此您还必须确保有一个请求此版本的清单。

要更改颜色,您可以尝试DTM_SETMCCOLOR,但只有MCSC_BACKGROUND才能在视觉样式处于活动状态时生效。

答案 1 :(得分:1)

我担心没有办法得到你想要的东西。我刚刚创建了一个简单的Win32应用程序来测试它的可能性。如果我使用DTM_GETDATETIMEPICKERINFOhwndDropDownhwndEdithwndUD会给我NULL。如果我尝试枚举子窗口,在我这样做之前,我用Spy ++检查它,没有运气,没有与之关联的子窗口。

enter image description here

最后,我尝试了GetFocus()WindowFromPoint(),两者都只给了我HWND本身的DateTimePicker

这是我的测试代码:

#pragma comment(lib, "comctl32.lib")
#include <windows.h>
#include <tchar.h>
#include <commctrl.h>

enum MYID {
    MYID_FIRST = WM_APP,
    MYID_DTP
};

LPCTSTR const g_MyWndClass = _T("DTPTest");
LPCTSTR const g_MyWndTitle = _T("DTPTest");

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void OnWindowCreate(HWND);
void OnTimer(HWND);

int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int nCmdShow)
{
    INITCOMMONCONTROLSEX icex{};
    icex.dwSize = sizeof(icex);
    icex.dwICC = ICC_DATE_CLASSES;
    InitCommonControlsEx(&icex);
    WNDCLASSEX wcex{};
    wcex.cbSize = sizeof(wcex);
    wcex.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.lpfnWndProc = WndProc;
    wcex.lpszClassName = g_MyWndClass;
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    RegisterClassEx(&wcex);
    HWND hwnd = CreateWindowEx(0,
        g_MyWndClass, g_MyWndTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, 600, 400,
        nullptr, nullptr, nullptr, nullptr);
    if (!hwnd) { return 99; }
    SetTimer(hwnd, 0, 100, nullptr);
    ShowWindow(hwnd, nCmdShow);
    MSG msg{};
    while (GetMessage(&msg, nullptr, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return static_cast<int>(msg.wParam);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l)
{
    switch (msg) {
    case WM_CREATE:
        OnWindowCreate(hwnd);
        break;
    case WM_TIMER:
        OnTimer(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, w, l);
    }
    return 0;
}

void OnWindowCreate(HWND hwnd)
{
    HWND hwndDTP = CreateWindowEx(0, DATETIMEPICK_CLASS, nullptr,
        WS_CHILD | WS_VISIBLE | DTS_SHOWNONE,
        20, 50, 220, 20,
        hwnd, reinterpret_cast<HMENU>(MYID_DTP), nullptr, nullptr);
    DATETIMEPICKERINFO info{};
    info.cbSize = sizeof(DATETIMEPICKERINFO);
    SendMessage(hwndDTP, DTM_GETDATETIMEPICKERINFO, 0,
        reinterpret_cast<LPARAM>(&info));
    if (!info.hwndDropDown && !info.hwndEdit && !info.hwndUD)
    {
        MessageBox(hwnd, _T("No luck with DTM_GETDATETIMEPICKERINFO"),
            nullptr, MB_ICONERROR);
    }
}

void OnTimer(HWND hwnd)
{
    POINT pt{};
    GetCursorPos(&pt);
    HWND hwndPoint = WindowFromPoint(pt);
    HWND hwndFocus = GetFocus();
    TCHAR buf[99]{};
    wsprintf(buf, _T("Pointing at %p, focusing %p"),
        hwndPoint, hwndFocus);
    SetWindowText(hwnd, buf);
}