PDA

View Full Version : No Callbacks for timers?



ReneMiner
24-03-2021, 22:39
I just wonder if the statement in help is still up to date.
timers are not created alike


Control Add Timer

but by


Dialog Set Timer


now i wanted to use a timer on each dialog to let the dialog redraw after resizing it. And i thought, the timer knows its Daddy so i can send all the timers to the same playground errr callback to have daddy shake the sand of his head.
But help says- see picture - timers do not support their callback-function-parameter.

Anyway it were nice to know how to declare a function to be a callback function because the WinAPI has a few Functions to enumerate members of something that works only using a callback.
for example

EnumWindows Lib "Coredll.dll" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long

EnumSystemCodePages Lib "Coredll.dll" Alias "EnumSystemCodePagesA" (ByVal lpCodePageEnumProc As Long, ByVal dwFlags As Long) As Long

or

EnumFontFamilies Lib "Coredll.dll" Alias "EnumFontFamiliesA" (ByVal hdc As Long, ByVal lpszFamily As String, ByVal lpEnumFontFamProc As Long, ByVal lParam As Long) As Long

to mention some. The one i had in mind is just... hiding somewhere. It's about how to. i don't want the finished stuff but to understand how i get there myself...

Petr Schreiber
02-04-2021, 21:05
Hi Rene,

I think it is still valid, but you can have a global timer callback this way - with named dialog:


Uses "UI", "Console"


' -- ID numbers of controls
Begin ControlID
%bClose
End ControlID


Begin Const
%MAIN_WIDTH = 320
%MAIN_HEIGHT = 240
End Const


' -- Create dialog here
Function TBMain()
Local hDlg As DWord


Dialog New Pixels, name "Main", 0, "My dialog",-1,-1, %MAIN_WIDTH, %MAIN_HEIGHT, %WS_POPUP | %WS_VISIBLE | %WS_CAPTION | %WS_SYSMENU | %WS_MINIMIZEBOX To hDlg

' -- Place controls here
Control Add Button name "CloseButton", hDlg, %bClose, "Click to close", %MAIN_WIDTH-105, %MAIN_HEIGHT-30, 100, 25

Dialog Show Modal hDlg', Call cbDialog


End Function


callback function Main_OnLoad()
printl "init"
Dialog Set Timer cbhndl, 1, 1000
end function


callback function Main_OnTimer()
printl cbhndl, cbctl
end function


callback function Main_OnDestroy()
printl "de-init"
sleep 1000
Dialog kill Timer cbhndl, 1
end function


'


callback function CloseButton_OnClick()
Dialog End CBHNDL
end function

ReneMiner
03-04-2021, 01:00
yes the idea seems logically correct.

I had in mind to have an action for each dialog after it was resized it starts a timer on itself alike



'##############################################################################################
' >> Refresh of the dialog is invoked after resizing by a timer <<
CallBack Function DlgMain_OnTimer() As Long
long W,H
'-------------------------------------------------------------------


select case cbctl
case %tmr_RefreshAfterDelay
dialog get size cbhndl to w, h
dialog set size cbhndl, w + 1, h ' tiny movements horizontal
dialog set size cbhndl, w, h + 1 ' & vertical to make the
dialog set size cbhndl, w, h ' controls looking good again
dialog Redraw cbhndl
dialog kill timer cbhndl, cbctl
case %tmr_Splitports
'...
End Select

function=true ' reply the callback - else the OS will try to find another recipient
' which will sloooooooooooow doooooowwn the eeeeeeexxxeeeeccuuuuutiiiioooonnnnnnn
'-------------------------------------------------------------------'-------------------------------------------------------------------
End Function
'##############################################################################################
' >> after dialog got resized its time to redraw all objects <<
CallBack Function DlgMain_OnSizing() As Long
'-------------------------------------------------------------------
Dialog set Timer cbhndl, %tmr_RefreshAfterDelay, 50
' use of a timer to redraw the window content after resizing
' the window to prevent the content from flickering
' as long as user resizes the timer will be hold on to 50 ms...



function = true
'-------------------------------------------------------------------
End Function
'##############################################################################################

Short: it were so easy if the timers could get a callback assigned...

Or long:
its a bit much to explain. Basically i create some UI/prototype/template that works just using names. the ControlIDs are wrapped behind the curtain and are given to the dialog automatically. alike the first created dialog gets a ControlID 0x1000 / yes you read right / a controlID that the dialog starts with to enumerate its controls, the second dialog or window will start at 0x2000, the third at 0x3000 etc.
The first user assigned control to the dialog gets the dialogs ID + 1, second control get DlgID + 2 etc.
Makes the dialogID itself to be an empty slot that i wanted to use for a timer that will be handled in one timer-event function provided by the template that cares for enumerating controls also. the timer knows its ControlID in a callback and also the CBHNDL of its parent window - if it had not that - its only one dialog that has the same number as StartID for its controls as the timer in its controlID... so it were nice if all timers would meet in the same callback to refresh after resize or when other controls on the dialog changed size or an image was loaded etc. the timer would do its job and disable itself again instantly and the user would not know that it happened
the thought was i let all dialogs that can be resized or need a refresh once in a while fire their timer so AFTER the user finished resizing or moving the timer will eventually count it's 50 ms and then make it look good again. and that function should be provided without to use the named users callback-function for it since i dont know what the dialogs names will be. i thought already of using an additional control that can assigned its own callback but it"s like a cat biting it's own tail...