Page 2 of 5
Re: Object Theme Library (for Dark or Light Theme)
Posted: Wed Nov 22, 2023 1:04 am
by jacdelad
Found the culprit: Line 798 in ObjectTheme.pbi. It's a SendMessage_() call within the Callback-function. Don't know if this is even allowed, maybe it's just a timing-thing. Both demos work, if I comment it out.
Also: The ComboBox with image doesn't change color for me. Looks like it works for you.
And finally: Windows 10, x64.
Re: Object Theme Library (for Dark or Light Theme)
Posted: Wed Nov 22, 2023 11:37 am
by ChrisR
Cool that you found it
But I don't really understand why! it should be possible to send a message (even in a callback) to change the theme depending on whether the Gadget is enabled or disabled.
This is what I tried to do for the checkbox, option and TrackBar, to see the disabled state, grayed out. By changing the theme when the message WM_ENABLE is received.
I'll take another look to see how I could do it differently, thanks for the feedback

Re: Object Theme Library (for Dark or Light Theme)
Posted: Wed Nov 22, 2023 1:30 pm
by jacdelad
I'm not sure, but maybe this creates an endless recursion or something like that.
Re: Object Theme Library (for Dark or Light Theme)
Posted: Wed Nov 22, 2023 4:13 pm
by ChrisR
I've removed my SetWindowTheme tweak and also the StaticProc callback, which is no longer needed.
it's simpler and better this way.
Thanks

it's uploaded on Github v1.2
Re: Object Theme Library (for Dark or Light Theme)
Posted: Wed Nov 22, 2023 8:05 pm
by novablue
Very nice! I would like to ask if you could put as much of your code as possible into a module for better code separation?
Re: Object Theme Library (for Dark or Light Theme)
Posted: Wed Nov 22, 2023 10:16 pm
by jacdelad
I downloaded version 1.2, but it crashes again, this time at line 836, another SendMessage_() within the callback procedure.
Re: Object Theme Library (for Dark or Light Theme)
Posted: Thu Nov 23, 2023 12:12 pm
by ChrisR
Very strange, I don't know why you have this, as for the previous one, I don't reproduce despite the number of tries made.
There should be no worries, endless recursion...by using SendMessage_(lParam, #EM_SETSEL, -1, 0) in the Window Callback. There's no reason and it's been working like that for a while now in ObjectColor with no return!
And here, it is useful to deselect the ComboBox editable string if it is not the active Gadget. Otherwise, the text would be selected after each use of SetObjectTheme()
Does anyone else reproduce or have any idea why jacdelad has this error that I don't have ?
Re: Object Theme Library (for Dark or Light Theme)
Posted: Thu Nov 23, 2023 12:25 pm
by ChrisR
novablue wrote: Wed Nov 22, 2023 8:05 pm
Very nice! I would like to ask if you could put as much of your code as possible into a module for better code separation?
I'm not always a fan of modules but here it's appropriate, it works by itself, without the need for postevent()...
I've updated it as a module, on Github in version 1.3 now.
UseModule ObjectTheme is mandatory to call macros directly (e.g. ButtonGadget) without having to change existing code and use ObjectTheme::ButtonGadget.
Re: Object Theme Library (for Dark or Light Theme)
Posted: Thu Nov 23, 2023 6:34 pm
by Kuron
novablue wrote: Wed Nov 22, 2023 8:05 pm
Very nice! I would like to ask if you could put as much of your code as possible into a module for better code separation?
I would ask that he DOESN'T.
Re: Object Theme Library (for Dark or Light Theme)
Posted: Thu Nov 23, 2023 7:31 pm
by ChrisR
It shouldn't be too hard to maintain the 2 versions, standard and module, they are very close.
The 2 versions are on GitHub, the module version at the root and the standard version in the Non-Module_Version folder.
I'm a bit annoyed by jacdelad bugs that I don't understand at all, so thanks for the feedback to know how it goes for you?
In case of crash, it would be good to have Callstack infos
Re: Object Theme Library (for Dark or Light Theme)
Posted: Thu Nov 23, 2023 7:33 pm
by Little John
ChrisR wrote: Thu Nov 23, 2023 12:12 pm
Does anyone else reproduce or have any idea why jacdelad has this error that I don't have ?
I don't encounter any issues with this library here (on Windows 11). For me, version 1.3 works as well as version 1.0 did.
Re: Object Theme Library (for Dark or Light Theme)
Posted: Thu Nov 23, 2023 11:30 pm
by jacdelad
It's even getting stranger for me: I put a Debug right before said SendMessage_() and it always works about a hundred times or so before crashing at also said position.
I tried using #WM_GETTEXT and #WM_SETTEXT. It doesn't crash, but rendering doesn't work anymore...
Re: Object Theme Library (for Dark or Light Theme)
Posted: Fri Nov 24, 2023 12:16 pm
by ChrisR
Little John wrote: Thu Nov 23, 2023 7:33 pm
ChrisR wrote: Thu Nov 23, 2023 12:12 pm
Does anyone else reproduce or have any idea why jacdelad has this error that I don't have ?
I don't encounter any issues with this library here (on Windows 11). For me, version 1.3 works as well as version 1.0 did.
Thanks for your confirmation Little John.
Just for further testing, I added this snippet to ObjectTheme_Demo.pb, to change theme every 10s and with 10 call to SendMessage_(lParam, #EM_SETSEL, -1, 0) each time.
And I let it running all night, with no problems, no bugs and no memory leaks.
So it's up to jacdelad!
Code: Select all
Procedure Thread(Value)
PostEvent(#PB_Event_Gadget, #Window_1, #ApplyTheme_1, #PB_EventType_LeftClick)
Delay(Value)
CreateThread(@Thread(),10000)
EndProcedure
........
Open_Window_1()
Open_Window_2()
CreateThread(@Thread(), 10000)
Re: Object Theme Library (for Dark or Light Theme)
Posted: Fri Nov 24, 2023 2:33 pm
by dcr3
First time trying it, I haven't tried previous versions. So I can't comment on it.
On this version 1.3, It crashes on the 64bit, on the 32bit there is a stack overflow at line 1030.
Re: Object Theme Library (for Dark or Light Theme)
Posted: Fri Nov 24, 2023 4:55 pm
by ChrisR
Gulp!
If you're compiling in x64, what does the OnError window say when it crashes?
In x86, can you please send the Debug\Callstack infos, screenshot or info with lines and procedure.
There's a bit of work behind it and I wouldn't want to put it in the trash.
It seems to work well for me and Little John but not for you and jacdelad. What's wrong!!!
Does it also crash with this summary code?
And possibly, does
ObjectColor crash as well?
Code: Select all
EnableExplicit
Enumeration Window
#Window
EndEnumeration
Enumeration Gadgets
#String
#Combo
#Btn_Change_Color
EndEnumeration
Global BaseColor.l = $2A0408
Global BrushBaseColor = CreateSolidBrush_(BaseColor)
Global NewColor.l = $04082A
Global BrushNewColor = CreateSolidBrush_(NewColor)
Global BrushHighLight = CreateSolidBrush_(GetSysColor_(#COLOR_HIGHLIGHT))
Procedure SetComboDarkMode(IDGadget)
Protected ChildGadget, Buffer.s = Space(64)
If GetClassName_(IDGadget, @Buffer, 64)
If Buffer = "ComboBox"
SetWindowTheme_(IDGadget, "DarkMode_CFD", "Combobox")
EndIf
EndIf
ChildGadget = GetWindow_(IDGadget, #GW_CHILD)
If ChildGadget
Buffer = Space(64)
If GetClassName_(ChildGadget, @Buffer, 64)
If Buffer = "ComboBox"
SetWindowTheme_(ChildGadget, "DarkMode_CFD", "Combobox")
EndIf
EndIf
EndIf
EndProcedure
Procedure WinCallback(hWnd, uMsg, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents
Protected Gadget, ParentGadget, Buffer.s, Text.s
Protected *DrawItem.DRAWITEMSTRUCT
Select uMsg
Case #WM_CLOSE
PostEvent(#PB_Event_Gadget, GetDlgCtrlID_(hWnd), 0, #PB_Event_CloseWindow)
Case #WM_NCDESTROY
DeleteObject_(BrushBaseColor)
DeleteObject_(BrushNewColor)
DeleteObject_(BrushHighLight)
Case #WM_CTLCOLOREDIT
ParentGadget = GetParent_(lParam)
Buffer = Space(64)
If GetClassName_(ParentGadget, @Buffer, 64)
If Buffer = "ComboBox"
Gadget = GetDlgCtrlID_(ParentGadget)
If Gadget <> GetActiveGadget()
; TRY by commenting the SendMessage below, the text in the ComboBox edit part is selected, as long as it has not been deselected
SendMessage_(lParam, #EM_SETSEL, -1, 0) ; Deselect the ComboBox editable string if not the active Gadget
EndIf
SetTextColor_(wParam, #White)
SetBkMode_(wParam, #TRANSPARENT)
If GetWindowColor(#Window) = BaseColor
ProcedureReturn BrushBaseColor
Else
ProcedureReturn BrushNewColor
EndIf
EndIf
EndIf
Case #WM_DRAWITEM
*DrawItem.DRAWITEMSTRUCT = lParam
If *DrawItem\CtlType = #ODT_COMBOBOX And IsGadget(wParam) And *DrawItem\itemID <> -1
If *DrawItem\itemstate & #ODS_SELECTED
FillRect_(*DrawItem\hDC, *DrawItem\rcitem, BrushHighLight)
Else
If GetWindowColor(#Window) = BaseColor
FillRect_(*DrawItem\hDC, *DrawItem\rcitem, BrushBaseColor)
Else
FillRect_(*DrawItem\hDC, *DrawItem\rcitem, BrushNewColor)
EndIf
EndIf
SetBkMode_(*DrawItem\hDC, #TRANSPARENT)
SetTextColor_(*DrawItem\hDC, #White)
Text = GetGadgetItemText(*DrawItem\CtlID, *DrawItem\itemID)
*DrawItem\rcItem\left + DesktopScaledX(4)
DrawText_(*DrawItem\hDC, Text, Len(Text), *DrawItem\rcItem, #DT_LEFT | #DT_SINGLELINE | #DT_VCENTER)
EndIf
EndSelect
ProcedureReturn Result
EndProcedure
Procedure Open_Window(X = 0, Y = 0, Width = 220, Height = 175)
Protected I
If OpenWindow(#Window, X, Y, Width, Height, "CTLCOLOREDIT", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
SetWindowColor(#Window, BaseColor)
StringGadget(#String, 20, 20, 180, 24, "String")
SetGadgetColor(#String, #PB_Gadget_FrontColor, #White)
SetGadgetColor(#String, #PB_Gadget_BackColor, BaseColor)
ComboBoxGadget(#Combo, 20, 65, 180, 28, #PB_ComboBox_Editable | #CBS_HASSTRINGS | #CBS_OWNERDRAWFIXED)
SendMessage_(GadgetID(#Combo), #CB_SETMINVISIBLE, 5, 0)
For I = 1 To 10 : AddGadgetItem(#Combo, -1, "Combo Element " + Str(I)) : Next
SetGadgetState(#Combo, 0)
ButtonGadget(#Btn_Change_Color, 20, 115, 180, 40, "Change_Color")
SetComboDarkMode(GadgetID(#Combo))
SetWindowCallback(@WinCallback(), #Window)
ProcedureReturn #True
EndIf
EndProcedure
If Open_Window()
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case #Btn_Change_Color
If GetWindowColor(#Window) = BaseColor
SetWindowColor(#Window, NewColor)
SetGadgetColor(#String, #PB_Gadget_BackColor, NewColor)
Else
SetWindowColor(#Window, BaseColor)
SetGadgetColor(#String, #PB_Gadget_BackColor, BaseColor)
EndIf
EndSelect
EndSelect
ForEver
EndIf