Code: Alles auswählen
;by HJBremer - Februar 2015 - 2.11, Purebasic 5.31 Windows Vista X86
DeclareModule ComboBox
Declare.i ComboBox(pbnr, x, y, w, h, flags = 0)
Declare.i ComboBox_AddItem(pbnr, text$)
Declare.i Combobox_LoadItem(pbnr, typ$)
Declare.i Combobox_SaveItem(pbnr, typ$)
EndDeclareModule
Module ComboBox
EnableExplicit
Structure Comboboxinfo ;für x86, für x64 ???
cbSize.i
rcItem.RECT
rcButton.RECT
stateButton.i
hwndCombo.i
hwndEdit.i
hwndList.i
EndStructure
Structure Combobox ;interne Struktur
pbnr.i
pbid.i
group.s
oldedit.i
oldlist.i
oldcombo.i
EndStructure
Global comboboxfile$ = "Combobox.txt" ;Filename für Load/Save
Global NewList combolist() ;Liste verwaltet Gadgetdaten
Procedure.i Combobox_SetGroup(pbnr, grp$)
Protected *cb.Combobox
ForEach combolist()
*cb = combolist()
If pbnr = *cb\pbnr Or pbnr = #PB_All
*cb\group = grp$
EndIf
Next
EndProcedure
Procedure.i ComboBox_AddItem(pbnr, text$)
Protected pos, id = GadgetID(pbnr)
If text$ ;wenn Text, suchen in Liste, wenn nicht gefunden dann Add
pos = SendMessage_(id, #CB_FINDSTRINGEXACT, -1, @text$)
If pos = #CB_ERR: SendMessage_(id, #CB_ADDSTRING, 0, @text$): EndIf
EndIf
EndProcedure
Procedure.i Combobox_SaveItem(pbnr, grp$)
Protected anz, nr
Protected ok = OpenPreferences(comboboxfile$)
If ok = 0: ok = CreatePreferences(comboboxfile$): EndIf
If ok
If grp$
RemovePreferenceGroup(grp$)
PreferenceGroup(grp$)
WritePreferenceString(Str(nr), GetGadgetText(pbnr)) ;Nr.0 aus Editfeld
anz = CountGadgetItems(pbnr) ;Anzahl in Liste
For nr = 1 To anz ;Liste speichern 1-anz
WritePreferenceString(Str(nr), GetGadgetItemText(pbnr, nr-1))
Next
EndIf
ClosePreferences()
EndIf
EndProcedure
Procedure.i Combobox_LoadItem(pbnr, grp$)
Protected nr, lg, text$
Protected ok = OpenPreferences(comboboxfile$)
If ok = 0: ok = CreatePreferences(comboboxfile$): EndIf
If ok
PreferenceGroup(grp$)
text$ = ReadPreferenceString(Str(nr), "") ;Nr.0 ins Editfeld
SetGadgetText(pbnr, text$)
Repeat
nr + 1
text$ = ReadPreferenceString(Str(nr), "") ;ab Nr.1 ins Listfeld
ComboBox_AddItem(pbnr, text$)
Until text$ = ""
ClosePreferences()
EndIf
;wenn Editfeld leer, dann 1.Eintrag aus Liste
If GetGadgetText(pbnr) = "": SetGadgetState(pbnr, 0): EndIf
;wenn immer noch leer, Groupnamen als Banner
If GetGadgetText(pbnr) = ""
lg = StringByteLength(grp$, #PB_Unicode)
text$ = Space(lg)
PokeS(@text$, grp$, Len(text$), #PB_Unicode)
SendMessage_(GadgetID(pbnr), #CB_SETCUEBANNER, 0, @text$)
EndIf
;Groupnamen dem Memblock mitteilen für SaveItem
Combobox_SetGroup(pbnr, grp$)
EndProcedure
Procedure.i ComboBox_CBEdit(hwnd, msg, wParam, lParam)
Protected *cb.Combobox = GetWindowLongPtr_(hwnd, #GWL_USERDATA)
Protected oldwndproc = *cb\oldedit
Select msg
Case #WM_KILLFOCUS
;wenn hier, könnte VK_Return entfallen, ich finde es gut.
ComboBox_AddItem(*cb\pbnr, GetGadgetText(*cb\pbnr))
Case #WM_KEYDOWN
Select wparam
Case #VK_RETURN
ComboBox_AddItem(*cb\pbnr, GetGadgetText(*cb\pbnr))
SendMessage_(hwnd, #EM_SETSEL, 0, -1)
Case #WM_CHAR:; Debug "edit #WM_CHAR" + wparam
;hier könnte eine Eingabekontrolle sein
;z.B. if wparam = 46: wparam = 44: endif
EndSelect
EndSelect
ProcedureReturn CallWindowProc_(oldwndproc, hwnd, msg, wParam, lParam)
EndProcedure
Procedure.i ComboBox_CBList(hwnd, msg, wParam, lParam)
Protected *cb.Combobox = GetWindowLongPtr_(hwnd, #GWL_USERDATA)
Protected item, oldwndproc = *cb\oldlist
Select msg
Case #WM_RBUTTONDOWN
;entfernt ein Item aus der ComboboxGadget-Listbox
item = SendMessage_(hwnd, #LB_GETCURSEL, 0, 0)
SendMessage_(hwnd, #LB_DELETESTRING, item, 0)
SendMessage_(hwnd, #LB_SETCURSEL, item-1, 0)
EndSelect
ProcedureReturn CallWindowProc_(oldwndproc, hwnd, msg, wParam, lParam)
EndProcedure
Procedure.i ComboBox_CBCombo(hwnd, msg, wParam, lParam)
Protected *cb.Combobox = GetWindowLongPtr_(hwnd, #GWL_USERDATA)
Protected oldwndproc = *cb\oldcombo
Select msg
Case #WM_DESTROY
ForEach combolist()
If *cb = combolist()
Combobox_SaveItem(*cb\pbnr, *cb\group)
DeleteElement(combolist()): FreeMemory(*cb)
EndIf
Next
Case #WM_CTLCOLOREDIT, #WM_CTLCOLORLISTBOX
SetBkMode_(wParam, #TRANSPARENT) ;wParam ist das DC
SetTextColor_(wparam, #Blue)
ProcedureReturn GetStockObject_(#WHITE_BRUSH)
EndSelect
ProcedureReturn CallWindowProc_(oldwndproc, hwnd, msg, wParam, lParam)
EndProcedure
Procedure.i ComboBox(pbnr, x, y, w, h, flags = 0)
Protected nr, id, cbi.comboboxinfo
Protected *cb.Combobox = AllocateMemory(SizeOf(Combobox))
flags | #CBS_SORT
If pbnr = #PB_Any
nr = ComboBoxGadget(#PB_Any, x, y, w, h, flags): id = GadgetID(nr)
Else
nr = pbnr: id = ComboBoxGadget(pbnr, x, y, w, h, flags)
EndIf
cbi\cbSize = SizeOf(comboboxinfo)
GetComboBoxInfo_(id, cbi)
*cb\pbnr = nr
*cb\pbid = id
*cb\oldedit = SetWindowLongPtr_(cbi\hwndEdit, #GWL_WNDPROC, @ComboBox_CBEdit())
*cb\oldlist = SetWindowLongPtr_(cbi\hwndList, #GWL_WNDPROC, @ComboBox_CBList())
*cb\oldcombo = SetWindowLongPtr_(cbi\hwndCombo, #GWL_WNDPROC, @ComboBox_CBCombo())
SetWindowLongPtr_(cbi\hwndEdit, #GWL_USERDATA, *cb) ;in Userdata speichern
SetWindowLongPtr_(cbi\hwndList, #GWL_USERDATA, *cb) ;in Userdata speichern
SetWindowLongPtr_(cbi\hwndCombo, #GWL_USERDATA, *cb) ;in Userdata speichern
AddElement(combolist()): combolist() = *cb
If pbnr = #PB_Any
ProcedureReturn nr
Else
ProcedureReturn id
EndIf
EndProcedure
EndModule
UseModule ComboBox
OpenWindow(0, 0, 0, 270, 180, "ComboBox", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ComboBox(0, 10, 10, 250, 21, #PB_ComboBox_Editable)
ComboBox(1, 10, 50, 250, 21)
ComboBox(2, 10, 90, 250, 21, #PB_ComboBox_Editable)
ComboBox_AddItem(1, "keine Ahnung")
ComboBox_AddItem(1, "uups")
ComboBox_AddItem(1, "blah")
Combobox_LoadItem(0, "Zahlen") ;ohne LoadItem, kein Save
Combobox_LoadItem(1, "Diverses")
Combobox_LoadItem(2, "Stadtnamen")
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_Gadget
Select EventGadget()
Case 0
EndSelect
EndSelect
Until event = #PB_Event_CloseWindow