Page 1 of 1

ListIconGadget multi-row column title possible?

Posted: Tue Dec 08, 2009 11:06 pm
by dfmurray99
Is it possible (under pb 4.20) for the column heading in a listicongadget to allow a multiple line heading?

I've tried chr(13)+Chr(10) as one would do with a buttongadget, but that does not work and I have not been able to find any refrence to it on the forum.

Re: ListIconGadget multi-row column title possible?

Posted: Wed Dec 09, 2009 5:36 am
by netmaestro
It can be done, however not quite that easily. You have to:

1) Adjust the header height larger to accomodate two lines of text
2) Subclass the header so it defends itself against attempts to alter its size
3) Ownerdraw the header control
4) Put a dummy first item in the ListIcon gadget to take up the extra header space; Your first item will always be 1 now

Anyway, with those considerations in mind, here's a sample. It's really not as much work as it sounds:

Code: Select all

Procedure HDProc(hwnd, msg, wparam, lparam)
  oldproc = GetProp_(hwnd, "oldproc")
  Select msg
    Case #WM_NCDESTROY
      RemoveProp_(hwnd, "oldproc")
    
    Case #WM_WINDOWPOSCHANGING 
      *wp.WINDOWPOS = lparam
      With *wp
        \cx=300
        \cy=32
      EndWith
      ProcedureReturn 0
      
  EndSelect
  
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
EndProcedure

Procedure LVProc(hwnd, msg, wparam, lparam)
  oldproc = GetProp_(hwnd, "oldproc")
  Select msg
    Case #WM_NCDESTROY
      RemoveProp_(hwnd, "oldproc")
    
    Case #WM_DRAWITEM
      
      *dis.DRAWITEMSTRUCT = lparam
      
      If *dis\itemstate
        DrawFrameControl_(*dis\hdc,*dis\rcItem,#DFC_BUTTON, #DFCS_BUTTONPUSH|#DFCS_PUSHED)
        bot=17
      Else
        DrawFrameControl_(*dis\hdc,*dis\rcItem,#DFC_BUTTON, #DFCS_BUTTONPUSH) 
        bot=16
      EndIf
      
      Select *dis\itemID
        Case 0
          TextOut_(*dis\hdc, *dis\rcItem\left+30, bot-14, "George", Len("George"))
          TextOut_(*dis\hdc, *dis\rcItem\left+36, bot, "Bush", Len("Bush"))
        Case 1
          TextOut_(*dis\hdc, *dis\rcItem\left+40, bot-14, "Bill", Len("Bill"))
          TextOut_(*dis\hdc, *dis\rcItem\left+30, bot, "Clinton", Len("Clinton"))
        Case 2
          TextOut_(*dis\hdc, *dis\rcItem\left+32, bot-14, "Albert", Len("Albert"))
          TextOut_(*dis\hdc, *dis\rcItem\left+34, bot, "Gore", Len("Gore"))
      
      EndSelect
      
      ProcedureReturn 1
  EndSelect
  
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
EndProcedure

OpenWindow(0,0,0,500,400,"Multiline Listview Header",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ListIconGadget(0,30,30,300,300,"",100,#PB_ListIcon_GridLines)
SetProp_(GadgetID(0),"oldproc",SetWindowLongPtr_(GadgetID(0),#GWL_WNDPROC,@LVProc()))
AddGadgetColumn(0,1,"",98)
AddGadgetColumn(0,2,"",98)
AddGadgetItem(0, 0, Chr(10)+Chr(10)) ; dummy gadget item to use extra header space
AddGadgetItem(0, -1, "Huh? What?"+Chr(10)+"I didn't have sex!"+Chr(10)+"The sky is falling!")

header = SendMessage_(GadgetID(0),#LVM_GETHEADER,0,0)
SetProp_(header,"oldproc",SetWindowLongPtr_(header,#GWL_WNDPROC,@HDProc()))
SetWindowPos_(header,0,0,0,300,32,0)

item.HD_ITEM\mask = #HDI_FORMAT

For i=0 To 2
  SendMessage_(header, #HDM_GETITEM, i, @item)
  item\fmt = #HDF_OWNERDRAW 
  SendMessage_(header, #HDM_SETITEM, i, @item)
Next

Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow

Re: ListIconGadget multi-row column title possible?

Posted: Wed Dec 09, 2009 11:05 am
by srod
On Vista, the resized header eats into the rows of the ListIcon Netmaestro.

I find that it is better to process the #HDM_LAYOUT message.

Code: Select all

Procedure HDProc(hwnd, msg, wparam, lparam)
  Protected *hdlayout.HD_LAYOUT, *rect.RECT, *windowpos.WINDOWPOS

  oldproc = GetProp_(hwnd, "oldproc")
  Select msg
    Case #WM_NCDESTROY
      RemoveProp_(hwnd, "oldproc")
    
    Case #HDM_LAYOUT
      result = CallWindowProc_(oldProc, hwnd, msg, wParam, lParam) 
      *hdlayout = lParam 
      If *hdlayout\prc <> 0 
        *rect = *hdlayout\prc 
        *rect\top = 32
      EndIf 
      If *hdlayout\pwpos <> 0 
        *windowpos = *hdlayout\pwpos 
        *windowpos\cy = 32
      EndIf 

    Default
      result = CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)

  EndSelect
  
  ProcedureReturn result
EndProcedure

Procedure LVProc(hwnd, msg, wparam, lparam)
  oldproc = GetProp_(hwnd, "oldproc")
  Select msg
    Case #WM_NCDESTROY
      RemoveProp_(hwnd, "oldproc")
    

    Case #WM_DRAWITEM
      
      *dis.DRAWITEMSTRUCT = lparam
      
      If *dis\itemstate
        DrawFrameControl_(*dis\hdc,*dis\rcItem,#DFC_BUTTON, #DFCS_BUTTONPUSH|#DFCS_PUSHED)
        bot=17
      Else
        DrawFrameControl_(*dis\hdc,*dis\rcItem,#DFC_BUTTON, #DFCS_BUTTONPUSH) 
        bot=16
      EndIf
      
      Select *dis\itemID
        Case 0
          TextOut_(*dis\hdc, *dis\rcItem\left+30, bot-14, "George", Len("George"))
          TextOut_(*dis\hdc, *dis\rcItem\left+36, bot, "Bush", Len("Bush"))
        Case 1
          TextOut_(*dis\hdc, *dis\rcItem\left+40, bot-14, "Bill", Len("Bill"))
          TextOut_(*dis\hdc, *dis\rcItem\left+30, bot, "Clinton", Len("Clinton"))
        Case 2
          TextOut_(*dis\hdc, *dis\rcItem\left+32, bot-14, "Albert", Len("Albert"))
          TextOut_(*dis\hdc, *dis\rcItem\left+34, bot, "Gore", Len("Gore"))
      
      EndSelect
      
      ProcedureReturn 1
  EndSelect
  
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
EndProcedure

OpenWindow(0,0,0,500,400,"Multiline Listview Header",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ListIconGadget(0,30,30,300,300,"",100,#PB_ListIcon_GridLines)
SetProp_(GadgetID(0),"oldproc",SetWindowLongPtr_(GadgetID(0),#GWL_WNDPROC,@LVProc()))
AddGadgetColumn(0,1,"",98)
AddGadgetColumn(0,2,"",98)
AddGadgetItem(0, -1, "Huh? What?"+Chr(10)+"I didn't have sex!"+Chr(10)+"The sky is falling!")

header = SendMessage_(GadgetID(0),#LVM_GETHEADER,0,0)
SetProp_(header,"oldproc",SetWindowLongPtr_(header,#GWL_WNDPROC,@HDProc()))
SetWindowPos_(header,0,0,0,300,32,0)

item.HD_ITEM\mask = #HDI_FORMAT

For i=0 To 2
  SendMessage_(header, #HDM_GETITEM, i, @item)
  item\fmt = #HDF_OWNERDRAW 
  SendMessage_(header, #HDM_SETITEM, i, @item)
Next

Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow

Re: ListIconGadget multi-row column title possible?

Posted: Wed Dec 09, 2009 12:16 pm
by srod
Here's one using Custom draw :

Code: Select all

Procedure HDProc(hwnd, uMsg, wparam, lparam)
  Protected *hdlayout.HD_LAYOUT, *rect.RECT, *windowpos.WINDOWPOS
  oldproc = GetProp_(hwnd, "oldproc")
  Select uMsg
    Case #WM_NCDESTROY
      RemoveProp_(hwnd, "oldproc")
    Case #HDM_LAYOUT                                 
      result = CallWindowProc_(oldProc, hwnd, uMsg, wparam, lparam) 
      *hdlayout = lParam 
      If *hdlayout\prc <> 0 
        *rect = *hdlayout\prc 
        *rect\top = 40
      EndIf 
      If *hdlayout\pwpos <> 0 
        *windowpos = *hdlayout\pwpos 
        *windowpos\cy = 40
      EndIf 
    Default
      result = CallWindowProc_(oldproc, hwnd, uMsg, wparam, lparam)
  EndSelect
  ProcedureReturn result
EndProcedure

Procedure LVProc(hwnd, msg, wparam, lparam)
  Protected result, *nmh.NMHDR, *pnmcd.NMCUSTOMDRAW, text$, rc.RECT
  oldproc = GetProp_(hwnd, "oldproc")
  Select msg
    Case #WM_NCDESTROY
      RemoveProp_(hwnd, "oldproc")
      result = CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
    Case #WM_NOTIFY
      *nmh = lParam
      Select *nmh\code
        Case #NM_CUSTOMDRAW
          *pnmcd = lParam 
          Select *pnmcd\dwDrawStage 
            Case #CDDS_PREPAINT 
              result = #CDRF_NOTIFYITEMDRAW 
            Case #CDDS_ITEMPREPAINT 
              text$=GetGadgetItemText(*pnmcd\hdr\idFrom,-1,*pnmcd\dwItemSpec)
              If *pnmcd\uItemState & #CDIS_SELECTED
                DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH|#DFCS_PUSHED)
                *pnmcd\rc\top-2
                *pnmcd\rc\left+1
              Else
                DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH)
              EndIf
              InflateRect_(*pnmcd\rc, -6, 0)
              CopyMemory(*pnmcd\rc, rc, SizeOf(RECT))
              DrawText_(*pnmcd\hdc, @text$, Len(text$), rc, #DT_WORDBREAK|#DT_END_ELLIPSIS|#DT_CALCRECT|#DT_NOPREFIX|#DT_END_ELLIPSIS|#DT_CENTER)
              *pnmcd\rc\top = (*pnmcd\rc\bottom - rc\bottom)>>1
              *pnmcd\rc\bottom = *pnmcd\rc\top + rc\bottom
              DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_WORDBREAK|#DT_END_ELLIPSIS|#DT_NOPREFIX|#DT_END_ELLIPSIS|#DT_CENTER)
              result = #CDRF_SKIPDEFAULT
          EndSelect
        Default
          result = CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
      EndSelect
    Default
      result = CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
  EndSelect
  
  ProcedureReturn result
EndProcedure

OpenWindow(0,0,0,500,400,"Multiline Listview Header",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ListIconGadget(0,30,30,300,300,"George" + #LF$+ "Bush",100,#PB_ListIcon_GridLines)
SetProp_(GadgetID(0),"oldproc",SetWindowLongPtr_(GadgetID(0),#GWL_WNDPROC,@LVProc()))
AddGadgetColumn(0,1,"Bill" + #LF$ + "Clinton",98)
AddGadgetColumn(0,2,"Albert" + #LF$ +"Gore",98)
AddGadgetItem(0, -1, "Huh? What?"+Chr(10)+"I didn't have sex!"+Chr(10)+"The sky is falling!")

header = SendMessage_(GadgetID(0),#LVM_GETHEADER,0,0)
SetProp_(header,"oldproc",SetWindowLongPtr_(header,#GWL_WNDPROC,@HDProc()))

Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow


Re: ListIconGadget multi-row column title possible?

Posted: Wed Dec 09, 2009 6:49 pm
by dfmurray99
Thanks for information guys!

I'll put something together along those lines.