Page 1 of 2
SetGadgetItemColor doesn't work after windowcallback code
Posted: Sun Jul 28, 2019 7:51 am
by Fangbeast
Finally!! After years of wondering, I accidentally disabled my main SetWindowCallback(@MainWindowCallback()) and my SetGadgetItemColor started working again.
Prior to that, no combination of SetGadgetItemColor would work anywhere in my code.
Now that I know what killed it, I still don't know how to fix it.
Could someone smart person look over my window callback code and maybe suggest how I can prevent it from killing my colouring?
Code: Select all
Procedure MainWindowCallback(hWnd, uMsg, wParam, lParam)
Result = #PB_ProcessPureBasicEvents
; Netmaestro's windowsnap code
Static Snapped1.i, Snapped2.i, Snapped3.i, Snapped4.i
Select uMsg
; Netmaestro's windowsnap code
Case #WM_MOVING
If Toggle\ScreenSnap = 1
*view.RECT = lparam
curwidth = *view\right - *view\left
curheight = *view\bottom - *view\top
If AutoSnap ; AutoSnap Section
If *view\left < SnapD
If Not Snapped1
*view\left = 0
*view\right = curwidth
snapped1 = #True
ReturnValue = #True
EndIf
Else
snapped1 = #False
EndIf
If *view\top < SnapD
If Not Snapped2
*view\top = 0
*view\bottom = curheight
snapped2 = #True
ReturnValue = #True
EndIf
Else
snapped2 = #False
EndIf
If *view\right > screenw - SnapD
If Not Snapped3
*view\left = ScreenW - curwidth
*view\right = screenW
snapped3 = #True
ReturnValue = #True
EndIf
Else
snapped3 = #False
EndIf
If *view\bottom > screenH - SnapD
If Not Snapped4
*view\top = screenH - curheight
*view\bottom = screenH
snapped4 = #True
ReturnValue = #True
EndIf
Else
snapped4 = #False
EndIf
EndIf
If *view\top < 0 ; Inside Desktop Section
*view\top = 0
*view\bottom = curheight
EndIf
If *view\left < 0
*view\left = 0
*view\right = curwidth
EndIf
If *view\right > screenW
*view\right = screenW
*view\left = *view\right - curwidth
EndIf
If *view\bottom > screenH
*view\bottom = screenH
*view\top = *view\bottom - curheight
EndIf
MoveWindow_(WindowID, *view\left, *view\top, *view\right - *view\left, *view\bottom - *view\top, #True)
ReturnValue = #True
EndIf
; Draw a line through an item to indicate its deleted state
Case #WM_NOTIFY
*nmhdr.NMHDR = lParam
*lvCD.NMLVCUSTOMDRAW = lParam
If IsGadget(#Gadget_MyInfo_Titles)
If *lvCD\nmcd\hdr\hwndFrom = GadgetID(#Gadget_MyInfo_Titles) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
result = #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
result = #CDRF_NOTIFYSUBITEMDRAW;
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
thisRow = *lvCD\nmcd\dwItemSpec
thisCol = *lvCD\iSubItem
on_off = GetGadgetItemData(#Gadget_MyInfo_Titles, thisRow)
; If thisCol = 0 And on_off. Specifically for column 0. You can change this to any or just use on_off to set all columns
If on_off
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutYes))
result = #CDRF_NEWFONT; | #CDRF_DODEFAULT
Else
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutNo))
result = #CDRF_NEWFONT
EndIf
; Proper colour banding in listicons. This would have worked in main code with SetGadgetItemColor
; if something else in this callback didn't kill it.
If Toggle\ColourBand = #True ;<-----------Add This Block (Paul Leischow)
If (thisRow / 2) * 2 = thisRow
;*lvCD\clrText = $000000
;*lvCD\clrTextBk = $D4D4D4
*lvCD\clrText = $000000
*lvCD\clrTextBk = $EEEEEE
Else
;*lvCD\clrText = $FFFFFF
;*lvCD\clrTextBk = $C1C1C1
*lvCD\clrText = $484848
*lvCD\clrTextBk = $DADADA
EndIf
EndIf
EndSelect
EndIf
EndIf
EndSelect ; uMsg
ProcedureReturn Result
EndProcedure
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Sun Jul 28, 2019 10:27 am
by mk-soft
What does your GadgetCallback look like?
It is important in which order and with which return value these are executed.
Your own callback may not always call the previous callback. This would lead to double processing of the event and thus overwrite your own processing.
P.S.
The same is true for WindowCallback.
It does not always return '#PB_ProcessPureBasicEvents'.
For some events a True must be returned to confirm that the event would be processed.
Short Example with RichEditCallback...
Code: Select all
;-TOP
; Comment : Module SetGadgetCallback (Windows Only)
; Author : mk-soft
; Version : v0.02
; Created : 10.06.2018
; Updated :
; Link : https://www.purebasic.fr/english/viewtopic.php?f=12&t=70842
;
; Syntax Callback:
; Procedure GadgetCB(hWnd,uMsg,wParam,lParam)
; Select uMsg
; ;TODO
; EndSelect
; ; Call previous gadget procedure
; ProcedureReturn CallGadgetProc(hWnd,uMsg,wParam,lParam)
; EndProcedure
;
; *****************************************************************************
DeclareModule GadgetCallback
Declare SetGadgetCallback(Gadget, *lpNewFunc)
Declare CallGadgetProc(hWnd, uMsg, wParam, lParam)
EndDeclareModule
Module GadgetCallback
EnableExplicit
Global NewMap *lpPrevFunc()
Global MutexCB = CreateMutex()
; ---------------------------------------------------------------------------
Procedure SetGadgetCallback(Gadget, *lpNewFunc)
Protected GadgetID, GadgetKey.s
GadgetID = GadgetID(Gadget)
GadgetKey = Hex(GadgetID)
; Remove exists Callback
If FindMapElement(*lpPrevFunc(), GadgetKey)
SetWindowLongPtr_(GadgetID, #GWL_WNDPROC, *lpPrevFunc())
DeleteMapElement(*lpPrevFunc())
EndIf
If *lpNewFunc
If AddMapElement(*lpPrevFunc(), GadgetKey)
*lpPrevFunc() = SetWindowLongPtr_(GadgetID, #GWL_WNDPROC, *lpNewFunc)
ProcedureReturn *lpPrevFunc()
EndIf
EndIf
ProcedureReturn 0
EndProcedure
; ---------------------------------------------------------------------------
Procedure CallGadgetProc(hWnd, uMsg, wParam, lParam)
Protected result
LockMutex(MutexCB)
If FindMapElement(*lpPrevFunc(), Hex(hWnd))
result = CallWindowProc_(*lpPrevFunc(), hWnd, uMsg, wParam, lParam)
EndIf
UnlockMutex(MutexCB)
ProcedureReturn result
EndProcedure
EndModule
; *****************************************************************************
; Example
CompilerIf #PB_Compiler_IsMainFile
UseModule GadgetCallback
Procedure RichEditProc(hWnd,uMsg,wParam,lParam)
Select uMsg
Case #WM_KEYDOWN
Select wParam
Case #VK_DELETE
;ProcedureReturn 1
Case #VK_BACK
;ProcedureReturn 1
EndSelect
Case #WM_CHAR
Select wParam
Case #VK_TAB
SetFocus_(GetWindow_(hWnd,#GW_HWNDNEXT))
ProcedureReturn 1
EndSelect
EndSelect
ProcedureReturn CallGadgetProc(hWnd,uMsg,wParam,lParam)
EndProcedure
If OpenWindow(0,0,0,740,250,"Example SetGadgetCallback",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
EditorGadget(1,10,10,230,200)
EditorGadget(2,250,10,230,200)
EditorGadget(3,490,10,230,200)
SetGadgetCallback(1, @RichEditProc())
SetGadgetCallback(2, @RichEditProc())
SetGadgetCallback(3, @RichEditProc())
; SetGadgetCallback(1, 0)
; SetGadgetCallback(2, 0)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
CompilerEndIf
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Sun Jul 28, 2019 11:42 am
by Fangbeast
What does your GadgetCallback look like?
Hello, thanks for looking into this. There is no actual separate gadget callback. The WindowCallback on line 178 intercepts the Case #WM_NOTIFY flag on the #Gadget_MyInfo_Titles on the main form (A ListIconGadget) in order to be able to draw a line through a column of text. (I use it to indicate a deleted item).
If I rip out all other sections of code, that is the exact block of code that is causing the problem. Let me show you the stripped down version.
Code: Select all
Procedure MainWindowCallback(hWnd, uMsg, wParam, lParam)
Result = #PB_ProcessPureBasicEvents
; Draw a line through an item to indicate its deleted state
Case #WM_NOTIFY
*nmhdr.NMHDR = lParam
*lvCD.NMLVCUSTOMDRAW = lParam
If IsGadget(#Gadget_MyInfo_Titles)
If *lvCD\nmcd\hdr\hwndFrom = GadgetID(#Gadget_MyInfo_Titles) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
result = #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
result = #CDRF_NOTIFYSUBITEMDRAW;
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
thisRow = *lvCD\nmcd\dwItemSpec
thisCol = *lvCD\iSubItem
on_off = GetGadgetItemData(#Gadget_MyInfo_Titles, thisRow)
; If thisCol = 0 And on_off. Specifically for column 0. You can change this to any or just use on_off to set all columns
If on_off
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutYes))
result = #CDRF_NEWFONT; | #CDRF_DODEFAULT
Else
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutNo))
result = #CDRF_NEWFONT
EndIf
EndSelect
EndIf
EndIf
EndSelect ; uMsg
ProcedureReturn Result
EndProcedure
It is important in which order and with which return value these are executed.
I understand what you say but I lack the windows api skill to know what to do about this, sorry.
Your own callback may not always call the previous callback.
As mentioned above, there is no other callback operating for this gadget. And no other callbacks for the current code.
It does not always return '#PB_ProcessPureBasicEvents'.
Even though it was defined at the top of the code already? I think I see what you mean though but what do I do? I realise now that the result = #PB_ProcessPureBasicEvents as defined at the top is replaced by the result in the custom draw routine so the SetGadgetItemColor is never processed right?
What do I do about it?
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Sun Jul 28, 2019 12:59 pm
by mk-soft
Info
Module SetGadgetCallback for Gadgets does the same us SetWindowCallback for Windows;)
Its work
Code: Select all
EnableExplicit
#ColoredColumn = 0
#HeaderTextColor = #Red
#LVM_GETHEADER = #LVM_FIRST + 31
#Gadget_MyInfo_Titles = 0
Enumeration fonts
#FontStrikeoutYes
#FontStrikeoutNo
EndEnumeration
LoadFont(#FontStrikeoutYes, "", 12, #PB_Font_StrikeOut)
LoadFont(#FontStrikeoutNo, "", 12)
Define DefaultListIconCallback.I
Procedure CustomListIconCallback(hWnd, uMsg, wParam, lParam)
Shared DefaultListIconCallback.I
Protected *NMCUSTOMDRAW.NMCUSTOMDRAW
Protected *NMHDR.NMHDR
Protected Result.I
If hWnd = GadgetID(#Gadget_MyInfo_Titles)
If uMsg = #WM_NOTIFY
*NMHDR = lParam
If *NMHDR\code = #NM_CUSTOMDRAW
*NMCUSTOMDRAW = lParam
Select *NMCUSTOMDRAW\dwDrawStage
Case #CDDS_PREPAINT
;TODO
ProcedureReturn #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
If *NMCUSTOMDRAW\dwItemSpec = #ColoredColumn
SetTextColor_(*NMCUSTOMDRAW\hdc, #HeaderTextColor)
ProcedureReturn #CDDS_ITEMPREPAINT
EndIf
EndSelect
EndIf
EndIf
EndIf
ProcedureReturn CallWindowProc_(DefaultListIconCallback, hWnd, uMsg, wParam, lParam)
EndProcedure
Procedure MainWindowCallback(hWnd, uMsg, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents
Protected *nmhdr.NMHDR, *lvCD.NMLVCUSTOMDRAW
Protected thisRow, thisCol, on_off
; Draw a line through an item to indicate its deleted state
Select uMsg
Case #WM_NOTIFY
*nmhdr.NMHDR = lParam
*lvCD.NMLVCUSTOMDRAW = lParam
If IsGadget(#Gadget_MyInfo_Titles)
If *lvCD\nmcd\hdr\hwndFrom = GadgetID(#Gadget_MyInfo_Titles) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
;result = #CDRF_NOTIFYITEMDRAW ; <- Not used
Case #CDDS_ITEMPREPAINT
;result = #CDRF_NOTIFYSUBITEMDRAW; <- Not used
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
thisRow = *lvCD\nmcd\dwItemSpec
thisCol = *lvCD\iSubItem
on_off = GetGadgetItemData(#Gadget_MyInfo_Titles, thisRow)
; If thisCol = 0 And on_off. Specifically for column 0. You can change this to any or just use on_off to set all columns
If on_off
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutYes))
result = #CDRF_NEWFONT ; | #CDRF_DODEFAULT
Else
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutNo))
result = #CDRF_NEWFONT
EndIf
EndSelect
EndIf
EndIf
EndSelect ; uMsg
ProcedureReturn Result
EndProcedure
OpenWindow(0, 200, 100, 400, 100, "ListIconGadget with colored header text")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
"Name", 110, #PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0,
#PB_ListIcon_ColumnWidth) - 4)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ +
"12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ +
"130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ +
"321 Logo Drive, Mouse House, Downtown")
DefaultListIconCallback = SetWindowLongPtr_(GadgetID(0), #GWL_WNDPROC,
@CustomListIconCallback())
SetGadgetItemData(0, 1, #True)
SetWindowCallback(@MainWindowCallback())
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Sun Jul 28, 2019 1:44 pm
by Fangbeast
This is getting more and more complicated for me for follow.
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Sun Jul 28, 2019 1:52 pm
by mk-soft
I don't think it's possible to change the background color and the font separately.
You have to completely redraw the item yourself...
Link:
https://www.rsbasic.de/winapi-library/
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Sun Jul 28, 2019 2:03 pm
by Fangbeast
mk-soft wrote:I don't think it's possible to change the background color and the font separately.
You have to completely redraw the item yourself...
Link:
https://www.rsbasic.de/winapi-library/
That's beyond me so I'll study your example and see which callback I have to add the rest of the stuff in. And the colouring (the column shading), needs to be added to that gadget as well but depending on which database is showing, the colouring has to adapt so I don't know what to alter inside the callback as each database has different columns and the gadget is updated accordingly.
I'll take a look tomorrow. Today was full of backups and playing with the cat:):)
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Mon Jul 29, 2019 1:32 am
by Fangbeast
Had a play with it and don't understand how to use it. I have to be able to change the column colours whenever I need to, to cope with the fact that the gadget is changed with the number of columns to suit the database that is loaded at the time.
Same gadget, different database, different number of columns, different column colours.
Don't know how to do that with callbacks (or API in general) on demand.
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Mon Jul 29, 2019 4:55 am
by RASHAD
Hi Fang
To use the native commands for coloring the ListIcon()
You must disable the Customdraw(*lvCD.NMLVCUSTOMDRAW) in your windowcallback procedure
Code: Select all
EnableExplicit
#ColoredColumn = 0
#HeaderTextColor = #Red
#LVM_GETHEADER = #LVM_FIRST + 31
#Gadget_MyInfo_Titles = 0
Enumeration fonts
#FontStrikeoutYes
#FontStrikeoutNo
EndEnumeration
LoadFont(#FontStrikeoutYes, "", 12, #PB_Font_StrikeOut)
LoadFont(#FontStrikeoutNo, "", 12)
Procedure MainWindowCallback(hWnd, uMsg, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents
Protected *nmhdr.NMHDR, *lvCD.NMLVCUSTOMDRAW
Protected thisRow, thisCol, on_off
; Draw a line through an item to indicate its deleted state
Select uMsg
Case #WM_NOTIFY
; *nmhdr.NMHDR = lParam
;
; *lvCD.NMLVCUSTOMDRAW = lParam
;
; If IsGadget(#Gadget_MyInfo_Titles)
; If *lvCD\nmcd\hdr\hwndFrom = GadgetID(#Gadget_MyInfo_Titles) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
; Select *lvCD\nmcd\dwDrawStage
; Case #CDDS_PREPAINT
; result = #CDRF_NOTIFYITEMDRAW
; Case #CDDS_ITEMPREPAINT
; result = #CDRF_NOTIFYSUBITEMDRAW;
; Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
; thisRow = *lvCD\nmcd\dwItemSpec
; thisCol = *lvCD\iSubItem
; on_off = GetGadgetItemData(#Gadget_MyInfo_Titles, thisRow)
; ; If thisCol = 0 And on_off. Specifically for column 0. You can change this to any or just use on_off to set all columns
; If on_off
; SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutYes))
; result = #CDRF_NEWFONT; | #CDRF_DODEFAULT
; Else
; SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutNo))
; result = #CDRF_DODEFAULT
; EndIf
; EndSelect
; EndIf
; EndIf
EndSelect ; uMsg
ProcedureReturn Result
EndProcedure
OpenWindow(0, 200, 100, 400, 100, "ListIconGadget with colored header text")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
"Name", 110, #PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0,
#PB_ListIcon_ColumnWidth) - 4)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ +
"12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ +
"130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ +
"321 Logo Drive, Mouse House, Downtown")
SetGadgetItemColor(0,1,#PB_Gadget_BackColor,$16FBF8)
SetGadgetItemData(0, 1, #True)
SetWindowCallback(@MainWindowCallback())
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Mon Jul 29, 2019 6:00 am
by Fangbeast
RASHAD wrote:Hi Fang
To use the native commands for coloring the ListIcon()
You must disable the Customdraw(*lvCD.NMLVCUSTOMDRAW) in your windowcallback procedure
Code: Select all
EnableExplicit
#ColoredColumn = 0
#HeaderTextColor = #Red
#LVM_GETHEADER = #LVM_FIRST + 31
#Gadget_MyInfo_Titles = 0
Enumeration fonts
#FontStrikeoutYes
#FontStrikeoutNo
EndEnumeration
LoadFont(#FontStrikeoutYes, "", 12, #PB_Font_StrikeOut)
LoadFont(#FontStrikeoutNo, "", 12)
Procedure MainWindowCallback(hWnd, uMsg, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents
Protected *nmhdr.NMHDR, *lvCD.NMLVCUSTOMDRAW
Protected thisRow, thisCol, on_off
; Draw a line through an item to indicate its deleted state
Select uMsg
Case #WM_NOTIFY
; *nmhdr.NMHDR = lParam
;
; *lvCD.NMLVCUSTOMDRAW = lParam
;
; If IsGadget(#Gadget_MyInfo_Titles)
; If *lvCD\nmcd\hdr\hwndFrom = GadgetID(#Gadget_MyInfo_Titles) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
; Select *lvCD\nmcd\dwDrawStage
; Case #CDDS_PREPAINT
; result = #CDRF_NOTIFYITEMDRAW
; Case #CDDS_ITEMPREPAINT
; result = #CDRF_NOTIFYSUBITEMDRAW;
; Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
; thisRow = *lvCD\nmcd\dwItemSpec
; thisCol = *lvCD\iSubItem
; on_off = GetGadgetItemData(#Gadget_MyInfo_Titles, thisRow)
; ; If thisCol = 0 And on_off. Specifically for column 0. You can change this to any or just use on_off to set all columns
; If on_off
; SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutYes))
; result = #CDRF_NEWFONT; | #CDRF_DODEFAULT
; Else
; SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutNo))
; result = #CDRF_DODEFAULT
; EndIf
; EndSelect
; EndIf
; EndIf
EndSelect ; uMsg
ProcedureReturn Result
EndProcedure
OpenWindow(0, 200, 100, 400, 100, "ListIconGadget with colored header text")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
"Name", 110, #PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0,
#PB_ListIcon_ColumnWidth) - 4)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ +
"12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ +
"130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ +
"321 Logo Drive, Mouse House, Downtown")
SetGadgetItemColor(0,1,#PB_Gadget_BackColor,$16FBF8)
SetGadgetItemData(0, 1, #True)
SetWindowCallback(@MainWindowCallback())
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
But then I can't get the line drawn through the text if I want to. Is there any way around this Master RASHAD?
I need both colouring selectable whenever I want it and strikeout text always shown for deleted items.
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Mon Jul 29, 2019 9:48 am
by RASHAD
Hi Fang
Code: Select all
;EnableExplicit
#ColoredColumn = 0
#HeaderTextColor = #Red
#LVM_GETHEADER = #LVM_FIRST + 31
#Gadget_MyInfo_Titles = 0
Enumeration fonts
#FontStrikeoutYes
#FontStrikeoutNo
EndEnumeration
Global brush
brush = CreateSolidBrush_($15FBF8)
LoadFont(#FontStrikeoutYes, "", 12, #PB_Font_StrikeOut)
LoadFont(#FontStrikeoutNo, "", 12)
Procedure MainWindowCallback(hWnd, uMsg, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents
Protected *nmhdr.NMHDR, *lvCD.NMLVCUSTOMDRAW
Protected thisRow, thisCol, on_off
; Draw a line through an item to indicate its deleted state
Select uMsg
Case #WM_NOTIFY
*nmhdr.NMHDR = lParam
*lvCD.NMLVCUSTOMDRAW = lParam
If IsGadget(#Gadget_MyInfo_Titles)
If *lvCD\nmcd\hdr\hwndFrom = GadgetID(#Gadget_MyInfo_Titles) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
result = #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
result = #CDRF_NOTIFYSUBITEMDRAW;
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
thisRow = *lvCD\nmcd\dwItemSpec
thisCol = *lvCD\iSubItem
on_off = GetGadgetItemData(#Gadget_MyInfo_Titles, thisRow)
; If thisCol = 0 And on_off. Specifically for column 0. You can change this to any or just use on_off to set all columns
If on_off
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutYes))
text$ = GetGadgetItemText(0, thisRow ,thisCol)
SetBkMode_(*lvCD\nmcd\hdc,#TRANSPARENT)
FillRect_(*lvCD\nmcd\hdc, *lvCD\nmcd\rc, brush)
SetTextColor_(*lvCD\nmcd\hdc, $0000FF)
DrawText_(*lvCD\nmcd\hdc, @text$, Len(text$), *lvCD\nmcd\rc, #DT_CENTER|#DT_VCENTER|#DT_SINGLELINE|#DT_END_ELLIPSIS)
result = #CDRF_SKIPDEFAULT
Else
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutNo))
result = #CDRF_DODEFAULT
EndIf
EndSelect
EndIf
EndIf
EndSelect ; uMsg
ProcedureReturn Result
EndProcedure
OpenWindow(0, 200, 100, 400, 100, "ListIconGadget with colored header text")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
"Name", 110, #PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0,
#PB_ListIcon_ColumnWidth) - 4)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ +
"12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ +
"130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ +
"321 Logo Drive, Mouse House, Downtown")
;SetGadgetItemColor(0,1,#PB_Gadget_BackColor,$16FBF8)
SetGadgetColor(0,#PB_Gadget_BackColor,$CFFED4)
SetGadgetItemData(0, 1, #True)
SetWindowCallback(@MainWindowCallback())
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Tue Jul 30, 2019 6:25 am
by Fangbeast
Sorry RASHAD, I am lost here. You are changing the text colour in the callback and I need to change the text colour on-the-fly when I need it to accomodate each database I am using. It isn't static.
Is there any way of changing the text colour whenever I want to and still be able to draw deleted lines through text?
API is good, happy to use it, don't understand it.
Thanks for being patient with me.
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Tue Jul 30, 2019 9:49 am
by RASHAD
Hi Fang
Replace SetGadgetItemColor() with
_SetGadgetItemColor()
in your code and report if everything is OK (I hope so

)
Use it once then at any time you can enable it selcol(col) = 1 or disable it selcol(col) = 0
Code: Select all
;EnableExplicit
#ColoredColumn = 0
#HeaderTextColor = #Red
#LVM_GETHEADER = #LVM_FIRST + 31
#Gadget_MyInfo_Titles = 0
Enumeration fonts
#FontStrikeoutYes
#FontStrikeoutNo
EndEnumeration
Global backcolor,textcolor,itemtext$
Global Dim selcol(10)
backcolor = CreateSolidBrush_($15FBF8)
LoadFont(#FontStrikeoutYes, "Tahoma", 12, #PB_Font_StrikeOut)
LoadFont(#FontStrikeoutNo, "Tahoma", 12)
Procedure _SetGadgetItemColor(Gadget, Item, ColorType ,color, Col)
If ColorType = #PB_Gadget_BackColor
DeleteObject_(backcolor)
backcolor = CreateSolidBrush_(color)
ElseIf ColorType = #PB_Gadget_FrontColor
textcolor = color
EndIf
EndProcedure
Procedure MainWindowCallback(hWnd, uMsg, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents
Protected *nmhdr.NMHDR, *lvCD.NMLVCUSTOMDRAW
Protected on_off
; Draw a line through an item to indicate its deleted state
Select uMsg
Case #WM_NOTIFY
*nmhdr.NMHDR = lParam
*lvCD.NMLVCUSTOMDRAW = lParam
If IsGadget(#Gadget_MyInfo_Titles)
If *lvCD\nmcd\hdr\hwndFrom = GadgetID(#Gadget_MyInfo_Titles) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
result = #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
result = #CDRF_NOTIFYSUBITEMDRAW;
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
thisRow = *lvCD\nmcd\dwItemSpec
thisCol = *lvCD\iSubItem
on_off = GetGadgetItemData(#Gadget_MyInfo_Titles, thisRow)
; If thisCol = 0 And on_off. Specifically for column 0. You can change this to any or just use on_off to set all columns
itemtext$ = GetGadgetItemText(0,thisRow,thisCol)
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutNo))
result = #CDRF_DODEFAULT
If on_off And selcol(thisCol) = 1
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutYes))
SetBkMode_(*lvCD\nmcd\hdc,#TRANSPARENT)
FillRect_(*lvCD\nmcd\hdc, *lvCD\nmcd\rc, backcolor)
SetTextColor_(*lvCD\nmcd\hdc, textcolor)
DrawText_(*lvCD\nmcd\hdc, @itemtext$, Len(itemtext$), *lvCD\nmcd\rc, #DT_CENTER|#DT_VCENTER|#DT_SINGLELINE|#DT_END_ELLIPSIS)
result = #CDRF_SKIPDEFAULT
EndIf
EndSelect
EndIf
EndIf
EndSelect ; uMsg
ProcedureReturn Result
EndProcedure
OpenWindow(0, 0, 0, 600, 400, "ListIconGadget with colored header text",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
SetWindowCallback(@MainWindowCallback())
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
"Name", 110, #PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0,
#PB_ListIcon_ColumnWidth) - 4)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ +
"12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ +
"130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ +
"321 Logo Drive, Mouse House, Downtown")
SetGadgetColor(0,#PB_Gadget_BackColor,$E4FEE1)
SetGadgetItemData(0, 1, #True)
_SetGadgetItemColor(0, 1 , #PB_Gadget_FrontColor ,$171FFF,0)
_SetGadgetItemColor(0, 1 , #PB_Gadget_BackColor ,$CEFEFD,0)
selcol(0) = 0
selcol(1) = 1
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Tue Jul 30, 2019 9:56 am
by mk-soft
Perhaps over structure
Code: Select all
;EnableExplicit
#ColoredColumn = 0
#HeaderTextColor = #Red
#LVM_GETHEADER = #LVM_FIRST + 31
#Gadget_MyInfo_Titles = 0
Enumeration fonts
#FontStrikeoutYes
#FontStrikeoutNo
EndEnumeration
Structure udtItemInfo
On_Off.i
TextColor.i
BackColor.i
EndStructure
Global brush
brush = CreateSolidBrush_($15FBF8)
LoadFont(#FontStrikeoutYes, "", 10, #PB_Font_StrikeOut)
LoadFont(#FontStrikeoutNo, "", 10)
Procedure MainWindowCallback(hWnd, uMsg, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents
Protected *nmhdr.NMHDR, *lvCD.NMLVCUSTOMDRAW
Protected thisRow, thisCol, *ItemInfo.udtItemInfo, brush
; Draw a line through an item to indicate its deleted state
Select uMsg
Case #WM_NOTIFY
*nmhdr.NMHDR = lParam
*lvCD.NMLVCUSTOMDRAW = lParam
If IsGadget(#Gadget_MyInfo_Titles)
If *lvCD\nmcd\hdr\hwndFrom = GadgetID(#Gadget_MyInfo_Titles) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
result = #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
result = #CDRF_NOTIFYSUBITEMDRAW;
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
thisRow = *lvCD\nmcd\dwItemSpec
thisCol = *lvCD\iSubItem
*ItemInfo = GetGadgetItemData(#Gadget_MyInfo_Titles, thisRow)
; If thisCol = 0 And on_off. Specifically for column 0. You can change this to any or just use on_off to set all columns
If *ItemInfo
If *ItemInfo\On_Off
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutYes))
Else
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutNo))
EndIf
brush = CreateSolidBrush_(*ItemInfo\BackColor)
text$ = GetGadgetItemText(0, thisRow ,thisCol)
SetBkMode_(*lvCD\nmcd\hdc,#TRANSPARENT)
FillRect_(*lvCD\nmcd\hdc, *lvCD\nmcd\rc, brush)
SetTextColor_(*lvCD\nmcd\hdc, *ItemInfo\TextColor)
DrawText_(*lvCD\nmcd\hdc, @text$, Len(text$), *lvCD\nmcd\rc, #DT_CENTER|#DT_VCENTER|#DT_SINGLELINE|#DT_END_ELLIPSIS)
DeleteObject_(brush)
result = #CDRF_SKIPDEFAULT
Else
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutNo))
result = #CDRF_DODEFAULT
EndIf
EndSelect
EndIf
EndIf
EndSelect ; uMsg
ProcedureReturn Result
EndProcedure
OpenWindow(0, 200, 100, 400, 100, "ListIconGadget with colored header text")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
"Name", 110, #PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0,
#PB_ListIcon_ColumnWidth) - 4)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ +
"12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ +
"130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ +
"321 Logo Drive, Mouse House, Downtown")
;SetGadgetItemColor(0,1,#PB_Gadget_BackColor,$16FBF8)
SetGadgetColor(0,#PB_Gadget_BackColor,$CFFED4)
Dim ItemInfo.udtItemInfo(3)
ItemInfo(0)\On_Off = #False
ItemInfo(0)\BackColor = #Gray
ItemInfo(0)\TextColor = #White
ItemInfo(1)\On_Off = #True
ItemInfo(1)\BackColor = #Red
ItemInfo(1)\TextColor = #Yellow
ItemInfo(2)\On_Off = #False
ItemInfo(2)\BackColor = #Green
ItemInfo(2)\TextColor = #Black
SetGadgetItemData(0, 0, @ItemInfo(0))
SetGadgetItemData(0, 1, @ItemInfo(1))
SetGadgetItemData(0, 2, @ItemInfo(2))
SetWindowCallback(@MainWindowCallback())
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: SetGadgetItemColor doesn't work after windowcallback cod
Posted: Tue Jul 30, 2019 12:10 pm
by Fangbeast
mk-soft, you and RASHAD come up with some terrific stuff. I don't always understand it though!!!
One more question, can I address a specific column as well as a single line whenever I want to?