# PureBasic Forum

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

 All times are UTC + 1 hour

 Page 1 of 1 [ 12 posts ]
 Print view Previous topic | Next topic
Author Message
 PureBasic Protozoa

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 _________________ Amateur Radio, D-STAR/VK3HAF Top  Post subject: Posted: Thu Jun 07, 2007 6:26 pm  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

For j = 0 To 3
For i = 1 To 10
Next
next
For b=0 To 99; Add 100 rows.
Next
For i = 0 To 99
For j = 0 To 50
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

 Post subject: Thank youPosted: Fri Jun 08, 2007 1:06 am
 PureBasic Protozoa

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.

_________________

Top

 Post subject: Re: Colouring ListIconGadget headersPosted: Sat Apr 28, 2012 2:50 pm
 PureBasic Protozoa

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

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.

_________________

Top

 Post subject: Re: Colouring ListIconGadget headersPosted: Sat Apr 28, 2012 3:40 pm

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

 Post subject: Re: Colouring ListIconGadget headersPosted: Sat Apr 28, 2012 11:40 pm
 PureBasic Protozoa

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.

_________________

Top

 Post subject: Re: Colouring ListIconGadget headersPosted: Sat Apr 28, 2012 11:56 pm
 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

 Post subject: Re: Colouring ListIconGadget headersPosted: Sun Apr 29, 2012 2:56 am
 PureBasic Protozoa

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 :):)

_________________

Top

 Post subject: Re: Colouring ListIconGadget headersPosted: Sun Apr 29, 2012 4:43 am

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

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

 Post subject: Re: Colouring ListIconGadget headersPosted: Sun Apr 29, 2012 8:21 am
 PureBasic Protozoa

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

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!

_________________

Top

 Post subject: Re: Colouring ListIconGadget headersPosted: Sun Apr 29, 2012 9:37 am
 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

 Post subject: Re: Colouring ListIconGadget headersPosted: Sun Apr 29, 2012 11:35 am
 PureBasic Protozoa

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.

_________________

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 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 forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forum

Search for:
 Jump to:  Select a forum ------------------ PureBasic    Coding Questions    Game Programming    3D Programming    Assembly Programming    The PureBasic Editor    The PureBasic Form Designer    General Discussion    Feature Requests and Wishlists    Tricks 'n' Tips Bug Reports    Bugs - Windows    Bugs - Linux    Bugs - Mac OSX    Bugs - Documentation OS Specific    AmigaOS    Linux    Windows    Mac OSX Miscellaneous    Announcement    Off Topic Showcase    Applications - Feedback and Discussion    PureFORM & JaPBe    TailBite