Geht fast: Icons in allen Spalten eines ListIconGadget

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
Kurzer
Beiträge: 1618
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Geht fast: Icons in allen Spalten eines ListIconGadget

Beitrag von Kurzer »

Hallo Ihrs, :)

ich war auf der Suche nach einer Möglichkeit in allen Spalten eines ListIconGadgets Icons einzufügen.
Die SuFu war hier ganz nützlich und es gibt so einige schöne Beispielcodes.

Nun habe ich mir das, was ich benötige aus den meist sehr komplexen Beispielen extrahiert und rausgekommen ist das da unten.
Soweit klappt das auch, was mich nur nervt sind die folgenden zwei Dinge:

- Beim Setzen eines Icons in eine Spalte wird immer auch die Spalte 0 mit einem Icon belegt. Warum? Wie kann man das unterbinden?

- Ist eine Zeile mit Icon selektiert, dann wird das Icon nicht als transparentes Icon dargestellt. Man sieht also den weißen Rahmen drumherum. Gespeichert wurden die Icons mit IrfanView, wobei die weiße Randfarbe explizit als Transparenzfarbe ausgewählt wurde. Wie bekommt man das in den markierten Spalten auch transparent hin?
WIe man sieht habe ich versucht per API eine Transparenzmaske für die Icons zu erzeugen, aber damit klapperts auch nicht.

Dann noch eine weitere Frage. Ist es möglich mehrere Icons nebeneinander in die gleiche Spalte zu platzieren? Also ohne dafür ein neues (breiteres) Image zu erstellen, auf das die drei Icons nebeneinander gezeichnet werden?

Wäre cool, wenn man mir da mal unter die Arme greifen würde (nein, ich schwitze auch nicht :lol: )

Ich denke darüber nach, solche Erweiterungen von bestehenden Gadgets evtl. als eigenständige Befehle zu implementieren (PB-Lib), damit diese ganzen API-Aufrufe von meinem eigentlichen Programmcode weggekapselt sind.
Da ich das noch nie gemacht habe, weiß ich nicht ob es überhaupt sinnvoll ist. Falls doch gebt mir mal einen Hinweis wo/wonach ich am besten gucken sollte, um weitere Infos zu bekommen.

So, hier aber erstmal der Code mit dem ListIconGadget:

Edit: Ich habe das Problem mit dem Icon in der ersten Spalte erstmal mit einem "unsichtbaren" Icon gelöst. Aber schön ist das nicht, weil der Platz dafür noch immer reserviert bleibt. Den Code unten habe ich angepaßt.

Evtl. kann man tricksen, indem man die erste Spalte einfach auf Breite 0 setzt und sie nicht benutzt. :freak:
Bleibt noch das Problem, daß die Icons nicht transparent sind, wenn der blaube Selektionsbalken drüber liegt. Da sind die alle rechteckig.

Bin weiter für Lösungsansätze dankbar...

Edit 2, 14.07.09: Meine Fresse, offenbar ist die Problematik gar nicht so trivial.

Ich habe das Beispiel noch einmal überarbeitet. Das automatisch gesetzte Icon in der ersten Spalte kann man wieder löschen. Es muß nicht mit einem weißen Dummy-Icon "unsichtbar" gemacht werden.

Irgendwie habe ich es auch geschafft, daß die Icons in einer selektierten Zeile zumindest halbtransparent blau hinterlegt sind (vorher war der blaue Selektionsbalken über den Icons gar nicht zu sehen. Die hatten immer einen weißen Hintergrund). Das liegt jetzt aber auch nur daran, daß die Icons in der ImageList keinen transparenten Hintergrund haben (#CLR_NONE). Da habe ich jetzt entnervt aufgegeben das schöner hinzukriegen - eigentlich sollte die weiße Bereiche der Icons auch komplett mit der blauen Farbe des Balkens ausgefüllt sein, wenn selektiert). Aber andere bekommen es offenbar auch nicht hin, wie ich vorhin mit einem Blick auf meine FritzBox-Protect-Software sehen konnte - hehe.

So, allerdings bleibt rechts neben den Icons noch immer ein Rand von 2 Pixeln, in denen der blaue Auswahlbalken mit weiß unterbrochen ist.

Das fällt in dem Moment nicht mehr auf, wenn eine Spalte nur Grafik enthält und genauso breit ist, wie das Icon. Im aktuellen Beispiel also die Grafik in Spalte 2.

Ich denke für meine Bedürfnisse reicht das jetzt. Falls noch jemand eine Idee zur optischen Verbesserung hat... immer her damit. :)

Ach so... und die Icons sind natürlich Bitmaps. Hier habe ich übrigens auch vergeblich nach einem Win-API Äquivalent zu CatchImage() gesucht. Wäre ja cool, wenn man die ImageList_ für das ListIconGadget direkt per API aus den Datazeilen "grabben" könnte ohne vorher einmal extra Speicher für CatchImage() und FreeImage() benutzen zu müssen. Ein "LoadImageFromMemory_" wäre da nicht schlecht.

Code: Alles auswählen

EnableExplicit

Procedure SetGadgetItemIcon(iGadgetNr.i, iRow.i, iCol.i, iIcon.i, iSet.i)
  Protected lvi.lv_item
  lvi\mask     = #LVIF_IMAGE
  lvi\iItem    = iRow     ; row number for change
  lvi\iSubItem = iCol     ; 2nd subitem
  lvi\pszText  = #Null   ; text to change to
	If iSet 
  	lvi\iImage   = iIcon   ; Icon setzen
	Else
	  lvi\iImage   = -1				; Icon löschen
	EndIf
  SendMessage_(GadgetID(iGadgetNr), #LVM_SETITEM, 0, @lvi)
EndProcedure

Define iGadgetNr.i, hListIconGadget.i, hImlImages.i, iStyle.i, Event.i
Define sText.s

If OpenWindow(0, 100, 100, 350, 100, "Icons in allen ListIcon-Spalten, nicht nur in der ersten.", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	; ListIconGadget anlegen
	iGadgetNr = ListIconGadget(#PB_Any, 5, 5, 340, 90, "Dummy", 50, #PB_ListIcon_FullRowSelect) ;#PB_ListIcon_AlwaysShowSelection|#LVS_NOCOLUMNHEADER)

	; 4 weitere Spalten zufügen
	AddGadgetColumn(iGadgetNr, 1, "1", 16)
	AddGadgetColumn(iGadgetNr, 2, "2", 100)
	AddGadgetColumn(iGadgetNr, 3, "3", 80)
	AddGadgetColumn(iGadgetNr, 4, "4", 80)
	
	; Und drei Beispiel-Zeilen erzeugen
 	AddGadgetItem(iGadgetNr, -1, #LF$ + "" + #LF$ + " Ernst" + #LF$ + " hungrig")
 	AddGadgetItem(iGadgetNr, -1, #LF$ + "" + #LF$ + " Karl" + #LF$ + " faul")
 	AddGadgetItem(iGadgetNr, -1, #LF$ + "" + #LF$ + " Gabi" + #LF$ + " schön")

	hListIconGadget = GadgetID(iGadgetNr)

	; Eine Imagelist aufbauen
	CatchImage(0, ?Test)
	hImlImages = ImageList_Create_(16, 16, #ILC_COLOR32 | #ILC_MASK, 0, 8)	; | #ILC_MASK
 	ImageList_AddMasked_(hImlImages, ImageID(0), #CLR_NONE)
 	
	; Das "PB-eigenen" Image ist jetzt nicht mehr nötig, weil es in die ImageList kopiert wurde
	FreeImage(0)

	; Die Imagelist dem ListIconGadget zuordnen
	SendMessage_(hListIconGadget, #LVM_SETIMAGELIST, #LVSIL_SMALL, hImlImages)
	
	; Jetzt dem ListIconGadget sagen, daß es auch in SubItems Icons anzeigel soll/darf
  iStyle = SendMessage_(hListIconGadget, #LVM_GETEXTENDEDLISTVIEWSTYLE , 0, 0) | #LVS_EX_SUBITEMIMAGES
  SendMessage_(hListIconGadget, #LVM_SETEXTENDEDLISTVIEWSTYLE , 0, iStyle)
  
;   SendMessage_(hListIconGadget, #LVM_SETTEXTBKCOLOR , 0, #White) 
;   SendMessage_(hListIconGadget, #LVM_SETBKCOLOR, 0, #White) 
  
	;Die blöden, per default gesetzen Icons in Spalte 0 entfernen
 	SetGadgetItemIcon(iGadgetNr, 0, 0, 0, #False)
 	SetGadgetItemIcon(iGadgetNr, 1, 0, 0, #False)
 	SetGadgetItemIcon(iGadgetNr, 2, 0, 0, #False)

	;Jetzt die Icons nachträglich in die Spalten setzen
 	SetGadgetItemIcon(iGadgetNr, 0, 1, 2, #True)
 	SetGadgetItemIcon(iGadgetNr, 1, 1, 2, #True)
 	SetGadgetItemIcon(iGadgetNr, 2, 1, 2, #True)
 	 	
 	SetGadgetItemIcon(iGadgetNr, 0, 2, 1, #True)
 	SetGadgetItemIcon(iGadgetNr, 1, 2, 1, #True)
 	SetGadgetItemIcon(iGadgetNr, 2, 2, 0, #True)
		
 	SetGadgetItemIcon(iGadgetNr, 0, 4, 2, #True)
 	SetGadgetItemIcon(iGadgetNr, 1, 4, 2, #True)
 	SetGadgetItemIcon(iGadgetNr, 2, 4, 2, #True)

	Repeat
	 Event = WaitWindowEvent()
	Until Event = #PB_Event_CloseWindow

	; Am Ende die Imagelist wieder freigeben
	ImageList_Destroy_(hImlImages)
EndIf

DataSection
	; Dies ist ein 16 Farben BMP Image mit 48 x 16 Pixeln Ausmaße (also quasi drei 16 x 16 Pixel große Images nebeneinander)
	Test:
	; IncludeBinary "test.bmp"
  Data.l $01F64D42,$00000000,$00760000,$00280000,$00300000,$00100000,$00010000,$00000004,$01800000,$00000000
  Data.l $00000000,$00000000,$00000000,$02040000,$FEFC00FC,$02FC00FC,$00000004,$FC820000,$3A00002D,$3C0000FF
  Data.l $00000091,$5500007C,$01000001,$02000000,$00000000,$E9910000,$43B10061,$003700AC,$007E0080,$1111007C
  Data.l $11111111,$11111111,$11111111,$11111111,$11111111,$11111111,$11111111,$11111111,$11111111,$11111111
  Data.l $11111111,$11111111,$11111111,$10111111,$10111101,$11111101,$11111111,$11111111,$11222211,$11111111
  Data.l $00111100,$11111111,$11111111,$11111111,$21222212,$11111111,$01000010,$11111111,$11111111,$11111111
  Data.l $22111122,$11111111,$11000011,$11111111,$11881811,$12111111,$12111121,$11111121,$11111111,$11111111
  Data.l $81888811,$11111111,$11211211,$11111111,$11011011,$11111111,$88888818,$11111111,$11211211,$11111111
  Data.l $11011011,$11111111,$88888818,$11111111,$11211211,$11111111,$11011011,$11111111,$88888818,$12111111
  Data.l $12111121,$10111121,$10111101,$11111101,$81888811,$22111111,$22111122,$00111122,$00111100,$11111100
  Data.l $11881811,$22111111,$22111122,$00111122,$00111100,$11111100,$11111111,$12111111,$12111121,$10111121
  Data.l $10111101,$11111101,$11111111,$11111111,$11111111,$11111111,$11111111,$11111111,$11111111,$11111111
  Data.l $11111111,$11111111,$11111111,$11111111,$11111111
  Data.b $11,$11
  
EndDataSection
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
Benutzeravatar
Kurzer
Beiträge: 1618
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

Beitrag #1 und Sourcecode nochmal ergänzt (siehe Edit 2)
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Wie? Was? Wo? Problem gelöst oder was?
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
Kurzer
Beiträge: 1618
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag von Kurzer »

Na sagen wir mal so. Es gibt dabei noch Teilaspekte, die mir nicht so ganz gefallen.
Z.B., daß ich über CatchImage/FreeImage gehen muß, um eine binär Includete Bitmap in die Imagelist zu transferieren.
Oder daß in Spalte 0 am linken Rand immer noch 16 Pixel rumlümmeln, auch wenn kein icon drin ist.
Oder die Tatsache, daß der Hintergrund eines selektierten Icons einen 2 Pixel breiten weißen Streifen hat.

Manches geht wohl einfach nicht besser, weil es vielleicht nicht vorgesehen ist. Anderes kann man zwar teilweise über Würgarounds lösen, aber ich hasse solche Kompromisse.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
Benutzeravatar
E-P-S
Beiträge: 134
Registriert: 30.03.2007 09:39
Kontaktdaten:

Re: Geht fast: Icons in allen Spalten eines ListIconGadget

Beitrag von E-P-S »

Netter Code. Das mit den 16 Pixeln Rand in der ersten Spalte ärgert mich persönlich am meisten. Mein Workaround hierfür: Ich erstelle diese Spalte mit einer Breite von 0 und beginne einfach erst ab Spalte 2.

Oder hat jemand vielleicht eine bessere Lösung gefunden?
Antworten