It is currently Sat Oct 19, 2019 1:49 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 12 posts ] 
Author Message
 Post subject: Colouring ListIconGadget headers
PostPosted: Thu Jun 07, 2007 4:19 pm 
Offline
PureBasic Protozoa
PureBasic Protozoa
User avatar

Joined: Fri Apr 25, 2003 3:08 pm
Posts: 4493
Location: Not Sydney!!! (Bad water, no goats)
I found the following code in the forum to subclass a listicongadget so that I can colour the heading area but after I managed to modify it to colour 3 gadgets, it appeared that I was doing something wrong ans any gadgets after 3 wouldn't colour.


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

Procedure SubclassedListIcon(hwnd, msg, wparam, lparam)
  Protected hdi.hd_item
  result = CallWindowProc_(form\oldListIconCallback, 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\hHeader, #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, form\brush)
              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_CENTER | #DT_VCENTER | #DT_END_ELLIPSIS)
            result = #CDRF_SKIPDEFAULT
        EndSelect
      EndIf
  EndSelect
  ProcedureReturn result
EndProcedure


These are the two lines to invoke the colouring of a single gadget and I was wondering if there is a simple way to use a linked list to subclass and colour as many gadget headings that I want without resorting to a library with features I don't need?

Code:
;------------------------------------------------------------------------------------------------
  ; Sublcass ListIconGadget to allow header to be painted
  ;------------------------------------------------------------------------------------------------
  form\hHeader = SendMessage_(GadgetID(#Gadget_ebackup_items), #LVM_GETHEADER, 0, 0) ; Subclass ListIcon so we can customdraw the header text
  form\oldListIconCallback = SetWindowLong_(GadgetID(#Gadget_ebackup_items), #GWL_WNDPROC, @SubclassedListIcon())


Give me 30 years and I' might get betetr with the API but I doubt it :D :D :D :D :D

_________________
Amateur Radio, D-STAR/VK3HAF


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Jun 07, 2007 6:26 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Wed Oct 29, 2003 4:35 pm
Posts: 10525
Location: Beyond the pale...
fangles, I reckon the problem is your 'form' structure variable which I presume is global.

The thing is, that the code you're using was written for PB 3.94. With PB 4, we can easily get the header text and so there is no need to store the handle of the header control etc. In fact, we never needed to store it anyhow ... but that's another story! :)

The following is very rough and ready (but is all I have time for!) with the colouring routine being simplified over the version you're currently using:

Code:
;Coloured header control.
;By srod.
;Purebasic 4.
;Windows.


#LVM_GETHEADER = #LVM_FIRST + 31

; Globals
Global oldListIconCallback, redbrush, bluebrush
redbrush=CreateSolidBrush_(#Yellow)
bluebrush=CreateSolidBrush_(#Yellow)


; Proc for subclassed ListIconGadget
Procedure SubclassedListIcon(hwnd, msg, wparam, lparam)
  Protected hdi.hd_item
  result = CallWindowProc_(oldListIconCallback, 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$=GetGadgetItemText(GetDlgCtrlID_(hWnd),-1,*pnmcd\dwItemSpec)
 ;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.
            *pnmcd\rc\bottom-2 : *pnmcd\rc\right-2
            SetBkMode_(*pnmcd\hdc,#TRANSPARENT)
            If *pnmcd\dwItemSpec&1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, redbrush)
              SetTextColor_(*pnmcd\hdc, #Blue)
            Else
              FillRect_(*pnmcd\hdc, *pnmcd\rc, bluebrush)
              SetTextColor_(*pnmcd\hdc, #Red)
            EndIf
            *pnmcd\rc\top+2
            InflateRect_(*pnmcd\rc,-5,0)
            If *pnmcd\rc\right>*pnmcd\rc\left
              DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_CENTER|#DT_VCENTER|#DT_END_ELLIPSIS)
            EndIf
            result = #CDRF_SKIPDEFAULT
        EndSelect
      EndIf
  EndSelect
  ProcedureReturn result
EndProcedure


; ************************************************
; Main Window
; ************************************************
If OpenWindow(0, 100, 100, 415, 400, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
  ListIconGadget(0, 5, 5, 405, 80, "col 0", 50, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
  ListIconGadget(1, 5, 90, 405, 80, "col 0", 50, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
  ListIconGadget(2, 5, 175, 405, 80, "col 0", 50, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
  ListIconGadget(3, 5, 250, 405, 80, "col 0", 50, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
;Subclass ListIcon so we can customdraw the header text
  oldListIconCallback = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SubclassedListIcon())
  oldListIconCallback = SetWindowLong_(GadgetID(1), #GWL_WNDPROC, @SubclassedListIcon())
  oldListIconCallback = SetWindowLong_(GadgetID(2), #GWL_WNDPROC, @SubclassedListIcon())
  oldListIconCallback = SetWindowLong_(GadgetID(3), #GWL_WNDPROC, @SubclassedListIcon())

;Add 10 more columns.
  For j = 0 To 3
    For i = 1 To 10
      AddGadgetColumn(j, i, "col "+Str(i), 50)
    Next 
  next
;Add some data
  For b=0 To 99; Add 100 rows.
    AddGadgetItem(0,-1,"")
  Next
  For i = 0 To 99
    For j = 0 To 50
      SetGadgetItemText(0,i,Str(i+j),j)
    Next j
  Next i           

  Repeat
    EventID = WaitWindowEvent()
  Until EventID = #PB_Event_CloseWindow

  DeleteObject_(redbrush)
  DeleteObject_(bluebrush)
 
EndIf
End


I see no need for linked lists etc. If you really need to store info on each listicon then consider using a Window's property to store a pointer to whatever data you need to store.

_________________
I may look like a mule, but I'm not a complete ass.


Top
 Profile  
Reply with quote  
 Post subject: Thank you
PostPosted: Fri Jun 08, 2007 1:06 am 
Offline
PureBasic Protozoa
PureBasic Protozoa
User avatar

Joined: Fri Apr 25, 2003 3:08 pm
Posts: 4493
Location: Not Sydney!!! (Bad water, no goats)
I can see that I am going to have to sell my children to pay you. I still don't know bugger alla bout manipulating the api which is why I can't figure these things out myself. Normal pb code I can bugger up and hopefully fix but this stuff???

Thanks for that.. Hope things are going okay for you.

_________________
Amateur Radio, D-STAR/VK3HAF


Top
 Profile  
Reply with quote  
 Post subject: Re: Colouring ListIconGadget headers
PostPosted: Sat Apr 28, 2012 2:50 pm 
Offline
PureBasic Protozoa
PureBasic Protozoa
User avatar

Joined: Fri Apr 25, 2003 3:08 pm
Posts: 4493
Location: Not Sydney!!! (Bad water, no goats)
Really old post but as this question is related, I'll put it here.

The above code works fine if I do this for every code in the main openwindow statement

oldListIconCallback = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SubclassedListIcon())

(oldListIconCallback = SetWindowLong_(GadgetID(1), #GWL_WNDPROC, @SubclassedListIcon())

oldListIconCallback = SetWindowLong_(GadgetID(2), #GWL_WNDPROC, @SubclassedListIcon())

However, if I do this inside a PROCEDURE that opens another window on top of the main one, my program will either crash at the opening of that window when encountering that statement or when I exit that window.

I can reproduce it at will. Simply commenting out that statement fixes my problem immediately.

_________________
Amateur Radio, D-STAR/VK3HAF


Top
 Profile  
Reply with quote  
 Post subject: Re: Colouring ListIconGadget headers
PostPosted: Sat Apr 28, 2012 3:40 pm 
Offline
Addict
Addict

Joined: Tue Feb 22, 2011 1:16 pm
Posts: 1482
In one of the PureBasic blog posts, they said to change all SetWindowLong_() to SetWindowLongPtr_() now. Try that. And the same for GetWindowLong_() to GetWindowLongPtr_().

_________________
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!


Top
 Profile  
Reply with quote  
 Post subject: Re: Colouring ListIconGadget headers
PostPosted: Sat Apr 28, 2012 11:40 pm 
Offline
PureBasic Protozoa
PureBasic Protozoa
User avatar

Joined: Fri Apr 25, 2003 3:08 pm
Posts: 4493
Location: Not Sydney!!! (Bad water, no goats)
Thanks for that MachineCode, fingers crossed.

**EDIT** Just did it in 8 places in my program, tested, works like a charm. I'll go read the blog post, not that i'll understand it but I'll read it:):)

Thanks again.

_________________
Amateur Radio, D-STAR/VK3HAF


Top
 Profile  
Reply with quote  
 Post subject: Re: Colouring ListIconGadget headers
PostPosted: Sat Apr 28, 2012 11:56 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Wed Oct 29, 2003 4:35 pm
Posts: 10525
Location: Beyond the pale...
If you are using PB x64 (or writing code to compile on both x86 and x64) then yes you want to be using SetWindowLongPtr_() etc. fangles.

_________________
I may look like a mule, but I'm not a complete ass.


Top
 Profile  
Reply with quote  
 Post subject: Re: Colouring ListIconGadget headers
PostPosted: Sun Apr 29, 2012 2:56 am 
Offline
PureBasic Protozoa
PureBasic Protozoa
User avatar

Joined: Fri Apr 25, 2003 3:08 pm
Posts: 4493
Location: Not Sydney!!! (Bad water, no goats)
srod wrote:
If you are using PB x64 (or writing code to compile on both x86 and x64) then yes you want to be using SetWindowLongPtr_() etc. fangles.


No, I'm not. Could not shell out the buckaroonies for the x64 version of win7, especially when I could not get x64 versions of all my needed hardware drivers so I never bothered.

Just used PSPad text editor to do a search and replace on ALL my code and no more problems.

So glad it was an easy fix, too many other dramas going on around here :):):)

_________________
Amateur Radio, D-STAR/VK3HAF


Top
 Profile  
Reply with quote  
 Post subject: Re: Colouring ListIconGadget headers
PostPosted: Sun Apr 29, 2012 4:43 am 
Offline
Addict
Addict
User avatar

Joined: Fri Sep 21, 2007 5:52 am
Posts: 3402
Location: New Zealand
Fangbeast wrote:
Really old post but as this question is related, I'll put it here.

The above code works fine if I do this for every code in the main openwindow statement

oldListIconCallback = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SubclassedListIcon())

(oldListIconCallback = SetWindowLong_(GadgetID(1), #GWL_WNDPROC, @SubclassedListIcon())

oldListIconCallback = SetWindowLong_(GadgetID(2), #GWL_WNDPROC, @SubclassedListIcon())

However, if I do this inside a PROCEDURE that opens another window on top of the main one, my program will either crash at the opening of that window when encountering that statement or when I exit that window.

I can reproduce it at will. Simply commenting out that statement fixes my problem immediately.


I don't think you can't use it like that, not with multiple windows since the address stored in OldListIconCallBack
will always refer to the last opened windows procedure resulting in an IMA in your callback


Top
 Profile  
Reply with quote  
 Post subject: Re: Colouring ListIconGadget headers
PostPosted: Sun Apr 29, 2012 8:21 am 
Offline
PureBasic Protozoa
PureBasic Protozoa
User avatar

Joined: Fri Apr 25, 2003 3:08 pm
Posts: 4493
Location: Not Sydney!!! (Bad water, no goats)
idle wrote:
Fangbeast wrote:
Really old post but as this question is related, I'll put it here.

The above code works fine if I do this for every code in the main openwindow statement

oldListIconCallback = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SubclassedListIcon())

(oldListIconCallback = SetWindowLong_(GadgetID(1), #GWL_WNDPROC, @SubclassedListIcon())

oldListIconCallback = SetWindowLong_(GadgetID(2), #GWL_WNDPROC, @SubclassedListIcon())

However, if I do this inside a PROCEDURE that opens another window on top of the main one, my program will either crash at the opening of that window when encountering that statement or when I exit that window.

I can reproduce it at will. Simply commenting out that statement fixes my problem immediately.


I don't think you can't use it like that, not with multiple windows since the address stored in OldListIconCallBack
will always refer to the last opened windows procedure resulting in an IMA in your callback


Seems to work at the moment. Since I changed Get/SetWindowLong to Get/SetWindowLongPtr, it's no longer crashing, which it was before, all the time.

So much to do, I need a holiday!

_________________
Amateur Radio, D-STAR/VK3HAF


Top
 Profile  
Reply with quote  
 Post subject: Re: Colouring ListIconGadget headers
PostPosted: Sun Apr 29, 2012 9:37 am 
Offline
PureBasic Expert
PureBasic Expert

Joined: Wed Oct 29, 2003 4:35 pm
Posts: 10525
Location: Beyond the pale...
If you are not using PB x64 then SetWindowLongPtr_() will make no difference.

_________________
I may look like a mule, but I'm not a complete ass.


Top
 Profile  
Reply with quote  
 Post subject: Re: Colouring ListIconGadget headers
PostPosted: Sun Apr 29, 2012 11:35 am 
Offline
PureBasic Protozoa
PureBasic Protozoa
User avatar

Joined: Fri Apr 25, 2003 3:08 pm
Posts: 4493
Location: Not Sydney!!! (Bad water, no goats)
srod wrote:
If you are not using PB x64 then SetWindowLongPtr_() will make no difference.


Well, it made a difference here, apparently. Whether that's due to something else is decidedly unclear to me. Once I had changed from Get/SetWindowLong to Get/SetWindowLongPtr, no more crashes at all.

If that change is not the reason, I don't know why. As you well know, API isn't my forte.

_________________
Amateur Radio, D-STAR/VK3HAF


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye