[Windows only] Editierbares ListIconGadget und Auswahlliste

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

[Windows only] Editierbares ListIconGadget und Auswahlliste

Beitrag von NicTheQuick »

Hallo Leute,

ich habe mich mal die Woche hingesetzt und ein kleines Beispiel für das
ListIconGadget gebastelt, mit dem man über einen einfachen Callback das
Editieren der einzelnen Einträge ermöglichen kann. Statt einem Editierfeld ist es auch möglich eine Liste aufklappen zu lassen, mit der man sein
Auswahl treffen möchte.

///Edit 1 (16.04.2008, 23:41)
Fixed: ListBox wurde nicht komplett dargestellt, wenn man einen unteren Eintrag ausgewählt hat

///Edit 2 (17.04.2008, 17:13)
New: In der ListBox wird jetzt beim Öffnen der erste Eintrags ausgewählt, der mit dem String in der gewählten Zelle beginnt. Dabei wird Groß- und Kleinschreibung ignoriert.

Hier also die Include:

Code: Alles auswählen

EnableExplicit

Prototype ListIconGadget_Request(GadgetID.l, row.l, column.l, msg.l, *out, *userdata)

Enumeration 1
  ;Msg
  #ListIconGadget_Click
  #ListIconGadget_EditChange
  #ListIconGadget_EditEscape
  
  ;Return für *out
  #ListIconGadget_NoOpen
  #ListIconGadget_Edit
  #ListIconGadget_List
EndEnumeration

;Hier kann man maximal 32768 angeben. Mehr Zeichen unterstützt das Edit Control nicht.
#ListIconGadget_MaxChars = 1024

Structure ListIconGadget_S
  id.l
  *hnd
  msg.l[4]
  direct.l
  *oldCB
  *hedit
  item.l
  subitem.l
  type.l
  r.RECT
  *edit_oldCb
  *requestCB.ListIconGadget_Request
  *userdata
EndStructure

;Der Callback für das ListIconGadget
Procedure ListIconGadget_CB(hwnd.l, Msg.l, wParam.l, lParam.l)
  Protected *li.ListIconGadget_S = GetWindowLong_(hwnd, #GWL_USERDATA)
  Protected hit.LVHITTESTINFO, itemdata.LVITEM, open.l, *out, *c.Character, char.c, *begin
  Protected minpos.l, maxpos.l, cpp.l, delta.l, i.l, length.l, type.l, client.RECT
  
  If hwnd = *li\hnd
    Select Msg
      Case *li\msg[0], *li\msg[1], *li\msg[2], *li\msg[3]
      ;Case #WM_LBUTTONDOWN, #WM_LBUTTONDBLCLK
        ;Mauskoordinaten relativ zum Gadget
        hit\pt\x = lparam & $FFFF
        hit\pt\y = (lparam >> 16) & $FFFF
        
        ;Zeile und Spalte ermitteln
        SendMessage_(hwnd, #LVM_SUBITEMHITTEST, 0, hit)
        
        If hit\iItem >= 0
          If *li\requestCB
            type = *li\requestCB(*li\id, hit\iItem, hit\iSubitem, #ListIconGadget_Click, @*out, *li\userdata)
          Else
            type = #ListIconGadget_Edit
          EndIf
          
          ;Koordinaten des Eintrags errechnen
          *li\r\left = #LVIR_BOUNDS
          *li\r\top = hit\iSubItem
          SendMessage_(hwnd, #LVM_GETSUBITEMRECT, hit\iItem, *li\r)
          If hit\iSubItem = 0 ;Bei erster Spalte muss die Breite korrigiert werden
            *li\r\left - 2
            *li\r\right = *li\r\left + SendMessage_(hwnd, #LVM_GETCOLUMNWIDTH, 0, 0) + 2
          EndIf
          
          ;Text des Eintrags auslesen
          itemdata\iSubItem = hit\iSubItem
          itemdata\pszText = AllocateMemory((#ListIconGadget_MaxChars + 1) * SizeOf(Character))
          itemdata\cchTextMax = #ListIconGadget_MaxChars
          SendMessage_(hwnd, #LVM_GETITEMTEXT, hit\iItem, itemdata)
          
          ;Falls schon Edit Control/ListBox besteht, dann schließen und Änderungen übernehmen
          If *li\hedit
            Select *li\type
              Case #ListIconGadget_Edit
                SendMessage_(*li\hedit, #WM_KILLFOCUS, #VK_RETURN, 0)
              Case #ListIconGadget_List
                SendMessage_(*li\hedit, #WM_KILLFOCUS, #VK_ESCAPE, 0)
            EndSelect
            If Not *li\direct : ProcedureReturn 0 : EndIf
          EndIf
          
          Select type
            Case #ListIconGadget_NoOpen
              ProcedureReturn 0
              ;do nothing
            
            Case #ListIconGadget_Edit ;{
              *li\type = type
              
              *li\r\left + 6
              *li\r\bottom - 1
              
              ;neues StringGadget erstellen
              *li\hedit = CreateWindow_("edit", 0, #ES_AUTOHSCROLL | #WS_CHILD | #ES_LEFT, *li\r\left, *li\r\top, *li\r\right - *li\r\left, *li\r\bottom - *li\r\top, *li\hnd, 0, GetWindowLong_(*li\hnd, #GWL_HINSTANCE), 0)
              If *li\hedit
                ;Text zuweisen
                SendMessage_(*li\hedit, #WM_SETFONT, SendMessage_(hwnd, #WM_GETFONT, 0, 0), 0)
                SendMessage_(*li\hedit, #EM_REPLACESEL, #False, itemdata\pszText)
                *li\item = hit\iItem
                *li\subitem = hit\iSubItem
                SetWindowLong_(*li\hedit, #GWL_USERDATA, *li)
                *li\edit_oldCB = SetWindowLong_(*li\hedit, #GWL_WNDPROC, @ListIconGadget_CB())
                ShowWindow_(*li\hedit, #SW_SHOW)
                SetFocus_(*li\hedit)
              EndIf
              
              If itemdata\pszText : FreeMemory(itemdata\pszText) : EndIf
              ProcedureReturn 0 ;}
            
            Case #ListIconGadget_List ;{
              *li\type = type
              
              *li\r\left + 6
              *li\r\bottom = *li\r\top + (*li\r\bottom - *li\r\top) * 6 - 1
              
              GetClientRect_(hwnd, client)
              If *li\r\bottom > client\bottom
                *li\r\top - (*li\r\bottom - client\bottom)
                *li\r\bottom = client\bottom
              EndIf
              
              ;neue ListBox erstellen
              *li\hedit = CreateWindow_("listbox", 0, #WS_VSCROLL | #WS_CHILD | #WS_BORDER, *li\r\left, *li\r\top, *li\r\right - *li\r\left, *li\r\bottom - *li\r\top, *li\hnd, 0, GetWindowLong_(*li\hnd, #GWL_HINSTANCE), 0)
              If *li\hedit
                SendMessage_(*li\hedit, #WM_SETFONT, SendMessage_(hwnd, #WM_GETFONT, 0, 0), 0)
                *li\item = hit\iItem
                *li\subitem = hit\iSubItem
                SetWindowLong_(*li\hedit, #GWL_USERDATA, *li)
                *li\edit_oldCB = SetWindowLong_(*li\hedit, #GWL_WNDPROC, @ListIconGadget_CB())
                ShowWindow_(*li\hedit, #SW_SHOW)
                SetFocus_(*li\hedit)
                
                If *out
                  *c = *out
                  char = *c\c
                  *c + SizeOf(Character)
                  *begin = *c
                  i = 0
                  Repeat
                    If *c\c = char
                      If *c = *begin
                        Break
                      Else
                        *c\c = 0
                        SendMessage_(*li\hedit, #LB_ADDSTRING, 0, *begin)
                        *begin = *c + SizeOf(Character)
                        i + 1
                      EndIf
                    EndIf
                    *c + SizeOf(Character)
                  ForEver
                  FreeMemory(*out)
                  
                  SendMessage_(*li\hedit, #LB_SELECTSTRING, -1, itemdata\pszText)
                EndIf
              EndIf
              
              If itemdata\pszText : FreeMemory(itemdata\pszText) : EndIf
              ProcedureReturn 0 ;}
          EndSelect  
        EndIf
      
      Case #WM_PAINT ;{
        If *li\hedit
          ;Koordinaten des Eintrags errechnen
          *li\r\left = #LVIR_BOUNDS
          *li\r\top = *li\subitem
          SendMessage_(hwnd, #LVM_GETSUBITEMRECT, *li\item, *li\r)
          If *li\subitem = 0 ;Bei erster Spalte muss die Breite korrigiert werden
            *li\r\left - 2
            *li\r\right = *li\r\left + SendMessage_(hwnd, #LVM_GETCOLUMNWIDTH, 0, 0) + 2
          EndIf
          
          Select *li\type
            Case #ListIconGadget_Edit
              *li\r\left + 6
              *li\r\bottom - 1
              
              MoveWindow_(*li\hedit, *li\r\left, *li\r\top, *li\r\right - *li\r\left, *li\r\bottom - *li\r\top, 0)
            
            Case #ListIconGadget_List
              *li\r\left + 6
              *li\r\bottom = *li\r\top + (*li\r\bottom - *li\r\top) * 6 - 1
              
              GetClientRect_(hwnd, client)
              If *li\r\bottom > client\bottom
                *li\r\top - (*li\r\bottom - client\bottom)
                *li\r\bottom = client\bottom
              EndIf
              
              MoveWindow_(*li\hedit, *li\r\left, *li\r\top, *li\r\right - *li\r\left, *li\r\bottom - *li\r\top, 0)
          EndSelect
          
          InvalidateRect_(*li\hedit, 0, 0)
          ;Komplette erste Spalte neuzeichnen
          client\top = 0
          client\left = *li\r\left
          client\bottom = *li\r\bottom
          client\right = *li\r\right
          InvalidateRect_(hwnd, client, 0)
        EndIf ;}
      
      ;Aufpassen, dass das Edit Control nicht nach oben oder unten aus dem Fenster rutscht, links und rechts ist egal (vorerst)
      Case #WM_VSCROLL ;{
        If *li\hedit
          cpp = SendMessage_(hwnd, #LVM_GETCOUNTPERPAGE, 0, 0)
          minpos = SendMessage_(hwnd, #LVM_GETTOPINDEX, 0, 0)
          maxpos = minpos + cpp
          
          Select wParam & $FFFF
            Case #SB_THUMBPOSITION, #SB_THUMBTRACK
              minpos = (wParam >> 16) & $FFFF
              If *li\item < minpos Or *li\item >= minpos + cpp : ProcedureReturn 0: EndIf
            Case #SB_LINEDOWN   : If *li\item < minpos + 1    : ProcedureReturn 0 : EndIf
            Case #SB_LINEUP     : If *li\item >= maxpos - 1   : ProcedureReturn 0 : EndIf
            Case #SB_PAGEDOWN   : If *li\item < minpos + cpp  : ProcedureReturn 0 : EndIf
            Case #SB_PAGEUP     : If *li\item >= maxpos - cpp : ProcedureReturn 0 : EndIf
            Default             : ProcedureReturn 0
          EndSelect
        EndIf ;}
      
      ;Wenn jemand rumscrollen will, lass das ja nicht zu :)
      Case #WM_MOUSEWHEEL ;{
        If *li\hedit
;           delta = ((wParam >> 16) & $FFFF)
;           If delta > $7FFF : delta = -$10000 + delta : EndIf
;           minpos = SendMessage_(hwnd, #LVM_GETTOPINDEX, 0, 0)
;           maxpos = minpos + cpp
          ProcedureReturn 0
        EndIf ;}
    EndSelect
    
    ProcedureReturn CallWindowProc_(*li\oldCB, hwnd, Msg, wParam, lParam)
  
  ;***********************************************
  ;**** EVENT HANDLING FOR THE OTHER CONTROLS ****
  ;***********************************************
  ElseIf hwnd = *li\hedit
    Select *li\type
      Case #ListIconGadget_Edit ;{
      ;***********************************************
      ;***************** EDIT CONTROL ****************
      ;***********************************************
        Select Msg
          Case #WM_KILLFOCUS
            ;Text aus dem Stringgadget nehmen
            itemdata\pszText = AllocateMemory((#ListIconGadget_MaxChars + 1) * SizeOf(Character))
            PokeW(itemdata\pszText, #ListIconGadget_MaxChars)
            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)
            
            ;StringGadget schließen
            DestroyWindow_(hwnd)
            
            *li\hedit = 0
            
            If *li\requestCB
              *li\requestCB(*li\id, *li\item, *li\subitem, #ListIconGadget_EditChange, 0, *li\userdata)
            EndIf
          
          Case #WM_KEYDOWN
            Select wParam
              Case #VK_RETURN
                ;Text aus dem Stringgadget nehmen
                itemdata\pszText = AllocateMemory((#ListIconGadget_MaxChars + 1) * SizeOf(Character))
                PokeW(itemdata\pszText, #ListIconGadget_MaxChars)
                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)
                
                ;StringGadget schließen
                DestroyWindow_(hwnd)
                
                *li\hedit = 0
                
                If *li\requestCB
                  *li\requestCB(*li\id, *li\item, *li\subitem, #ListIconGadget_EditChange, 0, *li\userdata)
                EndIf
            
              Case #VK_ESCAPE ;Wenn Escape gedrückt wurde
                ;StringGadget schließen
                DestroyWindow_(hwnd)
                
                *li\hedit = 0
                
                If *li\requestCB
                  *li\requestCB(*li\id, *li\item, *li\subitem, #ListIconGadget_EditEscape, 0, *li\userdata)
                EndIf
            EndSelect
        EndSelect
        
        ProcedureReturn CallWindowProc_(*li\edit_oldCB, hwnd, Msg, wParam, lParam)
      ;}
      
      Case #ListIconGadget_List ;{
      ;***********************************************
      ;******************* LIST BOX ******************
      ;***********************************************
        Select msg
          Case #WM_KILLFOCUS
            *li\hedit = 0
            DestroyWindow_(hwnd)
            
            If *li\requestCB
              *li\requestCB(*li\id, *li\item, *li\subitem, #ListIconGadget_EditEscape, 0, *li\userdata)
            EndIf
          
          Case #WM_LBUTTONUP
            i = SendMessage_(hwnd, #LB_GETCURSEL, 0, 0)
            If i >= 0
              itemdata\cchTextMax = SendMessage_(hwnd, #LB_GETTEXTLEN, i, 0)
              itemdata\pszText = AllocateMemory((itemdata\cchTextMax + 1) * SizeOf(Character))
              SendMessage_(hwnd, #LB_GETTEXT, i, 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)
              
              *li\hedit = 0
              DestroyWindow_(hwnd)
              
              If *li\requestCB
                *li\requestCB(*li\id, *li\item, *li\subitem, #ListIconGadget_EditChange, i, *li\userdata)
              EndIf
            EndIf
          
          Case #WM_KEYDOWN
            If wParam = #VK_ESCAPE
              *li\hedit = 0
              DestroyWindow_(hwnd)
              
              If *li\requestCB
                *li\requestCB(*li\id, *li\item, *li\subitem, #ListIconGadget_EditEscape, 0, *li\userdata)
              EndIf
            EndIf
        EndSelect
        
        ProcedureReturn CallWindowProc_(*li\edit_oldCB, hwnd, Msg, wParam, lParam)
      ;}
    EndSelect
  EndIf
EndProcedure

;Die Procedure zum Initialisieren von allem oben drüber
Procedure ListIconGadget_SetEditable(*li.ListIconGadget_S, *requestCB = 0, *userdata = 0)
  *li\hnd = GadgetID(*li\id)
  SetWindowLong_(*li\hnd, #GWL_USERDATA, *li)
  *li\oldCB = SetWindowLong_(*li\hnd, #GWL_WNDPROC, @ListIconGadget_CB())
  *li\requestCB = *requestCB
  *li\userdata = *userdata
EndProcedure
Und dazu dieses simple Beispiel

Code: Alles auswählen

XIncludeFile "ListIconGadget editable.pbi"

;Der Callback macht folgendes:
;Bei Klick in die erste Spalte, klappt eine Auswahlliste aus
;Bei Klick in die zweite und dritte Spalte kann editiert werden
;Bei Klick in die dritte Spalte wechselt diese zwischen Ja und Nein
;Wenn man in Spalte 2 und 3 nichts eingegeben hat, dann wird '(nichts)' hineingeschrieben
Procedure requestEdit(GadgetID.l, row.l, column.l, msg.l, *out, *userdata)
  Protected *pout.Long = *out
  
  Select msg
    Case #ListIconGadget_Click
      If column = 0
        *pout\l = AllocateMemory(1024)
        If *pout\l
          ;Zuerst das Trennzeichen, dann die Elemente und dann zweimal das Trennzeichen
          PokeS(*pout\l, ";Hallo;das;ist;die;Auswahlliste;für;die;" + Str(row) + ". Zeile;;")
          ;*pout\l wird danach wieder mit FreeMemory() freigegeben
          ProcedureReturn #ListIconGadget_List
        EndIf
        ProcedureReturn #ListIconGadget_NoOpen
      
      ElseIf column = 3
        If GetGadgetItemText(GadgetID, row, column) = "Ja"
          SetGadgetItemText(GadgetID, row, "Nein", column)
        Else
          SetGadgetItemText(GadgetID, row, "Ja", column)
        EndIf
        ProcedureReturn #ListIconGadget_NoOpen
      EndIf
      
      ProcedureReturn #ListIconGadget_Edit
    
    Case #ListIconGadget_EditChange
      If GetGadgetItemText(GadgetID, row, column) = ""
        SetGadgetItemText(GadgetID, row, "(nichts)", column)
      EndIf
      Debug "Zeile " + Str(row) + ", Spalte " + Str(column) + " geändert: '" + GetGadgetItemText(GadgetID, row, column) + "'"
    
    Case #ListIconGadget_EditEscape
      Debug "Zeile " + Str(row) + ", Spalte " + Str(column) + " NICHT geändert: '" + GetGadgetItemText(GadgetID, row, column) + "'"
  EndSelect
EndProcedure

Define li.ListIconGadget_S, i.l, s.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", 75, #PB_ListIcon_FullRowSelect | #PB_ListIcon_GridLines)
      AddGadgetColumn(li\id, 1, "Column1", 75)
      AddGadgetColumn(li\id, 2, "Column2", 75)
      AddGadgetColumn(li\id, 3, "Column3", 75)
    
    For i = 0 To 100
      AddGadgetItem(li\id, i, "Row" + Str(i) + Chr(10) + "C1" + Chr(10) + "C2" + Chr(10) + "X")
    Next
    
    ;Messages, bei denen reagiert werden soll
    li\msg[0] = #WM_RBUTTONDOWN
    li\msg[1] = #WM_RBUTTONDBLCLK
    
    ;Steht 'direct' auf #True, kann man von einem Edit direkt ins andere klicken
    li\direct = #True
    
    ListIconGadget_SetEditable(li, @requestEdit(), 2)
    
    Repeat
    Until WaitWindowEvent() = #PB_Event_CloseWindow
  EndIf
EndIf
End
Wenn es Probleme, Kritik oder Wünsche gibt, nur her damit.
Zuletzt geändert von NicTheQuick am 17.04.2008 17:15, insgesamt 3-mal geändert.
Bild
Benutzeravatar
Morty
Beiträge: 268
Registriert: 22.10.2004 07:20
Wohnort: Erfurt
Kontaktdaten:

Beitrag von Morty »

Hi.

Ansich wirklich eine gute Sache :allright:
Was mir gerade beim ersten Test aufgefallen ist. Wenn man die Auswahlliste für die letzte Zeile öffnet (erste Spalte -> rechtsklick) verschwindet diese im Rahmen des Gadgets.

Morty
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Beitrag von NicTheQuick »

Okay, ich hab's geändert.

Ich weiß jetzt allerdings noch nicht, wie ich das ganze etwas flimmerfreier
beim Scrollen hinkriege. Falls sich da jemand auskennt, bitte melden! :allright:

///Edit:
Achja, es gibt noch ein Problem:
Wenn ich einen Eintrag ändere, werden bei mir im Debug-Fenster immer nur
die ersten 6 Zeichen des Eintrags angezeigt. Da weiß nicht zufällig jemand,
warum das so ist? Per API wird es ja richtig geändert und auch angezeigt,
aber 'GetGadgetItemText()' liefert dann nur die ersten 6 Zeichen. :freak:
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Beitrag von NicTheQuick »

Kuckucks!

Hab noch eine Kleinigkeit geändert. Siehe erste Post.

Bin mal gespannt, ob das am Wochenende noch ein paar Leute testen
werden. :wink:
Bild
marco2007
Beiträge: 906
Registriert: 26.10.2006 13:19
Kontaktdaten:

Beitrag von marco2007 »

Hi NTQ,

:allright:

Ich verstehe den Code zwar nicht wirklich, aber die 6 Zeichen kommen irgendwie vom längsten vorkommenden String in der ersten Spalte: Row100 -> ändert man dies z.B. auf:

Code: Alles auswählen

AddGadgetItem(li\id, i, "Row_" + Str(i) + Chr(10) + "C1" + Chr(10) + "C2" + Chr(10) + "X")
...dann werden 7 Zeichen angezeigt.

Macht man am Anfang folgendes:

Code: Alles auswählen

AddGadgetItem(li\id, 0, Space(255))
RemoveGadgetItem(li\id,0)
..dann werden auf jeden Fall bis zu 255 Zeichen angezeigt...ist aber nur eine schlampige Lösung :oops:

Hilft Dir das?

lg
Marco
Windows 11 - PB 6.03 x64
_________________________________
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Beitrag von NicTheQuick »

Tja, da muss ich bei Gelegenheit mal gucken. Ich könnte mir aber vorstellen,
das das eine Macke von PB ist, das sich vielleicht die maximale Länge eines
Eintrags irgendwo merkt oder so ein Schmarrn...
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Beitrag von NicTheQuick »

Ich behelfe mir immer noch mit dem 'Add' und 'Remove' vor dem Listen
füllen. Ich habe auch festgestellt, dass es nach einem 'ClearGadgetItemList()'
nochmals nötig ist das zu tun.

Kennt jemand da ein paar Interna von PB zum ListIconGadget?
Bild
marco2007
Beiträge: 906
Registriert: 26.10.2006 13:19
Kontaktdaten:

Beitrag von marco2007 »

Hi,

Ich habe in der Include folgendes geändert:

Code: Alles auswählen

Global auswahl.s 


+

Code: Alles auswählen

Case #WM_LBUTTONUP 
            i = SendMessage_(hwnd, #LB_GETCURSEL, 0, 0) 
            If i >= 0 
              itemdata\cchTextMax = SendMessage_(hwnd, #LB_GETTEXTLEN, i, 0) 
              itemdata\pszText = AllocateMemory((itemdata\cchTextMax + 1) * SizeOf(Character)) 
              Debug SendMessage_(hwnd, #LB_GETTEXT, i, itemdata\pszText) 
              
              ;Text in ListIconGadget schreiben und Speicher wieder freigeben 
              itemdata\iSubItem = *li\subitem 
              SendMessage_(*li\hnd, #LVM_SETITEMTEXT, *li\item, itemdata) 
              auswahl=PeekS(itemdata\pszText)
              FreeMemory(itemdata\pszText) 
              
              *li\hedit = 0 
              DestroyWindow_(hwnd) 
              
              If *li\requestCB 
                *li\requestCB(*li\id, *li\item, *li\subitem, #ListIconGadget_EditChange, i, *li\userdata) 
              EndIf 
            EndIf 

Code: Alles auswählen

auswahl=PeekS(itemdata\pszText)
...auch bei #VK_Return

Und in der Main:

Code: Alles auswählen

Case #ListIconGadget_EditChange 
      If GetGadgetItemText(GadgetID, row, column) = "" 
        SetGadgetItemText(GadgetID, row, "(nichts)", column) 
      EndIf 
      SetGadgetItemText(GadgetID, row, auswahl, column)
      Debug "Zeile " + Str(row) + ", Spalte " + Str(column) + " geändert: '" + GetGadgetItemText(GadgetID, row, column) + "'" 


...dann geht`s zumindest... Heißt das im Umkehrschluß, daß das Problem eventuell bei einem der Sendmessage-Befehle liegen kann? Bei den Parametern eventuell? #LVM..., #LB.., itemdata -> Ich kenn`mich mit WinApi leider null aus...

lg
Marco
Windows 11 - PB 6.03 x64
_________________________________
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Beitrag von NicTheQuick »

Ja, klar, das geht auch. Nur würde ich gerne die gesamte Include in
Procedures packen und auch Multithreading zulassen. Das geht mit globalen
Variablen natürlich nicht.
Aber in der SendMessage liegt der Fehler nicht. Denn der Text kann ja auch
wieder richtig ausgelesen werden. Ich habe wegen diesem Problem die Hilfe
zu jedem Befehl des ListIconGadget in der MSDN durch. Und es gibt einfach
keinen Fehler. Ich mache alles richtig.

Wenn ich mal Zeit hab, werde ich sowieso noch versuchen die Include auch
Linux tauglich zu machen. Eine Userlib werde ich wohl nicht daraus machen,
weil man dann auch nicht mehr schnell noch was dazubauen kann, wenn man
es braucht.

Vielleicht kann freak ja zum Handling des ListIconGadgets was sagen?
Bild
Antworten