Editierbares ListIconGadget
Verfasst: 10.04.2008 15:24
Hallo,
bin gerade dabei mir ein editierbares ListIconGadget zu basteln. Die
Codes, die es schon gibt, haben mir nicht sonderlich weitergeholfen, weil
man da immer das Handle des Hauptfensters brauchte.
Und jetzt gilt es noch ein paar Problemchen zu lösen.
Zum einen hätte ich gerne in dem Edit Control die selbe Schriftart wie im
ListIconGadget, weil ich nicht weiß, wie man das anstellt.
Zum anderen weiß ich selbst nicht genau, ob ich das mit den Callbacks
alles so richtig gemacht hab. Vielleicht kann einfach mal jemand drüber
schauen und meinen Code korrigieren. Welche Message muss ich denn
z.B. abfangen, wenn ich wissen will, wann das Gadget komplett
freigegeben wurde? #WM_DESTROY ist scheinbar nicht die letzte.
Zum dritten wird das Edit Control nicht an die selbe Position gesetzt wie
der zu editierende Text steht.
Hier also der Code:
bin gerade dabei mir ein editierbares ListIconGadget zu basteln. Die
Codes, die es schon gibt, haben mir nicht sonderlich weitergeholfen, weil
man da immer das Handle des Hauptfensters brauchte.
Und jetzt gilt es noch ein paar Problemchen zu lösen.
Zum einen hätte ich gerne in dem Edit Control die selbe Schriftart wie im
ListIconGadget, weil ich nicht weiß, wie man das anstellt.
Zum anderen weiß ich selbst nicht genau, ob ich das mit den Callbacks
alles so richtig gemacht hab. Vielleicht kann einfach mal jemand drüber
schauen und meinen Code korrigieren. Welche Message muss ich denn
z.B. abfangen, wenn ich wissen will, wann das Gadget komplett
freigegeben wurde? #WM_DESTROY ist scheinbar nicht die letzte.
Zum dritten wird das Edit Control nicht an die selbe Position gesetzt wie
der zu editierende Text steht.
Hier also der Code:
Code: Alles auswählen
EnableExplicit
Structure ListIconGadget_S
id.l
*hnd
*oldCB
*hedit
item.l
subitem.l
*edit_oldCb
EndStructure
Procedure ListIconGadget_EditCB(hwnd.l, Msg.l, wParam.l, lParam.l)
Protected *li.ListIconGadget_S = GetWindowLong_(hwnd, #GWL_USERDATA)
Protected result.l, itemdata.LVITEM
Select Msg
Case #WM_KEYDOWN, #WM_KILLFOCUS
If wParam = #VK_RETURN Or Msg = #WM_KILLFOCUS
;Text aus dem Stringgadget nehmen
itemdata\pszText = AllocateMemory(1025 * SizeOf(Character))
PokeW(itemdata\pszText, 1024)
SendMessage_(hwnd, #EM_GETLINE, 0, itemdata\pszText)
;Text in ListIconGadget schreiben und Speicher wieder freigeben
itemdata\iSubItem = *li\subitem
SendMessage_(*li\hnd, #LVM_SETITEMTEXT, *li\item, itemdata)
FreeMemory(itemdata\pszText)
;Alten Callback wieder aktivieren
SetWindowLong_(hwnd, #GWL_WNDPROC, *li\edit_oldCB)
;
InvalidateRect_(*li\hnd, 0, 0)
;StringGadget schließen
DestroyWindow_(hwnd)
*li\hedit = 0
ProcedureReturn 0
ElseIf wParam = #VK_ESCAPE
;Alten Callback wieder aktivieren
SetWindowLong_(hwnd, #GWL_WNDPROC, *li\edit_oldCB)
;
InvalidateRect_(*li\hnd, 0, 0)
;StringGadget schließen
DestroyWindow_(hwnd)
*li\hedit = 0
ProcedureReturn 0
EndIf
EndSelect
ProcedureReturn CallWindowProc_(*li\edit_oldCB, hwnd, Msg, wParam, lParam)
EndProcedure
Procedure ListIconGadget_CB(hwnd.l, Msg.l, wParam.l, lParam.l)
Protected *li.ListIconGadget_S = GetWindowLong_(hwnd, #GWL_USERDATA)
Protected hit.LVHITTESTINFO, r.Rect, itemdata.LVITEM
Select Msg
Case #WM_LBUTTONDBLCLK
;Mauskoordinaten relativ zum Gadget
hit\pt\x = lparam & $FFFF
hit\pt\y = (lparam >> 16) & $FFFF
;Zeile und Spalte herausfinden
SendMessage_(hwnd, #LVM_SUBITEMHITTEST, 0, hit)
;Debug "Row: " + Str(hit\iItem) + ", Column: " + Str(hit\iSubItem)
;Koordinaten des Eintrags herausfinden
r\left = #LVIR_LABEL
r\top = hit\iSubItem
SendMessage_(hwnd, #LVM_GETSUBITEMRECT, hit\iItem, r)
;Debug "Rect: " + Str(r\left) + ", " + Str(r\top) + ", " + Str(r\right) + ", " + Str(r\bottom)
If hit\iItem >= 0
;Text des Eintrags auslesen
itemdata\iSubItem = hit\iSubItem
itemdata\pszText = AllocateMemory(1025 * SizeOf(Character))
itemdata\cchTextMax = 1024
SendMessage_(hwnd, #LVM_GETITEMTEXT, hit\iItem, itemdata)
;Falls schon ein StringGadget besteht, dann schließen und Änderungen übernehmen
If *li\hedit
SendMessage_(*li\hedit, #WM_KEYDOWN, #VK_RETURN, 0)
EndIf
;neues StringGadget erstellen
*li\hedit = CreateWindow_("edit", 0, #WS_CHILD | #WS_VISIBLE | #ES_LEFT, r\left, r\top, r\right - r\left, r\bottom - r\top, *li\hnd, 0, GetWindowLong_(*li\hnd, #GWL_HINSTANCE), 0)
If *li\hedit
;Text zuweisen
SendMessage_(*li\hedit, #EM_REPLACESEL, #False, itemdata\pszText)
*li\edit_oldCB = SetWindowLong_(*li\hedit, #GWL_WNDPROC, @ListIconGadget_EditCB())
*li\item = hit\iItem
*li\subitem = hit\iSubItem
SetWindowLong_(*li\hedit, #GWL_USERDATA, *li)
SetFocus_(*li\hedit)
EndIf
If itemdata\pszText : FreeMemory(itemdata\pszText) : EndIf
ProcedureReturn 0
EndIf
EndSelect
ProcedureReturn CallWindowProc_(*li\oldCB, hwnd, Msg, wParam, lParam)
EndProcedure
Procedure ListIconGadget_SetEditable(*li.ListIconGadget_S)
*li\hnd = GadgetID(*li\id)
SetWindowLong_(*li\hnd, #GWL_USERDATA, *li)
*li\oldCB = SetWindowLong_(*li\hnd, #GWL_WNDPROC, @ListIconGadget_CB())
EndProcedure
Define li.ListIconGadget_S
If OpenWindow(0, 0, 0, 400, 300, "´bla", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
If CreateGadgetList(WindowID(0))
li\id = ListIconGadget(#PB_Any, 0, 0, 400, 300, "Column0", 100, #PB_ListIcon_FullRowSelect)
ListIconGadget_SetEditable(li)
AddGadgetColumn(li\id, 1, "Column1", 100)
AddGadgetColumn(li\id, 1, "Column2", 100)
AddGadgetItem(li\id, 0, "Row0" + Chr(10) + "XXX" + Chr(10) + "XXX")
AddGadgetItem(li\id, 1, "Row1" + Chr(10) + "XXX" + Chr(10) + "XXX")
AddGadgetItem(li\id, 2, "Row2" + Chr(10) + "XXX" + Chr(10) + "XXX")
AddGadgetItem(li\id, 3, "Row3" + Chr(10) + "XXX" + Chr(10) + "XXX")
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
EndIf
End