ListIconGadget multi-row column title possible?

Everything else that doesn't fall into one of the other PB categories.
dfmurray99
New User
New User
Posts: 3
Joined: Tue Dec 08, 2009 10:55 pm

ListIconGadget multi-row column title possible?

Post 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.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: ListIconGadget multi-row column title possible?

Post 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
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: ListIconGadget multi-row column title possible?

Post 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
Last edited by srod on Wed Dec 09, 2009 12:32 pm, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: ListIconGadget multi-row column title possible?

Post 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

I may look like a mule, but I'm not a complete ass.
dfmurray99
New User
New User
Posts: 3
Joined: Tue Dec 08, 2009 10:55 pm

Re: ListIconGadget multi-row column title possible?

Post by dfmurray99 »

Thanks for information guys!

I'll put something together along those lines.
Post Reply