Page 1 of 1

Disabled ComboBoxGadget with white background

Posted: Fri Jun 27, 2008 12:12 pm
by Shardik
In a current project my customers complained about the text in a programmatically disabled ComboBoxGadget which is barely readable because of dark gray text on a grey background (the snapshots were actually taken running Windows NT but are comparable to the "classic" setting in WinXP. With XP themes activated the problem is quite similar.):
Image
My starting point was an older thread in which Sparkie and srod already demonstrated how to change text and background color of an enabled ComboBoxGadget (http://www.purebasic.fr/english/viewtopic.php?t=17426). So my first approach was the utilisation of a callback to change the background from grey to white:
Image

Code: Select all

Procedure.L MainCallback(WindowHandle.L, Msg.L, wParam.L, lParam.L) 
  Shared BackgroundBrush.L

  If Msg = #WM_CTLCOLORSTATIC And lParam = GadgetID(0) 
    ProcedureReturn BackgroundBrush
  EndIf

  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure 


BackgroundBrush.L = CreateSolidBrush_(#White)
ComboBoxEnabled.L = #True

If OpenWindow(0, 0, 0, 270, 190, "Enable/Disable ComboBox", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  SetWindowCallback(@MainCallback())
  ComboBoxGadget(0,10,40,250,150)
  ButtonGadget(1, 70, 10, 120, 20, "Disable ComboBox")

  For i = 0 To 10
    AddGadgetItem(0, -1, "ComboBox item " + Str(i))
  Next i

  SetGadgetState(0, #True)

  Repeat
    WindowEvent = WaitWindowEvent()

    If WindowEvent = #PB_Event_Gadget
      If EventGadget() = 1
        If ComboBoxEnabled
          DisableGadget(0, #True)
          SetGadgetText(1, "Enable ComboBox")
          ComboBoxEnabled = #False
        Else
          DisableGadget(0, #False)
          SetGadgetText(1, "Disable ComboBox")
          ComboBoxEnabled = #True
        EndIf
      EndIf
    EndIf
  Until WindowEvent = #PB_Event_CloseWindow

  DeleteObject_(BackgroundBrush)
EndIf
The drawback of this solution is that the disabled combo box entry still has a grey color displayed on a white background (although the readabilty already is much better now).

I started a second try after finding a different solution in C on the codeguru website which doesn't need a callback and displays black text on a white background but has the drawback that the entries of the combo box have to be editable:
Image

Code: Select all

; http://www.codeguru.com/cpp/controls/combobox/article.php/c1803
; Moshe Stolar 

; // Make the disabled combo's edit control appear as enabled & R/O
;
; // 1. The first child window of a combo is its edit control
; CEdit* pComboEdit=(CEdit*)(GetDlgItem( IDC_COMBO )->GetWindow(GW_CHILD ));
;
; // 2. Enable combo's edit control, not the combo itself, and set R/O
; pComboEdit->EnableWindow( TRUE );
; pComboEdit->SetReadOnly();

ComboBoxEnabled.L = #True

If OpenWindow(0, 0, 0, 270, 190, "Enable/Disable ComboBox", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  ComboBoxGadget(0, 10, 40, 250, 150, #PB_ComboBox_Editable) 
  ButtonGadget(1, 70, 10, 120, 20, "Disable ComboBox")
    
  For i = 0 To 15
    AddGadgetItem(0, -1, "ComboBox item " + Str(i))
  Next i
  
  SetGadgetState(0, 1)

  ComboBoxHandle = GadgetID(0)
  ComboBoxEditControlHandle = GetWindow_(ComboBoxHandle, #GW_CHILD)

  Repeat
    WindowEvent = WaitWindowEvent()

    If WindowEvent = #PB_Event_Gadget
      If EventGadget() = 1
        If ComboBoxEnabled
          DisableGadget(0, #True)
          SetGadgetText(1, "Enable ComboBox")
          EnableWindow_(ComboBoxEditControlHandle, #True)
          ComboBoxEnabled = #False
        Else
          DisableGadget(0, #False)
          SetGadgetText(1, "Disable ComboBox")
          ComboBoxEnabled = #True
        EndIf
      EndIf
    EndIf
  Until WindowEvent = #PB_Event_CloseWindow
EndIf

Re: Disabled ComboBoxGadget with white background

Posted: Sat Nov 20, 2010 6:27 pm
by DoubleDutch
This really helped me out, thanks for the tip! (second try)

It would be good if this was 'built-in' and/or cross platform.

Re: Disabled ComboBoxGadget with white background

Posted: Sat Nov 20, 2010 10:58 pm
by Shardik
DoubleDutch wrote:It would be good if this was 'built-in' and/or cross platform.
This is a cross platform solution of the second try for Linux, Mac OS X and Windows
(tested with Windows XP SP2, Windows 7 x86 and Windows 7 x64):

Image

Image

Image

Image

Code: Select all

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  ImportC ""
    gtk_combo_box_set_button_sensitivity(*GtkComboBox, GtkSensitivityType)
  EndImport

  Enumeration 
    #GTK_SENSITIVITY_AUTO
    #GTK_SENSITIVITY_ON
    #GTK_SENSITIVITY_OFF
  EndEnumeration
CompilerEndIf

ComboBoxEnabled.I = #True

If OpenWindow(0, 0, 0, 270, 70, "Enable/Disable ComboBox", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ComboBoxGadget(0, 10, 40, 250, 20, #PB_ComboBox_Editable)
  ButtonGadget(1, 60, 10, 140, 20, "Disable ComboBox")
   
  For i = 0 To 15
    AddGadgetItem(0, -1, "ComboBox item " + Str(i))
  Next i
 
  SetGadgetState(0, 1)

  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    ComboBoxHandle = GadgetID(0)
    ComboBoxEditControlHandle = GetWindow_(ComboBoxHandle, #GW_CHILD)
  CompilerEndIf

  Repeat
    WindowEvent = WaitWindowEvent()

    If WindowEvent = #PB_Event_Gadget
      If EventGadget() = 1
        If ComboBoxEnabled
          SetGadgetText(1, "Enable ComboBox")
          ComboBoxEnabled = #False

          CompilerSelect #PB_Compiler_OS
            CompilerCase #PB_OS_Linux
              gtk_combo_box_set_button_sensitivity(GadgetID(0), #GTK_SENSITIVITY_OFF)
            CompilerCase #PB_OS_MacOS
              DisableGadget(0, #True)
            CompilerCase #PB_OS_Windows
              DisableGadget(0, #True)
              EnableWindow_(ComboBoxEditControlHandle, #True)
          CompilerEndSelect
        Else
          SetGadgetText(1, "Disable ComboBox")
          ComboBoxEnabled = #True

          CompilerSelect #PB_Compiler_OS
            CompilerCase #PB_OS_Linux
              gtk_combo_box_set_button_sensitivity(GadgetID(0), #GTK_SENSITIVITY_ON)
            CompilerDefault
              DisableGadget(0, #False)
          CompilerEndSelect
        EndIf
      EndIf
    EndIf
  Until WindowEvent = #PB_Event_CloseWindow
EndIf
The Linux version still has a drawback: it is possible to edit the disabled entry...