ListIconGadget - Mehrzeilige Einträge

Für allgemeine Fragen zur Programmierung mit PureBasic.
Christian
Beiträge: 73
Registriert: 31.08.2004 16:02

Beitrag von Christian »

Hallo!

Habe jetzt auch noch eine ganze Weile an dem Code herumgebastelt und nun ist es auch möglich Icons hinzuzufügen und MultiSelect funktioniert nun problemlos.

Code: Alles auswählen

; Author: Sparkie & Christian
; Date: 12. December 2004 


; Basics for drawing a custom multiline ListIconGadget 
; **************************************************** 
; You can specify wordwrap for each column as necessary. 
; Here I use wordwrap in Column 0 and single line with ellipsis (...) as needed. 

; Still To-Do list:
; ------------------
; Support #PB_ListIcon_CheckBoxes

; --> Constants 
#LVM_GETSUBITEMRECT = #LVM_FIRST + 56 
#LVM_GETEXTENDEDLISTVIEWSTYLE = #LVM_FIRST + 55
#LVS_EX_CHECKBOXES = $4
#LVS_SHOWSELALWAYS = $8

#DT_WORD_ELLIPSIS = $40000 
#DT_END_ELLIPSIS = $8000 
#DT_PATH_ELLIPSIS = $4000 
#DT_MODIFYSTRING = $10000 

#CDIS_CHECKED = 8 
#CDIS_DEFAULT = $20 
#CDIS_DISABLED = 4 
#CDIS_FOCUS = $10 
#CDIS_GRAYED = 2 
#CDIS_HOT = $40 
#CDIS_INDETERMINATE = $100 
#CDIS_MARKED = $80 
#CDIS_SELECTED = 1 
#CDIS_SHOWKEYBOARDCUES = $200 

#CDDS_ITEM = $10000 
#CDDS_MAPPART = 5 
#CDDS_POSTERASE = 4 
#CDDS_POSTPAINT = 2 
#CDDS_PREERASE = 3 
#CDDS_PREPAINT = 1 
#CDDS_ITEMPOSTERASE = #CDDS_ITEM | #CDDS_POSTERASE 
#CDDS_ITEMPOSTPAINT = #CDDS_ITEM | #CDDS_POSTPAINT 
#CDDS_ITEMPREERASE = #CDDS_ITEM | #CDDS_PREERASE 
#CDDS_ITEMPREPAINT = #CDDS_ITEM | #CDDS_PREPAINT 
#CDDS_SUBITEM = $20000 

#CDRF_DODEFAULT = 0 
#CDRF_NEWFONT = 2 
#CDRF_NOTIFYITEMDRAW = $20 
#CDRF_NOTIFYPOSTERASE = $40 
#CDRF_NOTIFYPOSTPAINT = $10 
#CDRF_NOTIFYSUBITEMDRAW = $20 
#CDRF_SKIPDEFAULT = 4 

#NO_ICON = -1

#IconID = 0

; --> Needed Variables
Global ImgListHnd.l

; --> Create assorted brushes for passing on to device context 
Dim brush(4) 

Enumeration 
  #C0Brush 
  #C1Brush 
  #C2Brush 
  #SelectedBrush
  #AlwaysSelectedBrush
EndEnumeration 

brush(#C0Brush) = CreateSolidBrush_(RGB(255, 155, 155))       ; column 0 brush 
brush(#C1Brush) = CreateSolidBrush_(RGB(155, 255, 155))       ; column 1 brush 
brush(#C2Brush) = CreateSolidBrush_(RGB(155, 155, 255))       ; column 2 brush 
brush(#SelectedBrush) = CreateSolidBrush_(RGB(255, 255, 155)) ; selected row brush 
brush(#AlwaysSelectedBrush) = CreateSolidBrush_(RGB(200, 200, 200)) ; AlwaysShowSelection row brush 

; --> Load Icon
LoadImage(#IconID, "Icon16.bmp") ; Specify your own path -> Image has to be 16*16 or 32*32 in size



; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;                      Procedures
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

; --> Get the Extended ListView Styles
Procedure GetExStyle(GadgetID)
  ProcedureReturn SendMessage_(GadgetID(GadgetID), #LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0)
EndProcedure

; --> Get the Styles of a Gadget
Procedure GetStyle(GadgetID)
  ProcedureReturn GetWindowLong_(GadgetID(GadgetID), #GWL_STYLE)
EndProcedure

; --> Windowcallback 
Procedure myWindowCallback(hwnd, msg, wparam, lparam) 
  result = #PB_ProcessPureBasicEvents 
  Select msg 
     Case #WM_NOTIFY 
      *nmhdr.NMHEADER = lparam 
      ; --> Lock column 0 width 
      If *nmhdr\hdr\code = #HDN_ITEMCHANGING  And *nmhdr\iItem = 0 
        result = #True 
      EndIf 
      *lvCD.NMLVCUSTOMDRAW = lparam 
      If *lvCD\nmcd\hdr\hwndFrom=GadgetID(0) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW    
        Select *lvCD\nmcd\dwDrawStage 
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT 
            result = #CDRF_NOTIFYSUBITEMDRAW; 
          Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM 
            thisItem = *lvCD\nmcd\dwItemSpec 
            ; --> Define rect for text 
            subItemRect.RECT\left = #LVIR_LABEL 
            subItemRect.RECT\top = *lvCD\iSubItem 
            ; --> Get the subitem rect 
            SendMessage_(GadgetID(0), #LVM_GETSUBITEMRECT, thisItem, @subItemRect) 
            subItemText$ = GetGadgetItemText(0, *lvCD\nmcd\dwItemSpec, *lvCD\iSubItem) 
            sitLen = Len(subItemText$)

            IconRect.RECT
            IconRect\left = #LVIR_ICON; 
            SendMessage_(GadgetID(0), #LVM_GETITEMRECT, thisItem, IconRect); 

            Select *lvCD\iSubItem 
              Case 0 
                ; --> Define text and background colors for column 0 and set Drawtext_() flags 
                lvFlags =  #DT_END_ELLIPSIS | #DT_WORDBREAK;| #DT_MODIFYSTRING 
                ; --> Paint over unused icon rect 
                subItemRect\left = 0
                If GetGadgetItemState(0, thisItem) & #PB_ListIcon_Selected And GetActiveWindow_() = hwnd
                  ; --> If item is selected, colorize column 0 
                  FillRect_(*lvCD\nmcd\hDC, subItemRect, brush(#SelectedBrush)) 
                ElseIf GetGadgetItemState(0, thisItem) & #PB_ListIcon_Selected And GetActiveWindow_() <> hwnd And GetFocus_() <> GadgetID(0) And GetStyle(0) & #PB_ListIcon_AlwaysShowSelection
                  ; --> If item is selected but gadget has no focus, colorize column 0 
                  FillRect_(*lvCD\nmcd\hDC, subItemRect, brush(#AlwaysSelectedBrush))                   
                Else
                  ; --> If item is not selected, colorize column 0 
                  FillRect_(*lvCD\nmcd\hDC, subItemRect, brush(#C0Brush)) 
                EndIf 
              ; --> Text color for column 0 
              SetTextColor_(*lvCD\nmcd\hDC, RGB(100, 0, 0)) 

              ; --> Draw Icon if there is one
              ImageList_GetIconSize_(ImgListHnd, @IconWidth, @IconHeight)
              ImageList_Draw_(ImgListHnd, thisItem, *lvCD\nmcd\hDC, IconRect\left, subitemrect\top, #ILD_TRANSPARENT)

              Case 1 
                ; --> Define text and background colors for column 1 and set Drawtext_() flags 
                lvFlags = #DT_END_ELLIPSIS | #DT_SINGLELINE | #DT_VCENTER 
                If GetGadgetItemState(0, thisItem) & #PB_ListIcon_Selected And GetActiveWindow_() = hwnd
                  ; --> If item is selected, colorize column 1
                  FillRect_(*lvCD\nmcd\hDC, subItemRect, brush(#SelectedBrush)) And GetActiveWindow_() <> hwnd And GetFocus_() <> GadgetID(0) And GetStyle(0) & #PB_ListIcon_AlwaysShowSelection
                ElseIf GetGadgetItemState(0, thisItem) & #PB_ListIcon_Selected
                  ; --> If item is selected but gadget has no focus, colorize column 1 
                  FillRect_(*lvCD\nmcd\hDC, subItemRect, brush(#AlwaysSelectedBrush))                   
                Else 
                  ; --> If item is not selected, colorize column 1 
                  FillRect_(*lvCD\nmcd\hDC, subItemRect, brush(#C1Brush)) 
                EndIf 
                ; --> Text color for column 1 
                SetTextColor_(*lvCD\nmcd\hDC, RGB(0, 100, 0)) 

              Case 2 
                ; --> Define text and background colors for column 2 and set Drawtext_() flags 
                lvFlags = #DT_END_ELLIPSIS | #DT_SINGLELINE | #DT_VCENTER 
                If GetGadgetItemState(0, thisItem) & #PB_ListIcon_Selected And GetActiveWindow_() = hwnd
                  ; --> If item is selected, colorize column 2
                  FillRect_(*lvCD\nmcd\hDC, subItemRect, brush(#SelectedBrush)) 
                ElseIf GetGadgetItemState(0, thisItem) & #PB_ListIcon_Selected And GetActiveWindow_() <> hwnd And GetFocus_() <> GadgetID(0) And GetStyle(0) & #PB_ListIcon_AlwaysShowSelection
                  ; --> If item is selected but gadget has no focus, colorize column 2
                  FillRect_(*lvCD\nmcd\hDC, subItemRect, brush(#AlwaysSelectedBrush))                   
                Else 
                  ; --> If item is not selected, colorize column 2
                  FillRect_(*lvCD\nmcd\hDC, subItemRect, brush(#C2Brush)) 
                EndIf 
                ; --> Text color for column x 
                SetTextColor_(*lvCD\nmcd\hDC, RGB(0, 0, 100)) 
            EndSelect 

            ; --> Adjust rect for text margins
            subItemRect\left + 5 + IconWidth
            subItemRect\right -3 
            subItemRect\bottom -3 
            ; --> Draw our text
            DrawText_(*lvCD\nmcd\hDC, subItemText$, sitLen, subItemRect, lvFlags) 
            result = #CDRF_SKIPDEFAULT 
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 


; --> Own AddGadgetItem for better handling of the ImagleList
Procedure.l AddGadgetItem_(GadgetID.l, Position.l, Text.s, ImageID.l)
ImgListHnd = SendMessage_(GadgetID(GadgetID), #LVM_GETIMAGELIST, #LVSIL_SMALL, 0)
; --> If there is no ImageList but an image that has to be drawn ...
If ImgListHnd = 0  And ImageID <> -1
    ; --> ... create ImageList ...
    ImgListHnd = ImageList_Create_(32, 32, #ILC_COLORDDB|#ILC_MASK, 0, 0)
    SendMessage_(GadgetID(GadgetID), #LVM_SETIMAGELIST, #LVSIL_SMALL, ImgListHnd)

    ; -- ... check whether image is 16*16 or 32*32 ...
    UseImage(ImageID) : ImageWidth = ImageWidth() : ImageHeight = ImageHeight()
    ; --> ... if 16*16, set size to 32*32 and centre picture ...
    If ImageWidth = 16 And ImageHeight = 16
        CreateImage(ImageID + 1, 32, 32)
        If StartDrawing(ImageOutput())
            Box(0, 0, 32, 32, $000000)
            DrawImage(UseImage(ImageID), 16/2, 16/2)
            StopDrawing()
        EndIf
        ImageID = UseImage(ImageID + 1)
    ElseIf ImageWidth = 32 And ImageHeight = 32
        ImageID = UseImage(ImageID)
    EndIf

    If ImgListHnd
        ; --> ... and add item to ListIconGadget and transparent image to its ImageList
        AddGadgetItem(GadgetID, Position, Text) : ImageList_AddMasked_(ImgListHnd, ImageID, $000000)
    EndIf


; --> If there is an ImageList and an image that has to be drawn ...
ElseIf ImgListHnd And ImageID <> -1
    ; -- ... check whether image is 16*16 or 32*32 ...
    UseImage(ImageID) : ImageWidth = ImageWidth() : ImageHeight = ImageHeight()
    ; --> ... if 16*16, set size to 32*32 and centre picture ...
    If ImageWidth = 16 And ImageHeight = 16
        CreateImage(ImageID + 1, 32, 32)
        If StartDrawing(ImageOutput())
            Box(0, 0, 32, 32, $000000)
            DrawImage(UseImage(ImageID), 16/2, 16/2)
            StopDrawing()
        EndIf
        ImageID = UseImage(ImageID + 1)
    ElseIf ImageWidth = 32 And ImageHeight = 32
        ImageID = UseImage(ImageID)
    EndIf

        ; --> ... and add item to ListIconGadget and transparent image to its ImageList
    AddGadgetItem(GadgetID, Position, Text) : ImageList_AddMasked_(ImgListHnd, ImageID, $000000)


; --> If there is no ImageList and no image that has to be drawn ...
ElseIf ImgListHnd = 0 And ImageID = -1
    ; --> ... create ImageList for having two rows possible ...
    ImgListHnd = ImageList_Create_(1, 32, #ILC_COLORDDB|#ILC_MASK, 0, 0)
    SendMessage_(GadgetID(GadgetID), #LVM_SETIMAGELIST, #LVSIL_SMALL, ImgListHnd)

    If ImgListHnd
        ; --> ... and add item to ListIconGadget without image
        AddGadgetItem(GadgetID, Position, Text); : ImageList_AddMasked_(ImgListHnd, ImageID, $000000)
    EndIf


; --> If there is an ImageList and no image that has to be drawn ...
ElseIf ImgListHnd And ImageID = -1
    ; --> ... add item to ListIconGadget without image
    AddGadgetItem(GadgetID, Position, Text)
EndIf

ProcedureReturn ImgListHnd
EndProcedure


; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;                        Main
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If OpenWindow(0, 0, 0, 500, 260,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Sparkies Multiline ListIconGadget") And CreateGadgetList(WindowID(0)) 
  CreateStatusBar(0, WindowID(0)) 
  ListIconGadget(0, 10, 10, 490, 225, "Column 0", 170, #PB_ListIcon_FullRowSelect | #PB_ListIcon_MultiSelect | #PB_ListIcon_AlwaysShowSelection)
    AddGadgetColumn(0, 1, "Column 1", 150) 
    AddGadgetColumn(0, 2, "Column 2", 150) 

  For a=0 To 9 
    addtext$ = "Locked Column 0 item #" + Str(a) + Chr(13) + "on 2 lines of text." + Chr(10) + "Column 1 item #" + Str(a) + " on 1 line" + Chr(10) + "Column 2 item #" + Str(a) + " on 1 line" 
    atLen = Len(addtext$) 
    AddGadgetItem_(0, a, addtext$, #IconID) ; last Parameter has to be #NO_ICON if you don't want to draw an icon 
                                            ; else the #ImageID of your image
  Next
  SetWindowCallback(@myWindowCallback())     

  Repeat 
    event = WaitWindowEvent() 
    Select event 
      Case #PB_EventGadget 
        Select EventGadgetID() 
          Case 0 
            ; --> Display selected ListIconGadget index in statusbar 
            StatusBarText(0, 0, "Selected item index is: " + Str(GetGadgetState(0)))
        EndSelect 
    EndSelect 
  Until event = #PB_Event_CloseWindow 
EndIf 
End 
Antworten