2010-02-02 9 views
0

J'implémente un combobox personnalisé pour se comporter comme une boîte de recherche. Il est construit à partir d'un contrôle d'édition, un bouton et une zone de liste.ComboBox personnalisé pour SearchBox

J'essaie d'ouvrir la liste en cliquant sur le bouton de la souris, il semble être simple mais devenir compliqué. J'ai d'abord essayé de gérer la souris en cliquant sur le "BN_CLICKED", mais ensuite j'ai découvert qu'il est trop tard et j'aimerais ouvrir la listbox déjà sur "WM_LBUTTONDOWN" (et sur "WM_LBUTTONDBLCLK"), le problème est, quand je J'essaie d'ouvrir la zone de liste sur ce message la boîte à liste reçoit "WM_KILLFOCUS" et étant fermé juste après avoir été ouvert pendant un moment, et plus tard le bouton reçoit le message "WM_SETFOCUS", je pensais ouvrir la zone de liste dans le " WM_SETFOCUS "qui reçoit le bouton, mais je ne peux pas compter sur ce message car il ne sera pas envoyé à chaque clic de bouton (par exemple lorsque je clique sur le bouton).

Répondre

1

Ne serait-il pas plus simple de commencer avec une zone de liste déroulante et d'en déduire une classe de fenêtre?

WNDPROC comboboxwndproc; 

LRESULT CALLBACK MyComboBoxWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 
    switch (uMsg) { 
    /* do your thing */ 
    } 

    return CallWindowProc(comboboxwndproc, hwnd, uMsg, wParam, lParam); 
} 

void register_custom_combobox() { 
    WINDOWCLASSEX mycbwc; 
    char mycbwcname[] = "MYCOMBOBOX"; 
    mycbwc.cbSize = sizeof(WNDCLASSEX); 
    GetClassInfoEx(NULL, "COMBOBOX", &mycbwc); 
    comboboxwndproc = cbwc.lpfnWndProc; 
    mycbwc.lpfnWndProc = MyComboBoxWndProc; 
    mycbwc.hInst = my_instance; 
    mycbwc.lpszClassName = mycbwcname; 
    RegisterClassEx(&mycbwc); 
} 

Si vous voulez, vous pouvez, au lieu d'utiliser la variable globale, l'espace de réserve dans la classe zone supplémentaire. Ensuite, dans la fenêtre personnalisée proc, vérifiez si elle a déjà été définie et, si ce n'est pas le cas, demandez à nouveau les informations de classe de la liste déroulante et placez le pointeur sur la procédure de la liste déroulante dans la zone Class Extra.

1

Sinon, vous pouvez remplacer la fenêtre proc sur la création au lieu de l'enregistrement d'une nouvelle classe de fenêtre:

WNDPROC g_ComboBoxProc; 

LRESULT CALLBACK SearchBoxProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 
    // Special handling here. 

    return CallWindowProc(g_ComboBoxProc, hwnd, uMsg, wParam, lParam); 
} 

HWND CreateSearchBox(LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, 
        int w, int h, HWND hWndParent, HMENU hMenu, 
        HINSTANCE hInstance, LPVOID lpParam) { 
    HWND hwnd = CreateWindow(TEXT("COMBOBOX"), lpWindowName, dwStyle, 
          x, y, w, h, hWndParent, hMenu, hInstance); 
    if (hwnd) { 
    g_ComboBoxProc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, 
               (WNDPROC) SearchBoxProc); 
    } 

    return hwnd; 
} 

Bien que SetWindowSubclass devrait probablement être utilisé à la place.

Questions connexes