ListIconGadget mit 2 Checkboxen
ListIconGadget mit 2 Checkboxen
Hallo Zusammen,
hat Jemand eine Idee wie man das realisieren kann in einem ListIconGadget ?
Mit dem Flag #PB_ListIcon_CheckBoxes werden in der ersten Spalte Checkboxen angezeigt.
Gibt es auch eine Möglichkeit (WinApi ist gerne gesehen) 2 (oder mehrere) Checkboxen anzuzeigen z. B. in Spalte 2
Und diese sollte auch noch ausgewertet werden...
Vielen Dank für Hinweise.
Grüße
Andreas
hat Jemand eine Idee wie man das realisieren kann in einem ListIconGadget ?
Mit dem Flag #PB_ListIcon_CheckBoxes werden in der ersten Spalte Checkboxen angezeigt.
Gibt es auch eine Möglichkeit (WinApi ist gerne gesehen) 2 (oder mehrere) Checkboxen anzuzeigen z. B. in Spalte 2
Und diese sollte auch noch ausgewertet werden...
Vielen Dank für Hinweise.
Grüße
Andreas
Re: ListIconGadget mit 2 Checkboxen
dies hier scheint zu passen:
http://www.purebasic.fr/english/viewtop ... 23#p360823
Grüße ... Kiffi
// Edit: Oh, sehe grade, dass das 2 ListIconGadgets sind...
// Edit2: Ah, nee, weiter unten ist ein Beispiel mit nur einem ListIconGadget
http://www.purebasic.fr/english/viewtop ... 23#p360823
Grüße ... Kiffi
// Edit: Oh, sehe grade, dass das 2 ListIconGadgets sind...
// Edit2: Ah, nee, weiter unten ist ein Beispiel mit nur einem ListIconGadget

a²+b²=mc²
Re: ListIconGadget mit 2 Checkboxen
Dankeschön
auch wenns 2 Gadgets sind.
Im unteren Beispiel sind 3 Gadgets, sieht aber eigentlich gut aus.

Im unteren Beispiel sind 3 Gadgets, sieht aber eigentlich gut aus.
- CodeCommander
- Beiträge: 213
- Registriert: 02.03.2014 16:06
Ist aba eine kontraproduktive Lösung weil zwei Gadgets erstellt werden. Es gibt keine direkte Verbindung der Datensätze mehr. Man muss sie immer getrennt hinzufügen. Und außerdem kann man den Spaltentrenner zwischen Spalte 1 und 2 nicht benutzen weils eben zwei Gadgets sind.
MFG CodeCommander
MFG CodeCommander
Zuletzt geändert von CodeCommander am 18.01.2015 14:24, insgesamt 1-mal geändert.
~ DELETE ~
Re: ListIconGadget mit 2 Checkboxen
Und genau deswegen, die Frage nach der Möglichkeit das in 1 Gadget zu bewerkstelligen 

- CodeCommander
- Beiträge: 213
- Registriert: 02.03.2014 16:06
Beschäftige dich mit Subclassing.
Im Forum gibt es Codes die du nehmen kannst.
MFG CodeCommander
Im Forum gibt es Codes die du nehmen kannst.
MFG CodeCommander
Zuletzt geändert von CodeCommander am 18.01.2015 14:25, insgesamt 1-mal geändert.
~ DELETE ~
Re: ListIconGadget mit 2 Checkboxen
Du koenntest es so machen, allerdings ist das etwas beschraenkt, so funktioniert z.B. kein SetGadgetItemColor mehr. Das muss man dann ebenfalls per Api machen.
Code: Alles auswählen
Enumeration Window
#WINDOW
EndEnumeration
Enumeration Gadget
#LIST
EndEnumeration
;Die Map, in der alle Checkboxenzustaende gespiechert werden
Global NewMap CheckListBoxMap.b()
Macro GetListViewCheckBoxState(Gadget, Item, SubItem)
CheckListBoxMap("" + GadgetID(Gadget) + ":" + Item + ":" + SubItem)
EndMacro
#PB_EventType_ChangeCheckBox = #PB_Event_FirstCustomValue
#SPALTENMITCHECKBOX = 2
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Procedure.i Callback(hWnd, uMsg, wParam, lParam)
Protected *dis.DRAWITEMSTRUCT
Protected text.s
Protected rc.RECT
Protected ColCount.i
Protected Header.i
Protected i.i, cx.i
Protected BackBrush.i
Protected *ia.NMITEMACTIVATE
Protected *lv.NMLISTVIEW
If uMsg = #WM_NOTIFY
*lv = lParam
;Eintraege in der Map loeschen
If *lv\hdr\idFrom = #LIST And *lv\hdr\code = #LVN_DELETEITEM
Header = SendMessage_(*lv\hdr\hwndFrom, #LVM_GETHEADER, 0, 0)
ColCount = SendMessage_(Header, #HDM_GETITEMCOUNT, 0, 0)
For i = 0 To ColCount - 1
;Alle Spalten aus der Map loeschen
DeleteMapElement(CheckListBoxMap(), "" + *lv\hdr\hwndFrom + ":" + *lv\iItem + i)
Next
EndIf
*ia = lParam
; Click in das Listview
If *ia\hdr\idFrom = #LIST And *ia\hdr\code = #NM_CLICK
If *ia\iSubItem < #SPALTENMITCHECKBOX ; nur die #SPALTENMITCHECKBOX werden abgefragt
rc\left = #LVIR_BOUNDS
SendMessage_(*ia\hdr\hwndFrom, #LVM_GETITEMRECT, *ia\iItem, rc)
For i = 0 To *ia\iSubItem - 1
cx + GetGadgetItemAttribute(*ia\hdr\idFrom, *ia\iItem, #PB_ListIcon_ColumnWidth, i)
Next
rc\left = cx + 2
rc\right = rc\left + 14
; Click in die Checkbox?
If PtInRect_(rc, PeekQ(*ia\ptAction))
;Checkboxstate scpeichern
CheckListBoxMap("" + *ia\hdr\hwndFrom + ":" + *ia\iItem + ":" + *ia\iSubItem) ! 1
;Neuzeichnen erzwingen
InvalidateRect_(*ia\hdr\hwndFrom, 0, 0)
;Event absondern
PostEvent(#PB_Event_Gadget, #PB_Ignore, *ia\hdr\idFrom, #PB_EventType_ChangeCheckBox)
EndIf
EndIf
EndIf
EndIf
If uMsg = #WM_DRAWITEM
*dis = lParam
If *dis\CtlID = #LIST And *dis\CtlType = #ODT_LISTVIEW
Header = SendMessage_(*dis\hwndItem, #LVM_GETHEADER, 0, 0)
ColCount = SendMessage_(Header, #HDM_GETITEMCOUNT, 0, 0) ; Spaltenanzahl
BackBrush = CreateSolidBrush_(GetSysColor_(#COLOR_HIGHLIGHT))
SetTextColor_(*dis\hdc, 0)
; alle Spalten durchlaufen
For i = 0 To ColCount - 1
rc\top = i
rc\left = #LVIR_BOUNDS
SendMessage_(*dis\hwndItem, #LVM_GETSUBITEMRECT, *dis\itemID, rc)
; Ist die Zeile selektiert?
If *dis\itemState & #ODS_SELECTED
FillRect_(*dis\hdc, rc, BackBrush)
SetTextColor_(*dis\hdc, GetSysColor_(#COLOR_HIGHLIGHTTEXT))
Else
SetTextColor_(*dis\hdc, GetSysColor_(#COLOR_WINDOWTEXT))
EndIf
rc\right = GetGadgetItemAttribute(*dis\CtlID, *dis\itemID, #PB_ListIcon_ColumnWidth, i) + rc\left
text = GetGadgetItemText(*dis\CtlID, *dis\itemID, i)
; ein wenig Luft in der Spalte
rc\left + 2
rc\right - 2
If i < #SPALTENMITCHECKBOX ; nur die #SPALTENMITCHECKBOX bekommen eine Checkbox !?
; Text verschieben
rc\left + 20
rc\right - 20
; Text zeichnen
DrawText_(*dis\hDC, text, -1, rc, #DT_SINGLELINE | #DT_VCENTER)
rc\left - 18
rc\right = rc\left + 14
; Checkboxstate abfragen und Checkbox zeichnen
If CheckListBoxMap("" + *dis\hwndItem + ":" + *dis\itemID + ":" + i)
DrawFrameControl_(*dis\hDC, rc, #DFC_BUTTON, #DFCS_BUTTONCHECK | #DFCS_CHECKED)
Else
DrawFrameControl_(*dis\hDC, rc, #DFC_BUTTON, #DFCS_BUTTONCHECK)
EndIf
Else
; Text ohne Checkbox zeichnen
DrawText_(*dis\hDC, text, -1, rc, #DT_SINGLELINE | #DT_VCENTER)
EndIf
Next
DeleteObject_(backbrush)
EndIf
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Procedure Main()
Protected Event.i
Protected i.i
If OpenWindow(#WINDOW, #PB_Ignore, #PB_Ignore, 505, 300, "")
ListIconGadget(#LIST, 0, 0, 505, 300, "Col0", 100, #LVS_OWNERDRAWFIXED|#PB_ListIcon_GridLines )
AddGadgetColumn(#LIST, 1, "Col1", 100)
AddGadgetColumn(#LIST, 2, "Col2", 100)
AddGadgetColumn(#LIST, 3, "Col3", 100)
AddGadgetColumn(#LIST, 4, "Col4", 100)
SetWindowCallback(@Callback(), 0)
For i = 0 To 13
AddGadgetItem(#LIST, i, "Col0" + #LF$ + "Col1" + #LF$ + "Col2" + #LF$ + "Col3" + #LF$ + "Col4")
Next
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Gadget
If EventType() = #PB_EventType_ChangeCheckBox
Debug GetListViewCheckBoxState(#LIST, 0, 1)
EndIf
EndIf
Until event = #PB_Event_CloseWindow
EndIf
EndProcedure: End Main()
Re: ListIconGadget mit 2 Checkboxen
Vielen Dank



- hjbremer
- Beiträge: 822
- Registriert: 27.02.2006 22:30
- Computerausstattung: von gestern
- Wohnort: Neumünster
Re: ListIconGadget mit 2 Checkboxen
Habe Edels Beispiel mal etwas aufgepeppt. Es ist immer noch ein Beispiel, da Save + Load fehlen, aber doch etwas flexibler.
Code: Alles auswählen
;Bitte beachten: Ab PB 5.30 (x86)
DeclareModule LvCheckbox
; Alle Elemente in diesem Abschnitt sind für den Zugriff von außerhalb verfügbar
EnableExplicit
#PB_EventType_ChangeCheckBox = #PB_Event_FirstCustomValue + 100
Declare.i LvCheckbox_SetColumn(gadget, col, datacol = #PB_Any)
Declare.i LvCheckBox_GetState(gadget, row, col)
Declare.i LvCheckbox_Callback(hWnd, msg, wParam, lParam)
EndDeclareModule
Module LvCheckbox
; TODO Colors in extra Prozedur
; TODO Save + load ?
; TODO Multiselect checked abfragen
;Allgemein
; Verschieben von Spalten wird nicht unterstützt.
; Anhängen von Spalten ist gestattet,
; da es egal ist welche Spalte den Status der Checkboxen aufnimmt.
; Warum gibt es eine Statusspalte ? Wegen Save/Load !
; Warum braucht man einen MainCallback ? Weil #WM_DRAWITEM nur ans Parentwindow gesendet wird
; und darum Subclassing des ListIcongadgets so einfach nicht geht.
EnableExplicit
Structure checkboxdata
datacolumn.i ;Spalte welche den Status der Checkbox(en) enthält
colornormal.i ;Text normal
colorchecked.i ;Text wenn Checkbox hat Haken
colorselected.i ;Text wenn Checkbox hat Haken und Zeile select
colorbackbrush.i ;Hintergrund wenn Zeile select
Array checkbox.i(0) ;Internes Feld, Index gleich Spalte und ist 1 = hat Checkbox
EndStructure
Procedure.i CheckBox_State(gadget, row, col)
Protected t$, state
Protected *ckb.checkboxdata = GetWindowLongPtr_(GadgetID(gadget), #GWL_USERDATA)
If *ckb\checkbox(col)
t$ = GetGadgetItemText(gadget, row, *ckb\datacolumn)
If Mid(t$, col+1, 1) = "1"
state = #True
Else
state = #False
EndIf
EndIf
ProcedureReturn state
EndProcedure
Procedure.i LvCheckBox_GetState(gadget, row, col)
Protected state, boxdata$
Protected *ckb.checkboxdata = GetWindowLongPtr_(GadgetID(gadget), #GWL_USERDATA)
If *ckb
If row > -1
boxdata$ = GetGadgetItemText(gadget, row, *ckb\datacolumn)
If Mid(boxdata$, col + 1, 1) = "1"
state = 1
EndIf
EndIf
EndIf
ProcedureReturn state
EndProcedure
Procedure.i CheckBox_SetState(gadget, row, col, state)
Protected t$, l$, r$
Protected *ckb.checkboxdata = GetWindowLongPtr_(GadgetID(gadget), #GWL_USERDATA)
Protected datalg = ArraySize(*ckb\checkbox()) + 1
If *ckb\checkbox(col)
t$ = GetGadgetItemText(gadget, row, *ckb\datacolumn)
t$ = LSet(t$, datalg, "-")
l$ = Left(t$, col)
r$ = Mid(t$, col+2)
If state = 1
t$ = l$ + "1" + r$
Else
t$ = l$ + "0" + r$
EndIf
SetGadgetItemText(gadget, row, t$, *ckb\datacolumn)
EndIf
EndProcedure
Procedure.i LvCheckbox_SetColumn(gadget, col, datacol = #PB_Any)
Protected *ckb.checkboxdata = GetWindowLongPtr_(GadgetID(gadget), #GWL_USERDATA)
;internes Mem
If *ckb = #False
*ckb = AllocateStructure(checkboxdata)
SetWindowLongPtr_(GadgetID(gadget), #GWL_USERDATA, *ckb)
EndIf
;weils einfacher ist, Array immer Redim
Protected header = SendMessage_(GadgetID(gadget), #LVM_GETHEADER, 0, 0)
Protected colanz = SendMessage_(header, #HDM_GETITEMCOUNT, 0, 0) - 1
ReDim *ckb\checkbox(colanz)
;diese Column bekommt eine Checkbox
*ckb\checkbox(col) = #True
;in diese Col kommt der DataString
If datacol = #PB_Any
*ckb\datacolumn = colanz ;letzte Column
Else
*ckb\datacolumn = datacol ;User definierte Col
EndIf
;könnte auch in einer extra Prozedur stehen
*ckb\colornormal = #Black
*ckb\colorchecked = #Blue
*ckb\colorselected = $C20000
*ckb\colorbackbrush = $FFBFBF
EndProcedure
Procedure.i LvCheckbox_Callback(hWnd, msg, wParam, lParam)
;Variablen allgemein
Protected pbnr ;Gadgetnr
Protected pbid ;GadgetID()
Protected item ;Row
Protected subitem ;Column
Protected rc.RECT ;Rechteck einer Zelle
Protected *ckb.checkboxdata ;Userdaten für die Checkboxen
;Variablen #WM_NOTIFY
Protected *nmia.NMITEMACTIVATE
;Variablen #WM_DRAWITEM
Protected text.s
Protected head
Protected cols
Protected backbrush
Protected cc.RECT
Protected *draw.DRAWITEMSTRUCT
Select msg
Case #WM_NOTIFY
;- WM_notify
*nmia = lParam
; Click in das Listview ?
If *nmia\hdr\code = #NM_CLICK
pbnr = *nmia\hdr\idFrom
pbid = *nmia\hdr\hwndFrom
item = *nmia\iItem
subitem = *nmia\iSubItem
If IsGadget(pbnr)
If GadgetType(pbnr) = #PB_GadgetType_ListIcon
;Userdata holen
*ckb = GetWindowLongPtr_(pbid, #GWL_USERDATA)
If *ckb
;hat Subitem eine Checkbox ?
If *ckb\checkbox(subitem) = #True
rc\top = subitem
rc\left = #LVIR_BOUNDS
SendMessage_(pbid, #LVM_GETSUBITEMRECT, item, rc)
rc\left + 4
rc\right = rc\left + 14
; Click in die Checkbox?
If PtInRect_(rc, PeekQ(*nmia\ptAction))
;CheckBox_State speichern
If CheckBox_State(pbnr, item, subitem) = 0
;auf 1 setzen
CheckBox_SetState(pbnr, item, subitem, 1)
Else
CheckBox_SetState(pbnr, item, subitem, 0)
EndIf
;Neuzeichnen erzwingen
InvalidateRect_(pbid, 0, 0)
;Event abschicken
PostEvent(#PB_Event_Gadget, #PB_Ignore, pbnr, #PB_EventType_ChangeCheckBox, subitem)
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
Case #WM_DRAWITEM
;- #WM_DRAWITEM
*draw = lParam
If *draw\CtlType = #ODT_LISTVIEW
pbnr = *draw\CtlID
pbid = *draw\hwndItem
item = *draw\itemID
subitem = 0
If IsGadget(pbnr)
If GadgetType(pbnr) = #PB_GadgetType_ListIcon
;Userdata holen
*ckb = GetWindowLongPtr_(pbid, #GWL_USERDATA)
If *ckb
backbrush = CreateSolidBrush_(*ckb\colorbackbrush)
head = SendMessage_(pbid, #LVM_GETHEADER, 0, 0)
cols = SendMessage_(head, #HDM_GETITEMCOUNT, 0, 0) ; Spaltenanzahl
; alle Spalten durchlaufen
For subitem = 0 To cols - 1
;Rect für Subitem bis Ende der Zeile ermitteln
rc\top = subitem
rc\left = #LVIR_BOUNDS
SendMessage_(pbid, #LVM_GETSUBITEMRECT, item, rc)
; Ist die Zeile selektiert? dann blauer Balken (backbrush)
If *draw\itemState & #ODS_SELECTED
FillRect_(*draw\hdc, rc, backbrush)
EndIf
;Right begrenzen für aktuelles Subitem
rc\right = rc\left + GetGadgetItemAttribute(*draw\CtlID, *draw\itemID, #PB_ListIcon_ColumnWidth, subitem)
;Text holen
text = GetGadgetItemText(pbnr, item, subitem)
; ein wenig Luft in der Spalte, jeweils für Text und Checkbox
rc\left + 4
rc\right - 4
CopyRect_(cc, rc)
;für Checkbox muß \right kleiner sein
cc\right = cc\left + 16
SetTextColor_(*draw\hdc, *ckb\colornormal)
If *ckb\checkbox(subitem) = #True ; nur die definierten Spalten bekommen eine Checkbox !
; CheckBox_State abfragen und Checkbox zeichnen
If CheckBox_State(*draw\CtlID, *draw\itemID, subitem) = #True
If *draw\itemState & #ODS_SELECTED
SetTextColor_(*draw\hdc, *ckb\colorselected)
Else
SetTextColor_(*draw\hdc, *ckb\colorchecked)
EndIf
DrawFrameControl_(*draw\hDC, cc, #DFC_BUTTON, #DFCS_BUTTONCHECK | #DFCS_CHECKED)
Else
DrawFrameControl_(*draw\hDC, cc, #DFC_BUTTON, #DFCS_BUTTONCHECK)
EndIf
; Text verschieben
rc\left + 20
; Text zeichnen
DrawText_(*draw\hDC, text, -1, rc, #DT_SINGLELINE | #DT_VCENTER)
Else
; Text ohne Checkbox zeichnen
DrawText_(*draw\hDC, text, -1, rc, #DT_SINGLELINE | #DT_VCENTER)
EndIf
Next
DeleteObject_(backbrush)
EndIf
EndIf
EndIf
EndIf
EndSelect
EndProcedure
EndModule
UseModule LvCheckbox
Enumeration Window
#window
EndEnumeration
Enumeration Gadget
#list
#list2
#button0
#button1
#button2
#button3
#button4
EndEnumeration
Procedure.i MainCallback(hWnd, msg, wParam, lParam)
LvCheckbox_Callback(hWnd, msg, wParam, lParam)
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure Main()
Protected j, event, rowlv1, rowlv2
If OpenWindow(#window, #PB_Ignore, #PB_Ignore, 999, 400, "")
SetWindowCallback(@MainCallback())
ButtonGadget(#button0, 11, 350, 89, 22, "Col 0")
ButtonGadget(#button1, 111, 350, 89, 22, "Col 1")
ButtonGadget(#button2, 211, 350, 89, 22, "Col 2")
ButtonGadget(#button3, 311, 350, 89, 22, "Col 3")
ButtonGadget(#button4, 411, 350, 89, 22, "Col 4")
ListIconGadget(#list, 5, 10, 650, 300, "Col0", 111, #LVS_OWNERDRAWFIXED|#PB_ListIcon_GridLines|#PB_ListIcon_MultiSelect )
AddGadgetColumn(#list, 1, "Col1", 111)
AddGadgetColumn(#list, 2, "Col2", 111)
AddGadgetColumn(#list, 3, "Col3", 111)
AddGadgetColumn(#list, 4, "Col4", 111)
AddGadgetColumn(#list, 5, "Data", 70)
LvCheckbox_SetColumn(#list, 1)
LvCheckbox_SetColumn(#list, 2)
LvCheckbox_SetColumn(#list, 4) ;oder LvCheckbox_SetColumn(#list, 4, 5) 5 steht für DataColumn
For j = 0 To 23
AddGadgetItem(#list, -1, "Col0" + #LF$ + "Col1" + #LF$ + "Col2" + #LF$ + "Col3" + #LF$ + "Col4" + #LF$ + "00101")
AddGadgetItem(#list, -1, "Col0" + #LF$ + "Col1" + #LF$ + "Col2" + #LF$ + "Col3" + #LF$ + "Col4" + #LF$ + "01100")
AddGadgetItem(#list, -1, "Col0" + #LF$ + "Col1" + #LF$ + "Col2" + #LF$ + "Col3" + #LF$ + "Col4" + #LF$ + "01001")
Next
ListIconGadget(#list2, 680, 10, 300, 300, "Col0", 66, #LVS_OWNERDRAWFIXED|#LVS_NOCOLUMNHEADER|#PB_ListIcon_GridLines|#PB_ListIcon_MultiSelect )
AddGadgetColumn(#list2, 1, "Col1", 95)
AddGadgetColumn(#list2, 2, "Col2", 115)
AddGadgetColumn(#list2, 3, "Data", 0)
LvCheckbox_SetColumn(#list2, 1)
LvCheckbox_SetColumn(#list2, 2)
For j = 0 To 23
AddGadgetItem(#list2, -1, "Hans" + #LF$ + "Eier" + #LF$ + "Bananen" + #LF$ + "001")
AddGadgetItem(#list2, -1, "Otto" + #LF$ + "Grünkohl" + #LF$ + "Äpfel" + #LF$ + "011")
AddGadgetItem(#list2, -1, "Werner" + #LF$ + "Käse" + #LF$ + "Birnen" + #LF$ + "010")
Next
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Gadget
rowlv1 = GetGadgetState(#list)
rowlv2 = GetGadgetState(#list2)
Select EventGadget()
Case #list
If EventType() = #PB_EventType_ChangeCheckBox
Debug "State ist jetzt " + LvCheckBox_GetState(#list, rowlv1, EventData())
EndIf
Case #list2
If EventType() = #PB_EventType_ChangeCheckBox
Debug "State ist jetzt " + LvCheckBox_GetState(#list2, rowlv2, EventData())
EndIf
Case #button0
Debug LvCheckBox_GetState(#list, rowlv1, 0)
Case #button1
Debug LvCheckBox_GetState(#list, rowlv1, 1)
Case #button2
Debug LvCheckBox_GetState(#list, rowlv1, 2)
Case #button3
Debug LvCheckBox_GetState(#list, rowlv1, 3)
Case #button4
Debug LvCheckBox_GetState(#list, rowlv1, 4)
EndSelect
EndIf
Until event = #PB_Event_CloseWindow
EndIf
EndProcedure
Main()
Purebasic 5.70 x86 5.72 X 64 - Windows 10
Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer