Page 1 of 2

Posted: Sun Nov 05, 2006 3:47 pm
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

Posted: Sun Nov 05, 2006 3:49 pm
by srod
That's the one! :)

Posted: Sun Nov 05, 2006 11:54 pm
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

Posted: Mon Nov 06, 2006 4:34 am
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) ;)

Posted: Mon Nov 06, 2006 5:44 am
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)

Arrrghgh!!

Posted: Mon Nov 06, 2006 6:13 am
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.

Posted: Mon Nov 06, 2006 11:29 am
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.

Posted: Mon Nov 06, 2006 11:57 am
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?

Posted: Mon Nov 06, 2006 12:34 pm
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... :)

Posted: Mon Nov 06, 2006 6:44 pm
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

Posted: Tue Nov 07, 2006 8:07 am
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

Posted: Tue Nov 07, 2006 2:23 pm
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. :)

Posted: Tue Nov 07, 2006 2:35 pm
by srod
Sorry fangs, my original post left out the GetParent_() etc. My fault! :oops:

Posted: Wed Nov 08, 2006 12:40 am
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.

Posted: Wed Nov 08, 2006 3:22 am
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