Page 1 of 2

VB 'Simple' Combobox?

Posted: Sat Jul 17, 2004 5:18 pm
by johnfermor
Hi everyone

Is there any way to create a 'simple' combo gadget as seen in VB?

Being a VB'er I am used to creating a combo control and setting its style property to '1 .. Simple'. What results is a fully functioning combo with a scaleable listbox-type appearance (showing a list of combo entries in this space).

I have cheecked the Flags property of the combo but this isn't inclded. Also, I have done a search but can't find anything. Will this need subclassing?

Cheers.

John

Posted: Sat Jul 17, 2004 5:22 pm
by Pupil
Have you tried 'ComboBoxGadget()'? Just remember that the height you set is the max height that the scrollable area will take up and not the area as seen on screen when it's in a closed state..

Posted: Sat Jul 17, 2004 5:29 pm
by johnfermor
About 2 mins for areply .. thanks Pupil!

I have just checked the ComboBoxGadget but the list is of the drop-down variety. I need one which displays a list of the entries with the combo-part at the top of the list.

Posted: Sat Jul 17, 2004 8:51 pm
by Dr_Pixel
I'm not picturing what you mean - maybe a ListView gadget?

If you look in the PB manual, it shows previews of what the different gadgets look like

Posted: Sun Jul 18, 2004 9:58 am
by johnfermor
Here is a screenshot of what I mean. It is a VB form with a combobox control and you can select its style (from the properties panel) to be either;

0. Dropdown Combo
1. Simple Combo
2. Dropdown List

By default when I create a combobox gadget in PB, it adopts the 'Dropdown Combo' which drops down only when I select it.

What I want is a combo which displays a static list as can be seen from the graphic but still acts as a combo. It must be a combobox gadget as I want to incorporate 'autocomplete' functionality and I don't think this can be done any other way.

Image (alt+p)

Posted: Sun Jul 18, 2004 10:04 am
by thefool
The autocomple can offcourse be done manually.

Posted: Sun Jul 18, 2004 10:18 am
by johnfermor
Yes I have seen some samples on the forum - thanks to you guys out there.

But can this be done? or do I have to somehow link a stringgadget with a listgadget or something?

This is a one-click operation in VB and is much needed in PB! Maybe one for the wishlist!

Posted: Sun Jul 18, 2004 10:27 am
by thefool
hmm got a little example here. Anyway, its pretty advanced and can sure be done a lot simpler. Taken from the codearchive.

Code: Select all

; English forum: http://jconserv.net/purebasic/viewtopic.php?t=8048&highlight=
; Author: Justin
; Date: 25. October 2003


;Autocomplete object
;Justin 10/03

; Just to play a little with the new functions. An object that makes an autocomplete
; in an editbox / listbox. It's a working example, note that you have to use setsel()
; if the selected listbox index changes outside the object, i did this to improve the
; speed, rather than checking the selected index for every edit change inside the object.
; Only for windows.

Interface IPBAutoComplete
  FindStr(str$)
  SetEdit(id)
  SetListBox(id)
  SetSel(isel)
EndInterface

Structure PBAutoCompleteFunctions
  FindStr.l
  SetEdit.l
  SetListBox.l
  SetSel.l
EndStructure

Structure OPBAutoComplete
  *VTable.PBAutoCompleteFunctions
  hwndedit.l
  hwndlistbox.l
  idedit.l
  idlistbox.l
  iselected.l
EndStructure

;finds and select the passed string
Procedure FindStr(*Object.OPBAutoComplete,str$)
  hwndlistbox=*Object\hwndlistbox
  istr=SendMessage_(hwndlistbox,#LB_FINDSTRING,-1,str$)
  If istr<>-1
    ;skip if item is selected
    If *Object\iselected=istr : ProcedureReturn : EndIf
    textlen=Len(str$)
    
    newtextlen=SendMessage_(hwndlistbox,#LB_GETTEXTLEN,istr,0)
    seltextlen=newtextlen-textlen
    
    ;select
    SendMessage_(hwndlistbox,#LB_SETCURSEL,istr,0)
    ;set edit text
    SetGadgetText(*Object\idedit,GetGadgetItemText(*Object\idlistbox,istr,-1))
    ;set selected text
    sendmessage_(*Object\hwndedit,#EM_SETSEL,textlen,newtextlen)
    
    ;update index
    *Object\iselected=istr
  EndIf
EndProcedure

;sets the editbox for this object
;id : editbox id
Procedure SetEdit(*Object.OPBAutoComplete,id)
  *Object\idedit=id
  *Object\hwndedit=GadgetID(id)
EndProcedure

;sets the listbox for this object
;id : listbox id
Procedure SetListBox(*Object.OPBAutoComplete,id)
  *Object\idlistbox=id
  *Object\hwndlistbox=GadgetID(id)
EndProcedure

;sets the selected listbox index
;iselected : index of selected item
;you are responsable to update this index every time it changes
;-1 = no selection
Procedure SetSel(*Object.OPBAutoComplete,iselected)
  *Object\iselected=iselected
EndProcedure

PBAutoCompleteFunctions.PBAutoCompleteFunctions\FindStr=@FindStr()
PBAutoCompleteFunctions.PBAutoCompleteFunctions\SetEdit=@SetEdit()
PBAutoCompleteFunctions.PBAutoCompleteFunctions\SetListBox=@SetListBox()
PBAutoCompleteFunctions.PBAutoCompleteFunctions\SetSel=@SetSel()

OPBAutoComplete.OPBAutoComplete\VTable=PBAutoCompleteFunctions

;-----------------------------------------------------------------
;CODE

;GADGET IDs
#String0=0
#ListView1=1

;WINDOW ID
#Window1=0

;WINDOW
OpenWindow(#Window1,150,70,550,350,#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_TitleBar,"Auto Complete")
CreateGadgetList(WindowID(#Window1))

StringGadget(#String0,10,8,310,24,"")
ListViewGadget(#ListView1,11,49,308,262)

AddGadgetItem(#ListView1,-1,"Red")
AddGadgetItem(#ListView1,-1,"Green")
AddGadgetItem(#ListView1,-1,"Blue")
AddGadgetItem(#ListView1,-1,"Yellow")
AddGadgetItem(#ListView1,-1,"Black")
AddGadgetItem(#ListView1,-1,"White")
AddGadgetItem(#ListView1,-1,"Pink")
AddGadgetItem(#ListView1,-1,"Purple")
AddGadgetItem(#ListView1,-1,"Gray")
AddGadgetItem(#ListView1,-1,"Orange")

ActivateGadget(#String0)

;create object
OAutoCP.IPBAutoComplete=@OPBAutoComplete

;init object
OAutoCP\SetEdit(#String0)
OAutoCP\SetListBox(#ListView1)
OAutoCP\SetSel(-1) ;no items selected

;EVENT LOOP
Repeat
  EvID=WaitWindowEvent()
  Select EvID
  Case #PB_Event_Gadget
    Select EventGadgetID()
    Case #String0
      Select EventType()
      Case #PB_EventType_Change
        str$=GetGadgetText(#String0)
        OAutoCP\FindStr(str$)
      EndSelect
      
    Case #ListView1 ;important to update selected index in object
      isel=GetGadgetState(#ListView1)
      ;update selected index
      OAutoCP\SetSel(isel)
      ;set selected in edit
      str$=GetGadgetItemText(#ListView1,isel,-1)
      SetGadgetText(#String0,str$)
    EndSelect
  EndSelect
Until EvID=#PB_EventCloseWindow

; ExecutableFormat=Windows
; EnableXP
; EOF

Posted: Sun Jul 18, 2004 10:31 am
by johnfermor
thefool, you are indeed a Wizard. That's pretty much exactly what I need!

I looked in the code archive and although I found several combogadget samples (coloured, owner drawn, etc) I couldn't find what I needed.

Many thanks for this and I'll look even harder next time!

Posted: Sun Jul 18, 2004 10:35 am
by thefool
np :)

Posted: Sun Jul 18, 2004 1:03 pm
by Pupil
Sorry i've not found an easy way to do what you want. The only way is to go full API which is a pain in the rectum. I tried just to change the style of the created PB gadget but it seems you must set this style when creating the thing.

Anyway this is what i've got:

Code: Select all

!extrn PB_Gadget_DefaultFont

#GAD_COMBOBOX	= 1
hInstance = GetModuleHandle_(0)
hFont.l
!MOV eax, dword [PB_Gadget_DefaultFont]
!MOV [v_hFont], eax

If OpenWindow(0,0,0,270,140,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"ComboBoxGadget") And CreateGadgetList(WindowID(0)) 
	hCombo.l = CreateWindowEx_(0, "COMBOBOX", "", #WS_CHILD|#WS_VISIBLE|#WS_CLIPCHILDREN|#CBS_SIMPLE|#CBS_HASSTRINGS, 10, 10, 250, 130, WindowID(0), #GAD_COMBOBOX, hInstance, 0)
	SendMessage_(hCombo, #WM_SETFONT, hFont, #TRUE)
	For i = 0 To 5
		SendMessage_(hCombo, #CB_ADDSTRING, 0, "item"+Str(i))
	Next
  Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow 
EndIf 
Sorry for the messy code ;)

Posted: Sun Jul 18, 2004 1:08 pm
by thefool
but the problem is that your code misses the autocomplete.

Posted: Sun Jul 18, 2004 1:20 pm
by Pupil
thefool wrote:but the problem is that your code misses the autocomplete.
I was merly trying to answer the original question NOT provide a full solution. So i don't see this as a problem, the logic behind the autocomplete-code provided earlier could be adapted to work with what i posted.. However it's probably easier to work with two separete gadgets in this case as PB doesn't provide the functionality to use the ComboBox as requested ealier.

..

Posted: Sun Jul 18, 2004 5:27 pm
by NoahPhense
@Pupil
Nice use of ASM...

@thefool
Why don't you give him the URL to the Codearchiv, he might even think
you are an more of an expert, less a wizard.. lol

- np

Posted: Sun Jul 18, 2004 5:40 pm
by thefool
@NoaPhence: dont get personal!
notice that i said this:
Taken from the codearchive.
:)

lol yourself.. 8)

@johnfermor: find the great codearchive on http://purearea.net