Search code examples
winapicolorscomboboxcommon-controls

WINAPI - Set background & text color of a combo box dropdown


So I was trying to set a ComboBox's background & text color using Common-Controls & WINAPI. I did manage to set the background & text color of the combo box itself, but the colors of its dropdown list remain the same.

Here is pretty much what I did: When creating the combo box, I used the CBS_DROPDOWNLIST style (along with WS_VISIBLE & WS_CHILD). Then in the window handler function, I handled the CTLCOLOR_LISTBOX messge in the following way:

SetBkMode(dc, OPAQUE);
SetTextColor(dc, RGB(255, 255, 255));
SetBkColor(dc, 0x383838);
comboBrush = CreateSolidBrush(0x383838); //global var
return (LRESULT)comboBrush;

As I said, this only colors the combobox itself, and not its drop-down list. How can I can color the drop down list as well?


Solution

  • For the background color and text color of the combo box, you can handle the WM_CTLCOLORLISTBOX and WM_CTLCOLOREDIT messages respectively.

    WM_CTLCOLORLISTBOX : Sent to the parent window of a list box before the system draws the list box. By responding to this message, the parent window can set the text and background colors of the list box by using the specified display device context handle.

    Some code:

       // Create Combox control
       int xpos = 100;            // Horizontal position of the window.
       int ypos = 100;            // Vertical position of the window.
       int nwidth = 200;          // Width of the window
       int nheight = 200;         // Height of the window
       HWND hwndParent = hWnd; // Handle to the parent window
    
       hWndComboBox = CreateWindow(WC_COMBOBOX, TEXT(""),
           CBS_DROPDOWNLIST | WS_CHILD |  WS_VISIBLE, 
           xpos, ypos, nwidth, nheight, hwndParent, NULL, hInstance,
           NULL);
    
       // load the combobox with item list.  
       // Send a CB_ADDSTRING message to load each item
    
       TCHAR Planets[9][10] =
       {
           TEXT("Mercury"), TEXT("Venus"), TEXT("Terra"), TEXT("Mars"),
           TEXT("Jupiter"), TEXT("Saturn"), TEXT("Uranus"), TEXT("Neptune"),
           TEXT("Pluto??")
       };
    
       TCHAR A[16];
       int  k = 0;
    
       memset(&A, 0, sizeof(A));
       for (k = 0; k <= 8; k += 1)
       {
           wcscpy_s(A, sizeof(A) / sizeof(TCHAR), (TCHAR*)Planets[k]);
    
           // Add string to combobox.
           SendMessage(hWndComboBox, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)A);
       }
    
       // Send the CB_SETCURSEL message to display an initial item 
       //  in the selection field  
       SendMessage(hWndComboBox, CB_SETCURSEL, (WPARAM)2, (LPARAM)0);
    
       ...
    

    Updated:

    //Windows Process
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {    
        case WM_CTLCOLORLISTBOX:
        {       
            COMBOBOXINFO info;
            info.cbSize = sizeof(info);
            SendMessage(hWndComboBox, CB_GETCOMBOBOXINFO, 0, (LPARAM)&info);
            COMBOBOXINFO info1;
            info1.cbSize = sizeof(info1);
            SendMessage(hWndComboBox1, CB_GETCOMBOBOXINFO, 0, (LPARAM)&info1);
    
            if ((HWND)lParam == info.hwndList)
            {
                HDC dc = (HDC)wParam;
                SetBkMode(dc, OPAQUE);
                SetTextColor(dc, RGB(255, 255, 0));
                SetBkColor(dc, 0x383838); //0x383838
                HBRUSH comboBrush = CreateSolidBrush(0x383838); //global var
                return (LRESULT)comboBrush;
            } 
            if ((HWND)lParam == info1.hwndList)
            {
                HDC dc = (HDC)wParam;
                SetBkMode(dc, OPAQUE);
                SetTextColor(dc, RGB(255, 0, 0));
                SetBkColor(dc, RGB(0, 0, 255)); 
                HBRUSH comboBrush = CreateSolidBrush(RGB(0, 0, 255)); 
                return (LRESULT)comboBrush;
            }
        }
        case WM_CTLCOLOREDIT:
        {
            HWND hWnd = (HWND)lParam;
            HDC dc = (HDC)wParam;
            if (hWnd == hWndComboBox)
            {
                SetBkMode(dc, OPAQUE);
                SetTextColor(dc, RGB(255, 0, 255));
                SetBkColor(dc, 0x383838); //0x383838
                HBRUSH comboBrush = CreateSolidBrush(0x383838); //global var
                return (LRESULT)comboBrush;
            }
            else if (hWnd == hWndComboBox1)
            {
                SetBkMode(dc, OPAQUE);
                SetTextColor(dc, RGB(255, 255, 0));
                SetBkColor(dc, RGB(0, 255, 0)); 
                HBRUSH comboBrush = CreateSolidBrush(RGB(0, 255, 0)); 
                return (LRESULT)comboBrush;
            }
        }
        ...
    

    Change the background color by comparing the edit handle and listbox handle returned by the window.

    Debug:

    enter image description here