Page 1 of 1

Change Combobox Icon when editing...

Posted: Tue May 07, 2024 9:49 am
by Michael Vogel
I want to create an editable combobox gadget showing a boolean flag (blue/red in the source below) for each entry. When entering a new entry or editing the text of a given entry, the flag in the edit box should be changed to neutral (green below).

My code does work when the gadget state is -1 (no item selected), so when entering "hello", the icon changes fine without side effects.

My code does not work when an entry has been selected (e.g. TEST 3) before editing. The icon gets green, but the text will be selected automatically. So changing "TEST 3" to " TEST 99" by selecting "3" and entering "99" will result in "9" only.

Code: Select all

Dim iconhandle(2)
iconhandle(0)=CreateImage(0,20,20,32,#Red)
iconhandle(1)=CreateImage(1,20,20,32,#Blue)
iconhandle(2)=CreateImage(2,20,20,32,#Green)


OpenWindow(0,0,0,320,50,"...",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

ComboBoxGadget(0,10,10,300,30,#PB_ComboBox_Editable|#PB_ComboBox_Image)
For i=0 To 9
	AddGadgetItem(0,-1,"TEST "+Str(i),iconhandle(i&1))
Next i
SetActiveGadget(0)

Repeat
	EventID.l = WaitWindowEvent()
	Select EventID

	Case #PB_Event_CloseWindow
		End

	Case #PB_Event_Gadget

		Select EventGadget()
		Case 0
			Select EventType()
			Case #PB_EventType_Change
				n=GetGadgetState(0)
				s.s=GetGadgetText(0)
				If n<0 Or s<>GetGadgetItemText(0,n)
					If n>=0
						SetGadgetState(0,-1)
						SetGadgetText(0,s)
						;SendMessage_(GadgetID(0),#EM_SETSEL,1,1)
					EndIf
					SetGadgetItemImage(0,-1,iconhandle(2))
				EndIf

			EndSelect

		EndSelect

	EndSelect
ForEver


Re: Change Combobox Icon when editing...

Posted: Tue May 07, 2024 3:31 pm
by tatanas
It seems the editbox redraws the image each time there is an event.

Look at this code :

Code: Select all

Declare WinCallback(hWnd, uMsg, WParam, LParam) 

Global Dim iconhandle(2)
iconhandle(0)=CreateImage(0,20,20,32,#Red)
iconhandle(1)=CreateImage(1,20,20,32,#Blue)
iconhandle(2)=CreateImage(2,20,20,32,#Green)

Global himglist = ImageList_Create_(16, 16, #ILC_COLOR, 3, 1)
ImageList_Add_(himglist, iconhandle(0), 0)
ImageList_Add_(himglist, iconhandle(1), 0)
ImageList_Add_(himglist, iconhandle(2), 0)

Macro LOWORD(dwValue) : dwValue & $FFFF : EndMacro
Macro HIWORD(dwValue) : dwValue >> 16 : EndMacro


OpenWindow(0,0,0,320,50,"...",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

ComboBoxGadget(0,10,10,300,30,#PB_ComboBox_Editable|#PB_ComboBox_Image)
For i=0 To 9
	AddGadgetItem(0,-1,"TEST "+Str(i), iconhandle(i&1))
Next i
SetActiveGadget(0)

#CBEM_SETIMAGELIST = #WM_USER + 2
SendMessage_(GadgetID(0), #CBEM_SETIMAGELIST, 0, himglist)

SetWindowCallback(@WinCallback())

Repeat
	EventID.l = WaitWindowEvent()
	Select EventID
			
		Case #PB_Event_CloseWindow
			End

	EndSelect
ForEver


Procedure WinCallback(hWnd, uMsg, WParam, LParam) 

	If uMsg = #WM_COMMAND 
		If LParam = GadgetID(0)
			Select HIWORD(WParam)
				Case #CBN_EDITCHANGE

					hDC = GetDC_(LParam)
					ImageList_Draw_(himglist, 0, hDC, 4, 4, #ILD_IMAGE)
					ReleaseDC_(LParam, hDC)

			EndSelect 
		EndIf
	EndIf

	ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure 
Maybe ownerdraw combobox is the solution...

Re: Change Combobox Icon when editing...

Posted: Tue May 07, 2024 5:12 pm
by breeze4me
You first need to get the handle of the edit control for the combobox gadget.

Code: Select all

Dim iconhandle(2)
iconhandle(0)=CreateImage(0,20,20,32,#Red)
iconhandle(1)=CreateImage(1,20,20,32,#Blue)
iconhandle(2)=CreateImage(2,20,20,32,#Green)


OpenWindow(0,0,0,320,50,"...",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

ComboBoxGadget(0,10,10,300,30,#PB_ComboBox_Editable|#PB_ComboBox_Image)
For i=0 To 9
	AddGadgetItem(0,-1,"TEST "+Str(i),iconhandle(i&1))
Next i
SetActiveGadget(0)

Repeat
	EventID.l = WaitWindowEvent()
	Select EventID

	Case #PB_Event_CloseWindow
		End

	Case #PB_Event_Gadget

		Select EventGadget()
		Case 0
			Select EventType()
			Case #PB_EventType_Change
				n=GetGadgetState(0)
				s.s=GetGadgetText(0)
				If n<0 Or s<>GetGadgetItemText(0,n)
				  SetGadgetState(0,-1)
				  SetGadgetText(0,s)
				  
				  #CBEM_GETEDITCONTROL = 1031
				  hEdit = SendMessage_(GadgetID(0), #CBEM_GETEDITCONTROL, 0, 0)
				  SendMessage_(hEdit, #EM_SETSEL, -1, 0)
				  
				  SetGadgetItemImage(0,-1,iconhandle(2))
				EndIf

			EndSelect

		EndSelect

	EndSelect
ForEver

Re: Change Combobox Icon when editing...

Posted: Tue May 07, 2024 5:31 pm
by Michael Vogel
Thank you all, still was investigating (SendMessage_(GetWindow_(GadgetID(0),#GW_CHILD),#EM_SETSEL,len,len) works when #PB_ComboBox_Image is not used), now I am happy with something like that:

Would only like to know which image is visible actually in the edit box (something like GetGadgetItemImage(combobox,-1))

Code: Select all

Dim iconhandle(2)
iconhandle(0)=CreateImage(0,20,20,32,#Red)
iconhandle(1)=CreateImage(1,20,20,32,#Blue)
iconhandle(2)=CreateImage(2,20,20,32,#Green)

OpenWindow(0,0,0,320,50,"...",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ComboBoxGadget(0,10,10,300,30,#PB_ComboBox_Editable|#PB_ComboBox_Image)
#CBEM_GETEDITCONTROL = 1031
Global hEdit = SendMessage_(GadgetID(0), #CBEM_GETEDITCONTROL, 0, 0)

For i=0 To 9
	AddGadgetItem(0,-1,"TEST "+Str(i),iconhandle(i&1))
Next i
SetActiveGadget(0)


Repeat
	EventID.l = WaitWindowEvent()
	Select EventID

	Case #PB_Event_CloseWindow
		End

	Case #PB_Event_Gadget

		Select EventGadget()
		Case 0
			Select EventType()
			Case #PB_EventType_Change
				n=GetGadgetState(0)
				s.s=GetGadgetText(0)
				If n<0 Or s<>GetGadgetItemText(0,n)
					a=SendMessage_(hEdit,#EM_GETSEL,0,0)
					SetGadgetState(0,-1)
					SetGadgetText(0,s)
					a>>16;  simplified as the cursor shouldn't be a selection 
					SendMessage_(hEdit, #EM_SETSEL,a,a)
					SetGadgetItemImage(0,-1,iconhandle(2))
				EndIf
			EndSelect
		EndSelect

	EndSelect
ForEver

Re: Change Combobox Icon when editing...

Posted: Tue May 07, 2024 7:37 pm
by chi
Michael Vogel wrote: Tue May 07, 2024 5:31 pm Would only like to know which image is visible actually in the edit box (something like GetGadgetItemImage(combobox,-1))
Use SetGadgetItemData/GetGadgetItemData ;)

Re: Change Combobox Icon when editing...

Posted: Tue May 07, 2024 8:45 pm
by RASHAD
Just for your case only :)

Code: Select all

Dim iconhandle(2)
iconhandle(0)=CreateImage(0,20,20,32,#Red)
iconhandle(1)=CreateImage(1,20,20,32,#Blue)
iconhandle(2)=CreateImage(2,20,20,32,#Green)

OpenWindow(0,0,0,320,50,"...",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ComboBoxGadget(0,10,10,300,30,#PB_ComboBox_Editable|#PB_ComboBox_Image)
#CBEM_GETEDITCONTROL = 1031
Global hEdit = SendMessage_(GadgetID(0), #CBEM_GETEDITCONTROL, 0, 0)

For i=0 To 9
  AddGadgetItem(0,-1,"TEST "+Str(i),iconhandle(i&1))
Next i
SetActiveGadget(0)

AddWindowTimer(0,125,100)
Repeat
  EventID.l = WaitWindowEvent()
  Select EventID
      
    Case #PB_Event_CloseWindow
      End
      
    Case #PB_Event_Timer
      item = GetGadgetState(0)
      If item >= 0
        If item % 2 = 0
          Debug "Red"
        Else
          Debug "Blue"
        EndIf
      EndIf      
      
    Case #PB_Event_Gadget
      
      Select EventGadget()
        Case 0
          Select EventType()
            Case #PB_EventType_Change
              Debug "Green"
              n=GetGadgetState(0)
              s.s=GetGadgetText(0)
              If n<0 Or s<>GetGadgetItemText(0,n)
                a=SendMessage_(hEdit,#EM_GETSEL,0,0)
                SetGadgetState(0,-1)
                SetGadgetText(0,s)
                a>>16;  simplified as the cursor shouldn't be a selection 
                SendMessage_(hEdit, #EM_SETSEL,a,a)
                SetGadgetItemImage(0,-1,iconhandle(2))
              EndIf
          EndSelect
      EndSelect
      
  EndSelect
ForEver


Re: Change Combobox Icon when editing...

Posted: Wed May 08, 2024 6:49 pm
by Michael Vogel
Thanks once more, GadgetItemData was also one idea I had, but it doesn't work for the item '-1'. So I could also use global vars to store the state. Rashads strategy does match fine for my program...

Screenshot
Exe file (Windows 64 Bit)