Seite 1 von 1

jede 2.Zeile grau im Listicongadget mit NM_CUSTOMDRAW

Verfasst: 22.03.2012 23:22
von hjbremer
jede 2. Zeile grau im LV machen die meisten siche mit SetGadgetItemColor().

Mit NM_CUSTOMDRAW geht es ca 10% schneller und das macht bei großen Listen schon was aus.

Code: Alles auswählen

XIncludeFile "\Bremer\PureBasicPbi\DebugMacros.pbi"

EnableExplicit

Enumeration
   #win
   #bt1
   #bt2
   #lv1
EndEnumeration

LoadFont(1,"ARIAL", 11)
LoadFont(2,"ARIAL", 10, #PB_Font_Bold)

Procedure WinCallback(hWnd, msg, wParam, lParam) 
   
   Protected result = #PB_ProcessPureBasicEvents 
   
   Protected j, iitem, isubitem
   Protected *nmhdr.NMHDR
   Protected *nmlistview.NM_LISTVIEW
   Protected *nmlvcustomdraw.NMLVCUSTOMDRAW 
   
   Select msg 
      Case #WM_NOTIFY 
         
         *nmhdr = lParam
         *nmlistview = lParam
         *nmlvcustomdraw = lParam
         
         If *nmhdr\idFrom = #lv1 
            If *nmhdr\code = #NM_CUSTOMDRAW
                
               Select *nmlvcustomdraw\nmcd\dwDrawStage 
                  Case #CDDS_PREPAINT:     result = #CDRF_NOTIFYITEMDRAW 
                  Case #CDDS_ITEMPREPAINT: result = #CDRF_NOTIFYSUBITEMDRAW 
                  Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
                     iitem = *nmlvcustomdraw\nmcd\dwItemSpec ;:Debug iitem
                     isubitem = *nmlvcustomdraw\iSubItem         
                     ;Standard
                     *nmlvcustomdraw\clrTextBk = #White
                     ;jede 2.Zeile grau
                     If Mod(iitem,2): *nmlvcustomdraw\clrTextBk = $f0f0f0: EndIf
                     
                     ;bei Bedarf
                     Select isubitem
                        Case 0
                           *nmlvcustomdraw\clrText = #Black
                           SelectObject_(*nmlvcustomdraw\nmcd\hDC, FontID(2)) 
                        Case 1 
                           *nmlvcustomdraw\clrText = #Red
                           SelectObject_(*nmlvcustomdraw\nmcd\hDC, FontID(1)) 
                        Case 3
                           *nmlvcustomdraw\clrText = #Green
                           SelectObject_(*nmlvcustomdraw\nmcd\hDC, FontID(2))
                           If Val(GetGadgetItemText(#lv1, iitem, 3)) < 80
                              *nmlvcustomdraw\clrText = #Magenta
                           EndIf   
                        Default
                           *nmlvcustomdraw\clrText = #Blue
                           SelectObject_(*nmlvcustomdraw\nmcd\hDC, FontID(1))                
                     EndSelect
                     
                     result = #CDRF_NEWFONT 
               EndSelect 
               
            ElseIf *nmlistview\hdr\code = #LVN_DELETEITEM
               j = SendMessage_(*nmlistview\hdr\hwndFrom, #LVM_GETCOUNTPERPAGE, 0, 0)
               SendMessage_(*nmlistview\hdr\hwndFrom, #LVM_REDRAWITEMS, *nmlistview\iItem, *nmlistview\iItem + j)
            EndIf   
            
         EndIf
         
   EndSelect 
   
   ProcedureReturn result 
EndProcedure 

Define flag, j, a$, event, wb, idx

Dim subitem$(3)
subitem$(0) = "Meier" + #LF$ + "Berlin" + #LF$ + "83" 
subitem$(1) = "Bremer" + #LF$ + "Hamburg" + #LF$ + "74" 
subitem$(2) = "Müller" + #LF$ + "Bremen" + #LF$ + "92" 
subitem$(3) = "Schulze" + #LF$ + "München" + #LF$ + "67" 

OpenWindow(#win, 50, 100, 555, 540, "Test", #PB_Window_SystemMenu) 

SetWindowCallback(@WinCallback()) 

ButtonGadget(#bt1, 10, 510, 80, 20,"add")
ButtonGadget(#bt2, 90, 510, 80, 20,"del")

flag = #PB_ListIcon_GridLines
flag | #PB_ListIcon_FullRowSelect
flag | #PB_ListIcon_AlwaysShowSelection
flag | #PB_ListIcon_MultiSelect

ListIconGadget(#lv1, 14, 14, 500, 455, "Sp 0", 50, flag)
AddGadgetColumn(#lv1, 1, "Sp 1", 180)
AddGadgetColumn(#lv1, 2, "Sp 2", 180)
AddGadgetColumn(#lv1, 3, "Sp 3", 65)
SetGadgetFont(#lv1, FontID(1))

HideGadget(#lv1, 1)
For j = 0 To 1000
   a$ = Str(j) + #LF$ + subitem$(Random(3))
   AddGadgetItem(#lv1, -1, a$)
Next
HideGadget(#lv1, 0)

SetGadgetItemState(#lv1, 1, #PB_ListIcon_Selected)
SetActiveGadget(#lv1)

Repeat: event = WaitWindowEvent() 
   
   If event = #PB_Event_Gadget Or event = #PB_Event_Menu 
      
      wB = EventGadget()        
      Select wB
         Case #bt1
            idx = GetGadgetState(#lv1)
            AddGadgetItem(#lv1, idx, "add " + a$)
            SetActiveGadget(#lv1)
            
         Case #bt2
            idx = GetGadgetState(#lv1)
            RemoveGadgetItem(#lv1, idx)            
            SetGadgetItemState(#lv1, idx, #PB_ListIcon_Selected)
            SetActiveGadget(#lv1)
                                    
      EndSelect
      
   EndIf
   
Until event = #PB_Event_CloseWindow

End 

Re: jede 2.Zeile grau im Listicongadget mit NM_CUSTOMDRAW

Verfasst: 23.03.2012 22:41
von NicknameFJ
Danke HJBremer,

ich kenne mich mit dem API Zeuchs nicht so gut aus.

Wollte aber gerade sowas basteln um die Zeilen einzufärben damit man beim Lesen der Daten nicht in der Zeile verrutscht.

Hat mir viel Arbeit erspart. Danke

Grüße

NicknameFJ

Re: jede 2.Zeile grau im Listicongadget mit NM_CUSTOMDRAW

Verfasst: 24.03.2012 15:33
von NicknameFJ
Hallo zusammen,

Ich würde gern nicht nur die einzelnen Reihen einfärben, dass klappt ja mit obigen Code sehr gut, sondern auch die jeweils selektierte Reihe(n) einfärben.


[EDIT] Habe im englischen Forum einen Code von Sparkie gefunden der die selektierten Einträge im ListIconGadget in beliebiger Farbe darstellt. Für Alle die es gebrauchen können.

Code: Alles auswählen

#LVS_EX_CHECKBOXES = 4

;... Create brushes for painting item background
Structure MYBRUSHES
  brushDefault.l
  brushFocus.l
  brushSelected.l
EndStructure

Global brush.MYBRUSHES

brush\brushSelected = CreateSolidBrush_(RGB(128, 255, 128))
brush\brushFocus = CreateSolidBrush_(RGB(200, 255, 200))
brush\brushDefault = GetStockObject_(#WHITE_BRUSH)


Procedure myWindowCallback(hwnd, msg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents
  Select msg
    Case #WM_NOTIFY
      *nmhdr.NMHDR = lParam
      *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
            thisRow = *lvCD\nmcd\dwItemSpec
            thisCol = *lvCD\iSubItem
           
            ;... Draw checkboxes as needed
            exStyle = SendMessage_(*lvCD\nmcd\hdr\hwndFrom, #LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0)
            If thisCol = 0 And exStyle & #LVS_EX_CHECKBOXES
              stateList = SendMessage_(*lvCD\nmcd\hdr\hwndFrom, #LVM_GETIMAGELIST, #LVSIL_STATE, 0)
              ckState = SendMessage_(*lvCD\nmcd\hdr\hwndFrom, #LVM_GETITEMSTATE, thisRow, #LVIS_STATEIMAGEMASK) >>12 -1
              checkRect.RECT\left = #LVIR_ICON
              checkRect.RECT\top = 0
              SendMessage_(*lvCD\nmcd\hdr\hwndFrom, #LVM_GETITEMRECT, thisRow, @checkRect)
              ImageList_Draw_(stateList, ckState, *lvCD\nmcd\hdc, 0, checkRect\top, #ILD_TRANSPARENT)
            EndIf
            ;... Define rect for text
            subItemRect.RECT\left = #LVIR_LABEL
            subItemRect.RECT\top = *lvCD\iSubItem
            ;... Get the subitem rect
            SendMessage_(*lvCD\nmcd\hdr\hwndFrom, #LVM_GETSUBITEMRECT, thisRow, @subItemRect)
            subItemText$ = GetGadgetItemText(0, thisRow, thisCol)
            If GetGadgetItemState(*lvCD\nmcd\hdr\idFrom, thisRow) & #PB_ListIcon_Selected And GetFocus_() <> *lvCD\nmcd\hdr\hwndFrom
              FillRect_(*lvCD\nmcd\hdc, subItemRect, brush\brushFocus)
            ElseIf GetGadgetItemState(*lvCD\nmcd\hdr\idFrom, thisRow) & #PB_ListIcon_Selected And GetFocus_() = *lvCD\nmcd\hdr\hwndFrom
              FillRect_(*lvCD\nmcd\hdc, subItemRect, brush\brushSelected)
            Else
              FillRect_(*lvCD\nmcd\hdc, subItemRect, brush\brushDefault)
            EndIf
            ;.. Set left margin
            subItemRect\left + 3
            DrawText_(*lvCD\nmcd\hdc, subItemText$, Len(subItemText$), subItemRect, #DT_WORD_ELLIPSIS | #DT_SINGLELINE | #DT_VCENTER)
            result = #CDRF_SKIPDEFAULT
        EndSelect
      EndIf
  EndSelect
  ProcedureReturn result
EndProcedure

If OpenWindow(0, 0, 0, 480, 260, "Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
  SetWindowCallback(@myWindowCallback())
  ListIconGadget(0, 10, 10, 470, 225, "Column 0", 150, #PB_ListIcon_CheckBoxes | #PB_ListIcon_FullRowSelect | #PB_ListIcon_GridLines | #PB_ListIcon_MultiSelect | #PB_ListIcon_AlwaysShowSelection)
  AddGadgetColumn(0, 1, "Column 1", 150)
  For a = 0 To 9
    addtext$ = "Column 0 Item " + Str(a) + Chr(10) + "Column 1 Item " + Str(a)
    atLen = Len(addtext$)
    AddGadgetItem(0,-1, addtext$)
  Next
  Repeat
    event = WaitWindowEvent()
  Until event = #PB_Event_CloseWindow
  DeleteObject_(brush\brushSelected)
  DeleteObject_(brush\brushFocus)
 
EndIf
End 
NicknameFJ