Colouring a ListIconGadget header

Just starting out? Need help? Post your questions and find answers here.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Colouring a ListIconGadget header

Post by Fangbeast »

I found code in the forums to colour ListIconGadget headings but when I go past 2 callbacks to colour 2 different gadgets, I get syntax errors, even though there is none.

is there any way to make the below code generic so it can be used on as many ListIcons as I need? (The below one is for my first gadget)

Code: Select all

Procedure AddressListSubclassed(hwnd, msg, wparam, lparam)
  Protected hdi.hd_item
  result = CallWindowProc_(form\AddressCallback, hwnd, msg, wparam, lparam); Used for my first gadget
  Select msg
    Case #WM_NOTIFY
      *pnmh.NMHDR = lparam                                                                            ; Get handle to ListIcon header control
      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_(form\hAddresslist, #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. ; Here we alternate red text on blue background.
            InflateRect_(*pnmcd\rc, -1, -1)
            SetBkMode_(*pnmcd\hdc, #TRANSPARENT)
            ;If *pnmcd\dwItemSpec & 1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, Colour)
              SetTextColor_(*pnmcd\hdc, $000000)
            ;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

form\hAddresslist      = SendMessage_(GadgetID(#Gadget_listform_names), #LVM_GETHEADER, 0, 0)   ; Subclass ListIcon so we can customdraw the header text
form\AddressCallback   = SetWindowLong_(GadgetID(#Gadget_listform_names), #GWL_WNDPROC, @AddressListSubclassed())

srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Difficult to help without a little more code fangs.

I see no reason why you shouldn't be able to use the above on more than listicon.

I use similar code in my egrid lib and have just done a quick test with 3 egrids on one screen; all using the same colouring callbacks - no problems.

**EDIT - sorry I see what you're about.

Where you use 'form\hAddresslist' in the callback, you could swicth this for *pnmcd\hdr\hwndFrom. In fact, as far as the above code goes, this might do it.
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 »

So instead of this in the callback:

SendMessage_(form\hTitlelist, #HDM_GETITEM, *pnmcd\dwItemSpec, hdi)

I can use:

SendMessage_(*pnmcd\hdr\hwndFrom, #HDM_GETITEM, *pnmcd\dwItemSpec, hdi)

What about this section?

result = CallWindowProc_(form\AddressCallback, hwnd, msg, wparam, lparam)

Sorry about not having enough code but this is a 4,000 line program, libraries, icons etc. I couldn't distill the essence out of it:):)) But I could always send you the whole project (evil grin) :):):)
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Too many callbacks!!!

Post by Fangbeast »

Here are my 3 callbacks. One for each ListIconGadget

Code: Select all

;============================================================================================================================
; Subclass ListIcon so we can customdraw the header text and colour the header area
;============================================================================================================================

Procedure BookListSubclassed(hwnd, msg, wparam, lparam)
  Protected hdi.hd_item
  result = CallWindowProc_(form\BookCallback, hwnd, msg, wparam, lparam)
  Select msg
    Case #WM_NOTIFY
      *pnmh.NMHDR = lparam                                                      ; Get handle to ListIcon header control
      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_(form\hBooklist, #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.                                            ; Here we alternate red text on blue background.
            InflateRect_(*pnmcd\rc, -1, -1)
            SetBkMode_(*pnmcd\hdc, #TRANSPARENT)
            ;If *pnmcd\dwItemSpec & 1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, Colour)
              SetTextColor_(*pnmcd\hdc, $000000)
            ;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

;============================================================================================================================
; Subclass ListIcon so we can customdraw the header text and colour the header area
;============================================================================================================================

Procedure BorrowListSubclassed(hwnd, msg, wparam, lparam)
  Protected hdi.hd_item
  result = CallWindowProc_(form\BorrowCallback, hwnd, msg, wparam, lparam)
  Select msg
    Case #WM_NOTIFY
      *pnmh.NMHDR = lparam    ;--> Get handle to ListIcon header control
      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_(form\hBorrowlist, #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. ; Here we alternate red text on blue background.
            InflateRect_(*pnmcd\rc, -1, -1)
            SetBkMode_(*pnmcd\hdc, #TRANSPARENT)
            ;If *pnmcd\dwItemSpec & 1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, Colour)
              SetTextColor_(*pnmcd\hdc, $000000)
            ;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

;============================================================================================================================
; Subclass ListIcon so we can customdraw the header text and colour the header area
;============================================================================================================================

Procedure TitleListSubclassed(hwnd, msg, wparam, lparam)
  Protected hdi.hd_item
  result = CallWindowProc_(form\TitleCallback, hwnd, msg, wparam, lparam)
  Select msg
    Case #WM_NOTIFY
      *pnmh.NMHDR = lparam                                                                            ; Get handle to ListIcon header control
      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_(form\hTitlelist, #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. ; Here we alternate red text on blue background.
            InflateRect_(*pnmcd\rc, -1, -1)
            SetBkMode_(*pnmcd\hdc, #TRANSPARENT)
            ;If *pnmcd\dwItemSpec & 1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, Colour)
              SetTextColor_(*pnmcd\hdc, $000000)
            ;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

When I open the main program window, I colour the two primary gadget headings.

Code: Select all

;------------------------------------------------------------------------------------------------
; Subclass the main form ListIcongadgets to allow the headings to be coloured
;------------------------------------------------------------------------------------------------
form\hBooklist      = SendMessage_(GadgetID(#Gadget_booklist_booklist), #LVM_GETHEADER, 0, 0)   ; Subclass ListIcon so we can customdraw the header text
form\BookCallback   = SetWindowLong_(GadgetID(#Gadget_booklist_booklist), #GWL_WNDPROC, @BookListSubclassed())
 
form\hBorrowlist    = SendMessage_(GadgetID(#Gadget_booklist_borrowlist), #LVM_GETHEADER, 0, 0) ; Subclass ListIcon so we can customdraw the header text
form\BorrowCallback = SetWindowLong_(GadgetID(#Gadget_booklist_borrowlist), #GWL_WNDPROC, @BorrowListSubclassed())

When I open my secondary window to show other titles for the highlighted author, I attempt to colour that third ListIconGadget and get a syntax error. For the life of me, I cannot figure out why.

Code: Select all

;============================================================================================================================
; Get all other titles for a highlighted author in the list
;============================================================================================================================

Procedure ShowOtherTitles()
  If form\mutex <> 1                                                                            ; Only open if no other window is open
    program\curbookline = GetGadgetState(#Gadget_booklist_booklist)                             ; Get the current line number from highlight
    If program\curbookline <> -1                                                                ; If a line is highlighted
      If Window_titleform()                                                                     ; Can the window be opened?
        form\hTitlelist      = SendMessage_(GadgetID(#Gadget_titleform_titles), #LVM_GETHEADER, 0, 0) ; Subclass ListIcon so we can customdraw the header text
        form\TitleCallback   = SetWindowLong_(GadgetID(#Gadget_titleform_titles), #GWL_WNDPROC, @TitleListSubclassed())
;       Coming up As Syntax Error And I cannot see why yet, looks the same As main form
        author.s = GetGadgetItemText(#Gadget_booklist_booklist, program\curbookline, 1)         ; Get the author name
        form\mutex = 1                                                                          ; No other window allowed to be open!
        FadeInMyWindow(#Window_titleform)                                                       ; Fade in the window gently
        AddKeyboardShortcut(#Window_titleform, #PB_Shortcut_Escape, #Shortcut_titleform_escape)
        form\lastwindow = "othertitles"                                                         ; Set window tracking mode
        SetWindowTitle(#Window_titleform, "<°)))o><²³  Other titles by [ " + author.s + " ]")   ; Set the window title
        SetActiveWindow(#Window_titleform)                                                      ; Set this as the active window
        If SQL3GetTable("Select title, record FROM library WHERE author Like '%" + author.s + "%'", @myRows, @myCols, program\dbhandle)
          If CountList(SqlData.s()) <> 0                                                        ; Check if any data was returned even if query worked
            program\titlecounter = 0                                                            ; List display counter is empty
            ForEach SqlData.s()
              AddGadgetItem(#Gadget_titleform_titles, -1, StringField(SqlData.s(), 1, "|") + Chr(10) + StringField(SqlData.s(), 2, "|"))
              program\titlecounter + 1
            Next
          EndIf
        EndIf
        FillCombo(#Gadget_titleform_authors, "SELECT DISTINCT author FROM library ORDER BY author")
        SetGadgetText(#Gadget_titleform_authors, author.s)
        MessageHandler(#StatusBar_booklist_messages, "ShowOtherTitles()", "Found all titles for author matching " + title.s, 1)
      Else
        MessageHandler(#StatusBar_booklist_messages, "ShowOtherTitles()", "Cannot open the get other titles window, possible memory error Or program.", 2)
      EndIf
    Else
      MessageHandler(#StatusBar_booklist_messages, "ShowOtherTitles()", "Cannot open the other titles window, no record selected.", 1)
    EndIf
  Else
    MessageHandler(#StatusBar_booklist_messages, "ShowOtherTitles()", form\lastwindow + " is still open, close it before trying this operation again", 1)
  EndIf
EndProcedure
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Not sure about the syntax error (although this would be the result of the Callback procedure not being found), but all the list icon's will share the same original window proc and so you can remove all the form\BookCallback, form\BorrowCallback, form\TitleCallback etc. for a single global variable.

Code: Select all

oldproc = SetWindowLong_(GadgetID(#Gadget_booklist_booklist), #GWL_WNDPROC, @BookListSubclassed())
etc.

Then

Code: Select all

result = CallWindowProc_(oldproc, hwnd, msg, wparam, lparam) 
can be used in your callbacks.

You definitely want to use a single callback though as there is a lot of repetition here.
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 »

srod wrote:Not sure about the syntax error (although this would be the result of the Callback procedure not being found), but all the list icon's will share the same original window proc and so you can remove all the form\BookCallback, form\BorrowCallback, form\TitleCallback etc. for a single global variable.

Code: Select all

oldproc = SetWindowLong_(GadgetID(#Gadget_booklist_booklist), #GWL_WNDPROC, @BookListSubclassed())
etc.

Then

Code: Select all

result = CallWindowProc_(oldproc, hwnd, msg, wparam, lparam) 
can be used in your callbacks.

You definitely want to use a single callback though as there is a lot of repetition here.
Sorry, I'm a donkey (cousin to an ass) and I don't quite understand how to do this. (evil grin). You start quoting api at me beyond what I can plug in and I can guarantee to kill my program worse than it is when I start modifying what I don't understand:):):):):):):):)

I'm lucky 2 out of three callbacks actually work! (Now I am going to get some ugly sleep. I need it!)
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.
Post Reply