Page 1 of 1

ComboBoxGadget - editable and not-editable items

Posted: Sat Aug 22, 2009 5:22 pm
by klaver
How make that some items in ComboBoxGadget are editable, while others are not (Windows OS) ? I tried to change the style with SetWindowLong_() when user changes the item, but no luck. Help anybody?
Thanks in advance.

Posted: Sat Aug 22, 2009 7:21 pm
by Fluid Byte
You can not change the style from editable to non-editable after the control is created. This doesn't even work for a combobox create via API.
Using an extended combox ("ComboBoxEx32") doesn't work as well. I guess you need to delete and recreate the control itself.

Posted: Sat Aug 22, 2009 8:27 pm
by netmaestro
More'n one way to skin a cat. You can't actually edit individual entries on the list, if you edit the box GetGadgetState will return -1. So not allowing edits for individual entries isn't something that you'd be able to do in any case. However, to turn editing on or off for the gadget:

Code: Select all

Global editable = 1

Procedure EditProc(hwnd, msg, wparam, lparam)
  oldproc = GetProp_(hwnd, "oldproc")
  
  Select msg
    Case #WM_NCDESTROY
      RemoveProp_(hwnd, "oldproc")
    
    Case #WM_CHAR, #EM_SETSEL 
      If Not editable 
        ProcedureReturn 0
      EndIf
      
  EndSelect

  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
EndProcedure

OpenWindow(0, 0, 0, 270, 140, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    
ComboBoxGadget(1, 10, 40, 250, 21, #PB_ComboBox_Editable)
For a = 1 To 5
  AddGadgetItem(1, -1,"ComboBox item " + Str(a))
Next

AddGadgetItem(1, -1,"Editing OFF")
AddGadgetItem(1, -1,"Editing ON")
  
SetGadgetState(1,0)
edit = GetWindow_(GadgetID(1),#GW_CHILD)

SetProp_(edit, "oldproc", SetWindowLongPtr_(edit, #GWL_WNDPROC, @EditProc()))

Repeat 
  EventID = WaitWindowEvent()
  Select EventID
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
 
          If GetGadgetState(1) = 5
            editable = 0
            
          ElseIf GetGadgetState(1) = 6
            editable = 1
            
          EndIf
      EndSelect
  EndSelect
Until EventID = #PB_Event_CloseWindow

Posted: Sun Aug 23, 2009 2:05 am
by klaver
Thank you guys. I'm a bit disappointed it's not possible.
netmaestro's code is at the moment best I can have. I've added this to make it a little better:

Code: Select all

Case #EM_SETSEL, #WM_PASTE, #WM_RBUTTONDOWN, #WM_CHAR
Other option is to use:
SendMessage_(edit, #EM_SETREADONLY, #True, 0) instead of editable = 0.

Posted: Sun Aug 23, 2009 2:51 am
by netmaestro
I passed on the EM_SETREADONLY because it makes the edit appear disabled, but if it appeals to you, there's nothing wrong with it. Also, you can add this bit if you'd like to make it clear to the user when edits are OK and when not:

Code: Select all

    Case #WM_SETCURSOR
      If Not editable
        SetCursor_(LoadCursor_(0, #IDC_NO))
        ProcedureReturn #True
      EndIf