2017-04-23 2 views
0

La structure DATETIMEPICKERINFO obtenue en envoyant le message DTM_GETDATETIMEPICKERINFO a un champ hwndEdit qui correspond peut-être à ce que je recherche. Cependant, je reçois toujours NULL pour cela, donc je me demande quelle est sa signification réelle. Si non, y a-t-il un moyen d'obtenir le handle du champ d'entrée?Existe-t-il un moyen d'obtenir le handle du champ d'entrée dans un sélecteur de date et d'heure (DTP)?

enter image description here

+1

Il est possible que le contrôle soit créé à la demande, de sorte qu'il peut ne pas exister au moment où vous le recherchez. –

+1

On dirait que vous posez des questions sur votre solution. Qu'essayez-vous finalement d'accomplir? – IInspectable

+0

Un grand merci pour le downvote, il m'encourage à continuer à essayer de comprendre comment poser des questions parfaites. –

Répondre

4

hwndEdit ne semble être valable lorsque le contrôle a le style DTS_APPCANPARSE et vous cliquez le texte date avec la souris (j'ai testé cela avec OutputDebugString et une minuterie). Le contrôle d'édition est créé et détruit dynamiquement. Le handle hwndUD n'est valide que si DTS_UPDOWN est défini et le hwndDropDown n'est valide que lorsque la liste déroulante est visible.

Il n'est pas appelé dans la documentation mais DTM_GETDATETIMEPICKERINFO est marqué Vista + et cela signifie souvent que la fonctionnalité n'est implémentée que dans ComCtl32 v6. Vous devez donc vous assurer que vous avez un manifeste qui demande cette version.

Pour modifier la couleur, vous pouvez essayer DTM_SETMCCOLOR mais seul le MCSC_BACKGROUND est documenté pour fonctionner lorsque les styles visuels sont actifs.

+0

Merci Anders. J'étais conscient de l'exigence Vista + et le manifeste est bon à propos de v6. Je vais essayer plus loin avec vos résultats mais je suppose que changer la couleur de fond quand 'hwndEdit' est valide ne suffira pas. En tout cas, merci beaucoup pour votre aide. –

+0

Pour contrôler complètement les couleurs, vous devez dessiner vous-même le contrôle de la date entière. – Anders

1

Je crains qu'il n'y ait aucun moyen d'obtenir ce que vous vouliez. Je viens de créer une simple application Win32 juste pour tester la possibilité. Si j'utilise le DTM_GETDATETIMEPICKERINFO, hwndDropDown, hwndEdit et hwndUD donnez-moi NULL. Si j'essaie d'ouvrir une fenêtre enfant, bien avant de le faire, je le vérifie avec Spy ++, pas de chance, il n'y a pas de fenêtre enfant associée.

enter image description here

Enfin, j'ai essayé GetFocus() et WindowFromPoint(), les deux me donne la HWND du DateTimePicker lui-même que.

Voici mon code d'essai:

#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); 
} 
+0

J'ai essayé quand le calendrier est affiché et j'ai un handle valide pour 'hwndDropDown' (voir le commentaire de Jonathan Potter ci-dessous la question). Le problème semble être avec 'hwndEdit'. –