Colouring a ListIconGadget header

Just starting out? Need help? Post your questions and find answers here.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Hi Fangles...I threw this together while you were asleep. 3 subclassed ListIconGadgets working off 1 callback. :)

All 3 headers should display white text on a blue background.

Code: Select all

#LVM_GETHEADER = #LVM_FIRST + 31

;...Used in subclass ProceduReturn = result
Global AddressCallback

;...Blue brush for header background color
Global Colour = CreateSolidBrush_(#Blue)

;...Subclass procedure for all 3 ListIconGadgets
Procedure AddressListSubclassed(hwnd, msg, wParam, lParam) 
  Protected hdi.HD_ITEM 
  result = CallWindowProc_(AddressCallback, hwnd, msg, wParam, lParam); Used for my first gadget 
  Select msg 
    Case #WM_NOTIFY 
      *pnmh.NMHDR = lParam       
       If *pnmh\code = #NM_CUSTOMDRAW 
        *pnmcd.NMCUSTOMDRAW = lParam                                                                  ; Determine drawing stage 
        Select *pnmcd\dwDrawStage 
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT                                                                     ; Get header text. 
            text$ = Space(100) 
            hdi\mask = #HDI_TEXT 
            hdi\pszText = @text$ 
            hdi\cchTextMax = Len(text$) 
            SendMessage_(*pnmh\hwndFrom, #HDM_GETITEM, *pnmcd\dwItemSpec, hdi)                     ; Check button state. 
            If *pnmcd\uItemState & #CDIS_SELECTED 
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH | #DFCS_PUSHED)  ; Offset text because of the selected button. 
              InflateRect_(*pnmcd\rc, -1, -1) 
            Else 
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH) 
            EndIf                      
                                                               
            ; Draw background.
            InflateRect_(*pnmcd\rc, -1, -1) 
            SetBkMode_(*pnmcd\hdc, #TRANSPARENT) 
            ;If *pnmcd\dwItemSpec & 1 
            FillRect_(*pnmcd\hdc, *pnmcd\rc, Colour) 
            SetTextColor_(*pnmcd\hdc, #White) 
            ;Else 
            ;  FillRect_(*pnmcd\hdc, *pnmcd\rc, Colour) 
            ;  SetTextColor_(*pnmcd\hdc, $000000) 
            ;EndIf 
            DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_LEFT | #DT_VCENTER | #DT_END_ELLIPSIS) 
            result = #CDRF_SKIPDEFAULT 
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 



If OpenWindow(0, 100, 100, 300, 300, "ListIcon Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If CreateGadgetList(WindowID(0))
    ListIconGadget(0, 5, 5, 290, 90, "Name", 100, #PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection)
    AddGadgetColumn(0, 1, "Address", 250)
    AddGadgetItem(0, -1, "Harry Rannit"+Chr(10)+"12 Parliament Way, Battle Street, By the Bay")
    AddGadgetItem(0, -1, "Ginger Brokeit"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity")
    
    ListIconGadget(1, 5, 105, 290, 90, "Name", 100, #PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection)
    AddGadgetColumn(1, 1, "Address", 250)
    AddGadgetItem(1, -1, "Harry Rannit"+Chr(10)+"12 Parliament Way, Battle Street, By the Bay")
    AddGadgetItem(1, -1, "Ginger Brokeit"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity")
    
    ListIconGadget(2, 5, 205, 290, 90, "Name", 100, #PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection)
    AddGadgetColumn(2, 1, "Address", 250)
    AddGadgetItem(2, -1, "Harry Rannit"+Chr(10)+"12 Parliament Way, Battle Street, By the Bay")
    AddGadgetItem(2, -1, "Ginger Brokeit"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity")
    
    ;...Subclass all 3 ListIconGadgets
    For g = 0 To 2
      AddressCallback = SetWindowLong_(GadgetID(g), #GWL_WNDPROC, @AddressListSubclassed()) 
    Next g
    
    Repeat
      Event = WaitWindowEvent()
    Until Event = #PB_Event_CloseWindow
    DeleteObject_(ColourBlue)
  EndIf
EndIf
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

That's the one! :)
I may look like a mule, but I'm not a complete ass.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Noooooo!! 2 wizards in the room and i'm not worthy!!

/me falls off the chair laughing hysterically.

Now I'll have to put you in the credits too Sparkie. Hmm, wonder if it's legal to say in the credits that I am apprenticed to two wizards, or will that start a guild war? :D :D :D
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Fangles wrote:...I am apprenticed to two wizards...
What :!: :?: You got yourself one guy who thinks he's a bat and another one who fancies himself as an ass :shock:

Fangles, me thinks you are screwed :!: :P

@srod(jk my friend) ;)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Sparkie wrote:
Fangles wrote:...I am apprenticed to two wizards...
What :!: :?: You got yourself one guy who thinks he's a bat and another one who fancies himself as an ass :shock:

Fangles, me thinks you are screwed :!: :P

@srod(jk my friend) ;)
Screwed?? Me??? At least tell me they are good quality brass screws and not that cheap alloy stuff!!!

And as I am a night hunting were-beast, (who has been defanged more often than he can remember), I consider myself to be in good company)
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Arrrghgh!!

Post by Fangbeast »

Well stuff me down a drainpipe and call me a monkey's underpants. Your code works fine, mine doesn't. And I think it has something to do with opening a secondary window.

Sparkie, in your code, you open up 1 window with 3 listicongadgets on it and the callback works.

In my code, I open up 1 window with 2 ListIconGadgets and it colours them fine. When opening a second window on top of that with 1 ListIconGadget on it, the line

Code: Select all

form\librarycallback = SetWindowLong_(GadgetID(#Gadget_titleform_titles), #GWL_WNDPROC, @LibrarySubclassed())
produces a syntax error. #Gadget_titleform_titles is my third ListIconGadget on my second window.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

@Sparkie: :D

@fangs: no problem with the following code; 2 windows, 3 listicons, 1 callback etc.

Code: Select all

#LVM_GETHEADER = #LVM_FIRST + 31 

;...Used in subclass ProceduReturn = result 
Global AddressCallback 

;...Blue brush for header background color 
Global Colour = CreateSolidBrush_(#Blue) 

;...Subclass procedure for all 3 ListIconGadgets 
Procedure AddressListSubclassed(hwnd, msg, wParam, lParam) 
  Protected hdi.HD_ITEM 
  result = CallWindowProc_(AddressCallback, hwnd, msg, wParam, lParam); Used for my first gadget 
  Select msg 
    Case #WM_NOTIFY 
      *pnmh.NMHDR = lParam        
       If *pnmh\code = #NM_CUSTOMDRAW 
        *pnmcd.NMCUSTOMDRAW = lParam                                                                  ; Determine drawing stage 
        Select *pnmcd\dwDrawStage 
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT                                                                     ; Get header text. 
            text$ = Space(100) 
            hdi\mask = #HDI_TEXT 
            hdi\pszText = @text$ 
            hdi\cchTextMax = Len(text$) 
            SendMessage_(*pnmh\hwndFrom, #HDM_GETITEM, *pnmcd\dwItemSpec, hdi)                     ; Check button state. 
            If *pnmcd\uItemState & #CDIS_SELECTED 
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH | #DFCS_PUSHED)  ; Offset text because of the selected button. 
              InflateRect_(*pnmcd\rc, -1, -1) 
            Else 
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH) 
            EndIf                      
                                                                
            ; Draw background. 
            InflateRect_(*pnmcd\rc, -1, -1) 
            SetBkMode_(*pnmcd\hdc, #TRANSPARENT) 
            ;If *pnmcd\dwItemSpec & 1 
            FillRect_(*pnmcd\hdc, *pnmcd\rc, Colour) 
            SetTextColor_(*pnmcd\hdc, #White) 
            ;Else 
            ;  FillRect_(*pnmcd\hdc, *pnmcd\rc, Colour) 
            ;  SetTextColor_(*pnmcd\hdc, $000000) 
            ;EndIf 
            DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_LEFT | #DT_VCENTER | #DT_END_ELLIPSIS) 
            result = #CDRF_SKIPDEFAULT 
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 



If OpenWindow(0, 100, 100, 300, 300, "ListIcon Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
  If CreateGadgetList(WindowID(0)) 
    ListIconGadget(0, 5, 5, 290, 90, "Name", 100, #PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection) 
    AddGadgetColumn(0, 1, "Address", 250) 
    AddGadgetItem(0, -1, "Harry Rannit"+Chr(10)+"12 Parliament Way, Battle Street, By the Bay") 
    AddGadgetItem(0, -1, "Ginger Brokeit"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity") 
    
    ListIconGadget(1, 5, 105, 290, 90, "Name", 100, #PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection) 
    AddGadgetColumn(1, 1, "Address", 250) 
    AddGadgetItem(1, -1, "Harry Rannit"+Chr(10)+"12 Parliament Way, Battle Street, By the Bay") 
    AddGadgetItem(1, -1, "Ginger Brokeit"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity") 

    OpenWindow(1, 0, 0, 300, 300, "ListIcon Example", #PB_Window_SystemMenu) 
    CreateGadgetList(WindowID(1)) 
    
    ListIconGadget(2, 5, 205, 290, 90, "Name", 100, #PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection) 
    AddGadgetColumn(2, 1, "Address", 250) 
    AddGadgetItem(2, -1, "Harry Rannit"+Chr(10)+"12 Parliament Way, Battle Street, By the Bay") 
    AddGadgetItem(2, -1, "Ginger Brokeit"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity") 
    
    ;...Subclass all 3 ListIconGadgets 
    For g = 0 To 2 
      AddressCallback = SetWindowLong_(GadgetID(g), #GWL_WNDPROC, @AddressListSubclassed()) 
    Next g 
    
    Repeat 
      Event = WaitWindowEvent() 
    Until Event = #PB_Event_CloseWindow 
    DeleteObject_(ColourBlue) 
  EndIf 
EndIf 
You'd get a syntax error if for some reason the 'form\librarycallback = SetWindowLong_(GadgetID(#Gadget_titleform_titles), #GWL_WNDPROC, @LibrarySubclassed())' command couldn't find the LibrarySubclassed() procedure. Check the placement of this command to make sure that the procedure has at least been declared before this command is executed.
I may look like a mule, but I'm not a complete ass.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Weird. I will do so immediately, at once ever, sir wizard no 2. Just a question though, why does it work for the first two and not for the third if it is the same callback (which it is) ???

*EDIT**
Okay, I declared the subclassing callback (that was apparently the problem as you said) but I am mystified as I thought (wrongly as it seemed) that callbacks didn't need declaring. I am wrong as usual. Main window worked because the callback was xincluded before the main window used it. Second one didn't because it was loaded before the callback.

I have a problem. I owe you and sparkie heaps but I don't send alcohol or cigarettes, only loose women. And I test the loose women first, thoroughly. Do you mind them loose and used?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Callbacks are regular procedures like any other and, at the end of the day, PB is a one-pass compiler and so forward references need declarations first. :)
And I test the loose women first, thoroughly. Do you mind them loose and used?
As long as you send them by first class mail I don't mind! Better avoid parcel force though as they tend to damage parcels!

I think this is perhaps the wrong forum... :)
I may look like a mule, but I'm not a complete ass.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Thanks Fangles, but you can send mine to srod. I can take 'em used but loose........hmmmm.....I don't think so :P
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Sparkie, hope you don't mind another question (especially since I haven't sent the loose women yet) but...Where in that callback could I detect which gadget was requesting the draw?

I have two different windows opening and two different gadgets that need two different colours.

Is it the *pnmh\hwndFrom parameter?

something like:

Code: Select all

IF *pnmh\hwndFrom = #Gadget_listform_names

  FillRect_(*pnmcd\hdc, *pnmcd\rc, form\maincolour) (My main gadget)

Else

  FillRect_(*pnmcd\hdc, *pnmcd\rc, form\alternatecolour) (MY second gadget on other window

EndIf
I tried this earlier and got a "Gadget object not initialised"

Code: Select all

IF *pnmh\hwndFrom = GadgetId(#Gadget_listform_names)

  FillRect_(*pnmcd\hdc, *pnmcd\rc, form\maincolour) (My main gadget)

ElseIf *pnmh\hwndFrom = GadgetId(#Gadget_postcodeform_postcodes)

  FillRect_(*pnmcd\hdc, *pnmcd\rc, form\alternatecolour) (MY second gadget on other window

EndIf
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

*pnmh\hwndFrom in this case refers the handle of the individual header control for each ListIconGadget. Using GetParent_(*pnmh\hwndFrom) should point you to the handle/GadgetID() of each ListIconGadget. :)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Sorry fangs, my original post left out the GetParent_() etc. My fault! :oops:
I may look like a mule, but I'm not a complete ass.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Is there any downside to an apprentice asking too many questions of resident wizards? Do I get turned into a frog or a hamster's ear or something worse?

Seriously, you blokes are excellent, thanks for all that help.

/me runs out of the batcave to try some code.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Fangles wrote:Do I get turned into a frog or a hamster's ear or something worse?
How does "BatAss Fangles" sound. :lol: :P Image
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Post Reply