Using SetTimer function without including windows.bi

Windows specific questions.
k4rl3on
Posts: 7
Joined: Dec 20, 2011 13:23

Using SetTimer function without including windows.bi

Postby k4rl3on » Dec 20, 2011 13:38

Hi,
i'm trying to use SetTimer function without including windows.bi which contain lot of declarations, types and includes, i need just the function SetTimer to set a timer... here is what i tried to do, i created 2 files: myprog.bas and headerz.bi:

code in headerz.bi:

Code: Select all

extern "windows" lib "user32"
    Declare Function SetTimer (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
end extern


code in myprog.bas:

Code: Select all

#include "headerz.bi"

Private Sub Test()
    Print "a"
End Sub

SetTimer (0, 1, 1000, @Test)
Sleep


when prog runs, i have a warning:
Passing pointer to scalar, at parameter 4 of SETTIMER()
and nothing apears on screen.

If some one can help :/
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Postby MichaelW » Dec 20, 2011 15:14

For the timer to work the calling thread must dispatch messages.

http://msdn.microsoft.com/en-us/library ... 85%29.aspx

I included windows.bi just as a convenience:

Code: Select all

''==============================================================================
#include "windows.bi"
''==============================================================================

'screenres 800,600,32

sub TimerProc( byval hwnd as HWND, _
               byval uMsg as UINT, _
               byval idEvent as UINT_PTR, _
               byval dwTime as DWORD )
    print "*";
end sub

''==============================================================================

SetTimer( 0, 0, 500, @TimerProc )

dim msg as MSG
do until( GetMessage( @msg, null, 0, 0 ) = 0 )
    if multikey(1) then exit do
    DispatchMessage( @msg )
loop
fxm
Posts: 9989
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Postby fxm » Dec 20, 2011 15:43

In graphic window mode only, under fbgfx, you can more rustically activate the SetTimer function:

Code: Select all

Extern "windows" Lib "user32"
    Declare Function SetTimer (Byval hwnd As Any Ptr, ByVal nIDEvent As Uinteger, Byval uElapse As Uinteger, Byval lpTimerFunc as Sub()) As Uinteger
    Declare Function KillTimer (Byval hwnd As Any Ptr, ByVal nIDEvent As Uinteger) As Integer
End Extern

Function GetHandle () As Any Ptr
    Dim HandleWindow As Any Ptr
    Screencontrol(2, Cast(Integer, HandleWindow))
    Function = HandleWindow
End Function



Private Sub Test()
    Print "a";
End Sub

Screen 12
Print "Test SetTimer function in graphic window mode under fbgfx:"
Print "Printing 'a' at each second, until keypress to quit"
SetTimer (GetHandle(), 1, 1000, @Test)
Sleep
KillTimer(GetHandle(), 1)
k4rl3on
Posts: 7
Joined: Dec 20, 2011 13:23

Postby k4rl3on » Dec 20, 2011 15:51

Thank you MichaelW, but i'm looking for how to use the function without including windows.bi, fxm that means i should use the graphic mode?
Thank you
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Postby MichaelW » Dec 20, 2011 16:06

k4rl3on wrote:Thank you MichaelW, but i'm looking for how to use the function without including windows.bi,

It looks like you already know how to do that - I was showing you what you don’t know. I included windows.bi as convenience so I would not have to add the necessary declarations to my code.
fxm
Posts: 9989
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Postby fxm » Dec 20, 2011 16:08

My above simplified code only works in graphic mode under fbgfx.
It does not work in text mode, even if you provide the handle of the text window.
Last edited by fxm on Dec 20, 2011 16:39, edited 1 time in total.
k4rl3on
Posts: 7
Joined: Dec 20, 2011 13:23

Postby k4rl3on » Dec 20, 2011 16:14

Sorry MichaelW for the misunderstanding caused by my bad english, does the parameter GFX_NULL in Screen 12, , ,"GFX_NULL" hide the windows
Thnx again
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Postby MichaelW » Dec 20, 2011 17:19

With GFX_NULL you must provide your own window and event handling. See the GFX_NULL examples.
k4rl3on
Posts: 7
Joined: Dec 20, 2011 13:23

Postby k4rl3on » Dec 20, 2011 17:32

Thnx a lot
pestery
Posts: 493
Joined: Jun 16, 2007 2:00
Location: Australia

Postby pestery » Dec 21, 2011 4:55

One way to separate your code from windows.bi is to use 2 or more modules. That way you can have you main code in one module and the functions that require windows.bi in the other module.

I tried to make an example using MichaelW's example, but it's too reliant on window.bi to be separated. Instead I found an old example using the Windows clipboard that I could use.
Compile using: fbc "main.bas" "os_spec.bas"

header.bi

Code: Select all

' Clipboard functions
Declare Function clipboard_get_string() As String
Declare Sub clipboard_set_string(ByRef text As String)

main.bas

Code: Select all

#Include "header.bi"

' Main code
Color 2 : Print " --- Checking clipboard for data ---"
Color 7 : Print clipboard_get_string()
Color 2 : Print " --- End of clipboard data ---"
Color 7
Sleep

os_spec.bas

Code: Select all

#Include "header.bi"

' Include library headers
#Include "windows.bi"

' Clipboard functions
Function clipboard_get_string() As String
   
   ' Define Windows clipboard code
   #If Defined(__FB_WIN32__)
   If IsClipboardFormatAvailable(CF_TEXT) = 0 Then Return ""
   Dim As String text
   Dim As ZString Ptr text_ptr
   Dim As HANDLE hglb
   If OpenClipboard(NULL) = 0 Then Return ""
   hglb = GetClipboardData(CF_TEXT)
   text_ptr = GlobalLock(hglb)
   If text_ptr Then text = *text_ptr
   GlobalUnlock(hglb)
   CloseClipboard
   Return text
   
   ' Define Linux clipboard code
   #ElseIf Defined(__FB_LINUX__)
   ' --- Add code for linux ---
   Return ""
   
   ' Error if not Windows ot Linux
   #Else
   #Error "Must compile for Windows or Linux"
   Return ""
   #EndIf
End Function
Sub clipboard_set_string(ByRef text As String)
   
   ' Define Windows clipboard code
   #If Defined(__FB_WIN32__)
   Dim As ZString Ptr text_ptr
   Dim As HANDLE hglb
   hglb = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, Len(text)+1)
   If hglb = 0 Then Exit Sub
   If OpenClipboard(NULL) = 0 Then
      GlobalFree(hglb)
      Exit Sub
   EndIf
   EmptyClipboard()
   text_ptr = GlobalLock(hglb)
   *text_ptr = text
   GlobalUnlock(hglb)
   SetClipboardData(CF_TEXT, hglb)
   CloseClipboard
   
   ' Define Linux clipboard code
   #ElseIf Defined(__FB_LINUX__)
   ' --- Add code for linux ---
   
   ' Error if not Windows ot Linux
   #Else
   #Error "Must compile for Windows or Linux"
   #EndIf
End Sub
TJF
Posts: 3604
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Postby TJF » Dec 21, 2011 11:03

@k4rl3on:

Here's an alternative without windows.bi (extended by a count-down). It uses a GLib timer and the code is cross-platform running on windows and LINUX (and maybe in future all GLib supporting OSs, ie like Mac OSX):

Code: Select all

#INCLUDE ONCE "gtk/glib.bi"

PRIVATE FUNCTION Test CDECL (BYVAL user_data AS gpointer) AS gboolean
  VAR count = CAST(INTEGER PTR, user_data)
  PRINT "a", *count
  *count -= 1
  RETURN IIF(*count <= 0, FALSE, TRUE)
END FUNCTION

VAR Loops = 5
VAR TimeOut = g_timeout_add(500, @Test(), @Loops)

VAR MainContext = g_main_context_default()
DO
  g_main_context_iteration(MainContext, TRUE)
LOOP UNTIL Loops <= 0

For details see GLib documentation: The Main Event Loop.
TJF
Posts: 3604
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Postby TJF » Dec 21, 2011 11:59

Just when I posted the last example I remembered a simple solution:

Another variant, without windows.bi and cross-platform

Code: Select all

VAR Loops = 5

PRIVATE SUB Test(BYVAL Quit AS ANY PTR)
  WHILE *CAST(INTEGER PTR, Quit) > 0
    PRINT "a", *CAST(INTEGER PTR, Quit)
    *CAST(INTEGER PTR, Quit) -= 1
    SLEEP 500
  WEND
END SUB

VAR Thread = THREADCREATE(@Test, @Loops)

SLEEP
Loops = 0

THREADWAIT(Thread)
k4rl3on
Posts: 7
Joined: Dec 20, 2011 13:23

Postby k4rl3on » Dec 21, 2011 16:06

thank you TJF for the second code, i think that what i'm looking for, only one problem: the while occupy 100% cpu ressource which means i return to the beginning, i wanted to repalce my while loop by a timer to avoid a 100% cpu ressouces using.
fxm
Posts: 9989
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Postby fxm » Dec 21, 2011 16:16

k4rl3on wrote:the while occupy 100% cpu ressource

No because of 'Sleep' inside the 'While' block.
I measured 0% cpu!

Remark: it is better to replace:
SLEEP 500
with:
SLEEP 500, 1
in order that the thread ignores any keypress.
k4rl3on
Posts: 7
Joined: Dec 20, 2011 13:23

Postby k4rl3on » Dec 21, 2011 16:21

Yes with the print instruction it's okay, but when the procedure Test contain more instructions and calls to other functions and procedures the cpu occupation jump to 100% :/ there is a way to limit the thread usage of cpu ressource ?

Return to “Windows”

Who is online

Users browsing this forum: No registered users and 4 guests