Jump to content

How to get WM_TIMER to work


PvS1
 Share

Recommended Posts

Hi All,

I am a happy user of AutoIT and trying to make an application. I ran into something I cannot get to work:

Setting up a timer sending WM_TIMER messages to the messageloop.

I created a small testapp that tries to setup such a timer and in addition setups a timer to a callback:

1x every 1000ms to callback - This one works

1x every 1900ms sending WM_TIMER - This does not happen

How should setting up a WM_TIMER message be done?

Test-timer.au3

Remark:

While trying and testing I also found my test program receives A LOT OF '0' messages, on my old notebook once about every 15 ms. This behaviour can be seen when line 62 is uncommented.

I am running on XP SP3 and using AutoIT 3.3.8.1

Link to comment
Share on other sites

The helpfile do say that GUIGetMsg() returns 0 and idles the CPU when there's no event, but at the same time it says nothing about receiving Windows Messages, so I don't know what you're thinking there...

How should setting up a WM_TIMER message be done?

Look up GUIRegisterMsg() ;)

Also depending on what you're doing, the native AdlibRegister() may just be enough, so check that out too.

Link to comment
Share on other sites

BTW, you're not actually "sending" any WM_TIMER messages anywhere in your script. I think you're confused as to what it is that you are doing.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Please check if you are referring this.In your code WM_TIMER is not used properly.

Replace This :

Case $WM_TIMER

LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received WM_TIMER event")

With :

Case $Timer_1

LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received Timer_1 event")

Case $Timer_2

LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received Timer_2 event")

This is how the timer event is sent to GUI.

Link to comment
Share on other sites

Uhm... Sometimes it's better not to say anything if you don't know what you're talking about.

Rather than being insulting, how about pointing out where I'm wrong so we all learn something?

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

If you really want to get thses events in your loop you can use a Dummy control.

#include <GUIConstantsEx.au3>
#include <ListboxConstants.au3>
#include <WindowsConstants.au3>
#include <ScrollBarConstants.au3>
#include <File.au3>
#include <Timers.au3>

Dim $LogWindow=0

Func CreateLogWindow($Title,$Width,$Height)
    If $LogWindow<>0 Then
        MsgBox(0,"Internal Error","Log window was already created")
        Return
    EndIf
    GUICreate($Title,$Width,$Height)
    $LogWindow=GUICtrlCreateList("",5,5,$Width-10,$Height-10,$LBS_NOSEL+$WS_VSCROLL)
    GUISetState()
EndFunc

Func LogString($LogText)
    If $LogWindow=0 Then
        MsgBox(0,"Internal Error","Log window used but not yet created")
        CreateLogWindow("LogWindow",800,300)
    EndIf
    GUICtrlSetData($LogWindow,$LogText)
    GUICtrlSendMsg($LogWindow,$WM_VSCROLL,$SB_LINEDOWN,0)
EndFunc

; Start of program
Global $Dummy
CreateLogWindow("Log",900,500)

$MainWindow=GUICreate("Test-1",370,86) ; The main window
$Button_1=GUICtrlCreateButton("Button_1",10,53)
$Button_2=GUICtrlCreateButton("Button_2",100,53)
$Exit=GUICtrlCreateButton("Cancel (Exit)",190,53)
$Dummy = GUICtrlCreateDummy()
GUISetState()

$Timer_1=_Timer_SetTimer($MainWindow,1000,"TimerCallback",-1)
LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Started Timer_1 1000ms")
$Timer_2=_Timer_SetTimer($MainWindow,1900,"TimerCallback",-1)
LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Started Timer_2 1900ms")

$cnt=0

While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case $Dummy
            Switch GUICtrlRead($Dummy)
                Case $Timer_1
                    LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received event via Timer_1")
                Case $Timer_2
                    LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received event via Timer_2")
            EndSwitch
        Case $Button_1
            LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received Button_1 event")
        Case $Button_2
            LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received Button_2 event")
        Case $Exit
            LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received Exit event")
            MsgBox(0,"Handling Exit event","Exiting")
            Exit
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func TimerCallback($hWnd, $Msg, $iIDTimer, $dwTime)
    GUICtrlSendToDummy($Dummy,$iIDTimer)
EndFunc
Edited by Andreik
Link to comment
Share on other sites

Hi All,

Thanks for all the responses. I checked all of them, please read my response below

AdmiralAlkex:

- The helpfile do say that GUIGetMsg() returns 0 and idles the CPU when there's no event

==> I agree. But I consider receiving something like 70 msg per sec as a waste of CPU instead of as idling the CPU.

- Setting up WM_TIMER through GUIRegisterMsg()

==> GUIRegisterMsg() is intended to attach a callback function with a particular windows message, something I already managed to do this for Timer_1 by providing a callback function to _Timer_SetTimer()

- Setting up WM_TIMER through AdlibRegister()

==> AdlibRegister() is intended to define a callback which is called every 250ms

BrewManNH

- you're not actually "sending" any WM_TIMER messages anywhere in your script

==> Hmmm, I intended to have WM_TIMER messages sent by calling _Timer_SetTimer() without callback and TimerID=-1. If so where are the WM_TIMER messages sent?

Bhuvani:

- Replace WM_TIMER with Timer_1 and Timer_2

==> I tried this but no effect

Andreik:

- Updated my script to have the TImer_1 callback function send messages which can subsequently be catched in the message loop

==> I understand the solution, now the messages end up in the messageloop.

From all responses I understand:

- I have not seen any solution for the WM_TIMER messages as set-up by my script to be catched by my script, it remains unclear where they are sent.

- There is a possibility to implement what I want by first having a callback be called and then from the callback inject a message into the message loop.

Kind Regards

PvS-1

Link to comment
Share on other sites

What about this?

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.8.1
 Author:         myName

 Script Function:
    Template AutoIt script.

#ce ----------------------------------------------------------------------------

; Script Start - Add your code below here
#include <GUIConstantsEx.au3>
#include <ListboxConstants.au3>
#include <WindowsConstants.au3>
#include <ScrollBarConstants.au3>
#include <File.au3>
#include <Timers.au3>

Dim $LogWindow=0

Func CreateLogWindow($Title,$Width,$Height)
    If $LogWindow<>0 Then
        MsgBox(0,"Internal Error","Log window was already created")
        Return
        EndIf
    GUICreate($Title,$Width,$Height)
    $LogWindow=GUICtrlCreateList("",5,5,$Width-10,$Height-10,$LBS_NOSEL+$WS_VSCROLL)
    GUISetState()
    EndFunc

Func LogString($LogText)
    If $LogWindow=0 Then
        MsgBox(0,"Internal Error","Log window used but not yet created")
        CreateLogWindow("LogWindow",800,300)
        EndIf
    GUICtrlSetData($LogWindow,$LogText)
    GUICtrlSendMsg($LogWindow,$WM_VSCROLL,$SB_LINEDOWN,0)
    EndFunc

Func TimerCallback($hWnd, $Msg, $iIDTimer, $dwTime)
    LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Called TimerCallback()")
    EndFunc

; Start of program
CreateLogWindow("Log",900,500)

$MainWindow=GUICreate("Test-1",370,86) ; The main window
$Button_1=GUICtrlCreateButton("Button_1",10,53)
$Button_2=GUICtrlCreateButton("Button_2",100,53)
$Exit=GUICtrlCreateButton("Cancel (Exit)",190,53)
GUISetState()

$Timer_1=_Timer_SetTimer($MainWindow,1000,"TimerCallback",-1)
LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Started Timer_1 1000ms")
$Timer_2=_Timer_SetTimer($MainWindow,1900,"",-1)
LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Started Timer_2 1900ms")

$cnt=0
$Dummy_WM_TIMER = GUICtrlCreateDummy()
GUIRegisterMsg($WM_TIMER, "WM_TIMER")

While 1
    $Msg = GUIGetMsg()
;   LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received event"&$Msg)
    Switch $Msg
        Case $Dummy_WM_TIMER
            LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received WM_TIMER event")
        Case $Button_1
            LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received Button_1 event")
        Case $Button_2
            LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received Button_2 event")
        Case $Exit
            LogString(@HOUR&":"&@MIN&":"&@SEC&":"&@MSEC&": Received Exit event")
            MsgBox(0,"Handling Exit event","Exiting")
            Exit
        Case $GUI_EVENT_CLOSE
            GUIRegisterMsg($WM_TIMER, "WM_TIMER")
            GUIDelete()
            Exit
        EndSwitch
    WEnd

    Func WM_TIMER($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $ilParam

    Switch _Timer_GetTimerID($iwParam)
        Case $Timer_2
            GUICtrlSendToDummy($Dummy_WM_TIMER)
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_TIMER

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

It's a little bit different. My 1st idea was the same as yours and I thought I can post something bit different.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Hi All,

From all responses I understand:

- I have not seen any solution for the WM_TIMER messages as set-up by my script to be catched by my script, it remains unclear where they are sent.

They are sent to the message queue, where all messages live a happy life until the evil window procedure snatches them. You could subclass the window, but that seems overkill for just a timer. Why don't go with the simpler GUIRegisterMsg()?

==> AdlibRegister() is intended to define a callback which is called every 250ms

Unless you specify another time...
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...