Oxygen Basic

Programming => Problems & Solutions => Topic started by: Aurel on March 19, 2012, 09:58:31 AM

Title: DoEvents
Post by: Aurel on March 19, 2012, 09:58:31 AM
Hi..
The way how doevents function work is not very good option for gui
programming at all.
It is a good option for games.
Im looking into a way to simplify message loop,
what would be simpliest solution?
creating some sort of callback function in OpenWindow(setwindow) function or
maybe something else.
I also lookin in Xblite option.
any suggestion....?
Title: Re: DoEvents
Post by: Aurel on March 21, 2012, 07:21:51 AM
I stuck again with message processing.
Example is translated from xblite example.
Is anyone here who can explain me why message is not translated or dispatched:
Code: [Select]
Include "awinh.inc"
#lookahead ' for procedures

INT win
INT winstyle
INT button1
INT ed1
INT Lb1

winstyle = WS_MINMAXSIZE or WS_CLIPCHILDREN
'create window
win = SetWindow("Test AwinH",100,100,640,480,winstyle)
print str(win)
'create button
button1 = SetButton(win,200,40,80,24,"button_1",0x50000001,0x200)
'create edit control
ed1 = SetEditBox(win,200,80,80,24,"edit 1",0,0)
'create listbox
Lb1 = SetListBox(win,200,140,180,240,"LB 1",0,0)


'WHILE GetMessage (&wm,0,0,0)<>0
'TranslateMessage &wm
'DispatchMessage &wm
'WEND
sys bRet
  '
  do while bRet := GetMessage (&wm, 0, 0, 0)
    if bRet = -1 then
      'show an error message
    else
      TranslateMessage &wm
      DispatchMessage &wm
    end if
  wend


FUNCTION WndProc(byval win as INT,byval wMsg as INT,byval wParam as INT,byval lParam as INT)as INT callback

SELECT wMsg
'----------------------------

CASE WM_DESTROY
PostQuitMessage 0
'--------------------------------------
CASE WM_COMMAND
controlID = LoWord(wParam)
notifyCode = HiWord(wParam)

SELECT notifyCode

CASE BN_CLICKED

select controlID
             case button1
    Print str(button1)
end select


END SELECT





CASE ELSE
FUNCTION = DefWindowProc win,wMsg,wParam,lParam

END SELECT


END FUNCTION



Title: Re: DoEvents
Post by: Aurel on March 21, 2012, 10:58:24 AM
I search more and almost think that something is wrong because i can't
intercept wMsg then i test message wm_destroy like this:
Code: [Select]
SELECT wMsg
'----------------------------

CASE WM_DESTROY
PRINT "CLOSED"
PostQuitMessage 0
'--------------------------------------
CASE WM_COMMAND
controlID = LoWord(wParam)
notifyCode = HiWord(wParam)

SELECT notifyCode

CASE BN_CLICKED

select controlID
             case button1
    Print str(button1)
end select

And it works but why then wm_command don't work is a mistery  :-\
it is really weird.
i will try more... ;)
Title: Re: DoEvents
Post by: Aurel on March 21, 2012, 11:49:18 AM
Hmmm i finally got to work something but still not as i espected :-\
BN_CLICKED respond but on every control which is created  ::)
It looks that don't respond on controlID = LoWord(wParam)
So , i will try check again function LoWord....
Title: Re: DoEvents
Post by: Charles Pegge on March 21, 2012, 08:12:01 PM

Hi Aurel,

Could we see AWinh.inc?

Charles
Title: Re: DoEvents
Post by: Aurel on March 21, 2012, 10:49:40 PM
yes of course..
nothing special as i say before just derived from peter wFunc ,and i just remove
wndproc function.

I'm not sure but LoWord & HiWord functions looks little bit weird to me.
what is exactly:
and lo,&hffff
shr hi,16
shr->what's that mean  ???

another thing which i probably made wrong is when i create control.
Each control is without ID  ::)
just return hendle this might couse problem,right?
like:
Code: [Select]
hButton = CreateWindowEx(_ext,"BUTTON",_btext,_bflag,_bx,_by,_bw,_bh,_bhwnd,0,0,0)and better will be:
Code: [Select]
hButton = CreateWindowEx(_ext,"BUTTON",_btext,_bflag,_bx,_by,_bw,_bh,_bhwnd,controlID,0,0)
hmmm....what you mean ?
Title: Re: DoEvents
Post by: Aurel on March 22, 2012, 03:29:31 AM
YES...
I finally got it what is wrong ,i add control ID in SetButton() function and work.
Code: [Select]
'syn : SetButton (hwnd,x,y,w,h,caption$,style,ext,controlID)
Function SetButton(byval _bhwnd as int,byval _bx as int,byval _by as int,byval _bw as int,byval _bh as int, byval _btext as string,byval _bflag as int,byval _ext as int,byval _cID as INT) as int
If _bflag=0
    _bflag = 0x50000000
EndIf
_ext = 0
hButton = CreateWindowEx(_ext,"BUTTON",_btext,_bflag,_bx,_by,_bw,_bh,_bhwnd,_cID,0,0)
UpdateWindow _bhwnd
Function = hButton
End Function

Note:this function is inside awinh.inc
So now example code look like this :
Code: [Select]
Include "awinh.inc"
#lookahead ' for procedures

INT win
INT winstyle
INT button1,button2
INT ed1
INT Lb1
int ed2
INT b1ID,b2ID,b3ID,b4ID,b5ID,b6ID,b7ID
b1ID=100
b1ID=101
b1ID=102
b1ID=103
b1ID=104
b1ID=105

winstyle = WS_MINMAXSIZE or WS_CLIPCHILDREN
'create window
win = SetWindow("Test AwinH",100,100,640,480,winstyle)

'create buttons
button1 = SetButton(win,200,40,80,24,"button_1",0x50000001,0x200,b1ID)
button2 = SetButton(win,300,40,80,24,"button_2",0x50000001,0x200,b2ID)

'create edit control
ed1 = SetEditBox(win,200,80,80,24,"edit 1",0,0)
'create listbox
Lb1 = SetListBox(win,200,140,180,240,"LB 1",0,0)


'WHILE GetMessage (&wm,0,0,0)<>0
'TranslateMessage &wm
'DispatchMessage &wm
'WEND
sys bRet
  '
  do while bRet := GetMessage (&wm, 0, 0, 0)
    if bRet = -1 then
      'show an error message
    else
      TranslateMessage &wm
      DispatchMessage &wm
    end if
  wend



Function WndProc(byval hWnd as long,byval wMsg as long, byval wParam as long,byval lparam as long) as long callback

SELECT wMsg
'----------------------------

CASE WM_DESTROY
PostQuitMessage 0
'-------------------------------------------------------------
CASE WM_COMMAND
controlID = LoWord(wparam) 'get control ID
notifyCode = HiWord(wParam) 'get notification message

Select controlID
   Case b1ID
If notifycode=0         
    Print "Button 1 Clicked!"
End If
   Case b2ID
     If notifycode=0         
    Print "Button 2 Clicked!"
End If



End Select
'-----------------------------------------------------
END SELECT




FUNCTION = DefWindowProc hwnd,wMsg,wParam,lParam



END FUNCTION



Title: Re: DoEvents
Post by: Aurel on March 22, 2012, 02:09:47 PM
Next step is set default gui font and add string to listbox.
Look into attachment,manifest work fine ;)

Code: [Select]
Include "awinh.inc"
#lookahead ' for procedures

INT win
INT winstyle
INT button1,button2
INT edit1,edit2,edit3
INT Lbox
INT ed1ID,ed2ID,ed3ID
INT b1ID,b2ID,b3ID,b4ID,b5ID,b6ID,b7ID
INT LboxID=300
b1ID=100
b1ID=101
b1ID=102
b1ID=103
b1ID=104
b1ID=105

ed1ID=200
ed2ID=201
ed3ID=202

winstyle = WS_MINMAXSIZE or WS_CLIPCHILDREN
'create window
win = SetWindow("Test AwinH",100,100,640,480,winstyle)

'create buttons
button1 = SetButton(win,200,40,80,24,"button_1",0x50000000,0x200,b1ID)
button2 = SetButton(win,300,40,80,24,"button_2",0x50000000,0x200,b2ID)

'create edit control
edit1 = SetEditBox(win,200,80,180,24,"edit 1",0x50004000,0x200,ed1ID)
'create listbox
Lbox = SetListBox(win,200,140,180,240,"LB 1",0x50000140,0x200,LboxID)
SendMessage Lbox,LB_ADDSTRING,0,"First Item"

'WHILE GetMessage (&wm,0,0,0)<>0
'TranslateMessage &wm
'DispatchMessage &wm
'WEND
sys bRet
  '
  do while bRet := GetMessage (&wm, 0, 0, 0)
    if bRet = -1 then
      'show an error message
    else
      TranslateMessage &wm
      DispatchMessage &wm
    end if
  wend



Function WndProc(byval hWnd as long,byval wMsg as long, byval wParam as long,byval lparam as long) as long callback

SELECT wMsg
'----------------------------

CASE WM_DESTROY
PostQuitMessage 0
'-------------------------------------------------------------
CASE WM_COMMAND
controlID = LoWord(wparam) 'get control ID
notifyCode = HiWord(wParam) 'get notification message

Select controlID
   Case b1ID
If notifycode=0         
    Print "Button 1 Clicked!"
End If
   Case b2ID
     If notifycode=0         
    Print "Button 2 Clicked!"
End If



End Select
'-----------------------------------------------------
END SELECT




FUNCTION = DefWindowProc hwnd,wMsg,wParam,lParam



END FUNCTION



Title: Re: DoEvents
Post by: izzy77 on March 22, 2012, 03:18:24 PM
SHR

Means Shift right the bits in a value. shr hi,16


A wparam is a 4 byte variable and the two most significant bytes are considered the Hiword of the wparam.

The two least significant bytes are the Loword of the wparam.

To get the value of the Hiword out of the wparam you shift the value 16 bits to the right which places the Hiword in the Loword position and it can be extracted as a word value this way.
Title: Re: DoEvents
Post by: Aurel on March 22, 2012, 10:20:02 PM
thanks izzy77 on explanation ;)
Title: Re: DoEvents
Post by: Aurel on March 23, 2012, 03:03:10 PM
Small step next...added bitmap button.
Code: [Select]
'loadbmp
'##########################################
INT bmpB1
bmpB1 = LoadImage(0,"data/xpBopen.bmp",0,76,20,16)

then:
Code: [Select]
button1 = SetButton(win,200,40,80,24,"",0x50000080,0x200,b1ID)
'set bitmap on button 1
SendMessage button1 , BM_SETIMAGE, 0, bmpB1
Title: Re: DoEvents
Post by: Aurel on March 29, 2012, 01:56:10 PM
Just tested and added static control creation.
Here is code:
Code: [Select]
'create static control
static1 = SetStatic(win,10,20,254,16," This is a STATIC text control with EX_CLIENTEDGE",0,0x200,st1ID)
static2 = SetStatic(win,10,40,254,13," This is a STATIC text control without ex_ClientEdge     ",0,0,st1ID)
'crete static control with bitmap
static3 = SetStatic(win,10,60,82,82,"",0x5000030E,0,st3ID)
SendMessage static3 ,370, 0, bmpS1

In attachment is screenshot how look.
Title: Re: DoEvents
Post by: kryton9 on March 29, 2012, 09:50:53 PM
Looking good!
Title: Re: DoEvents
Post by: Aurel on March 29, 2012, 09:51:46 PM
Thanks Kent ;)
Title: Re: DoEvents
Post by: Aurel on March 30, 2012, 12:00:31 PM
I try to add function SetText and found some weird problem.
When i try to change edit control text with:
Code: [Select]
SUB SetControlText
string n$
int n=3


n$ = str(n)
print n$   '....this work properly
SendMessage edit1,WM_SETTEXT,1,n$
but  text in control is not changed ???
So i try change variable type to sys n$="new text"
and sometimes work and sometimes not.

Title: Re: DoEvents
Post by: Aurel on March 30, 2012, 12:10:10 PM
Infact n$ = str(n) don't work if n$ is defined as string .
which is really weird to me ???
Title: Re: DoEvents
Post by: Aurel on March 30, 2012, 12:16:30 PM
Oh my ,oh my i am really confused with all this string types.
It looks that i must use bString  instead of just string.
So it looks that this work:
Code: [Select]
SUB SetControlText
bstring n$
n$=""
n$ = str(10)
SendMessage edit1,WM_SETTEXT,0,n$
'UpdateWindow(edit1)
END SUB

I will try this inside loop... ;)
Title: Re: DoEvents
Post by: Aurel on March 30, 2012, 12:35:09 PM
OK,here is part with for loop,and work fine ;)
Code: [Select]
SUB SetControlText
bstring n$
n$=""

'loop
For i = 0 To 10000
n$ = Str(i)
SendMessage edit1,WM_SETTEXT,0,n$
UpdateWindow(edit1)
Next i


END SUB
Title: Re: DoEvents
Post by: Charles Pegge on March 31, 2012, 07:55:43 AM
Hi Aurel

Oxygen ignores % and $ endings, so you were using the same variable when you intended to have 2 different variable types named n.

Bstrings are not garbage collected, so you need to free them when finished.

frees n



But if you prefer to use standard strings with the win64.inc definition of SendMessage: (it has not been given a prototype)

string n
....
SendMessage edit1,WM_SETTEXT,0,*n$




Charles
Title: Re: DoEvents
Post by: Aurel on March 31, 2012, 08:23:39 AM
Quote
Bstrings are not garbage collected, so you need to free them when finished.
-Hmmm ok,but it looks that don't couse any problems after exiting.

Charles,i even don't look into win64.h as you may see i prefer my own version of header,
by the way i don't think that is something wrong with win64.h.

I mean that win64 is only used for 64bit systems and almost forget about what is it.
my fault...
And one weird thing to me *n$ - it looks like pointer of n.string ,right?
And yeah,i still use 034 version,heh work fine for me,sounds strange maybe...
thanks on reply...
Title: Re: DoEvents
Post by: Charles Pegge on March 31, 2012, 10:25:03 AM

If local Bstrings are left to accumulate, they will eventually fill the entire memory space while the program is running. The problem does not usually reveal itself in short-run programs, but task-manager is useful for spotting memory leaks of this kind.

Peter's win64.inc and my MinWin.inc both have some API calls - low level, without prototypes which mean that the parameters have to be a perfect match.

But when functions are declared in the usual way, type matching and byval/byref are automatically handled by the compiler. Then no need for '*'
when passing string n$.

Like PowerBasic strings, OxygenBasic strings are double pointered: they are indirect Bstrings.

Charles
Title: Re: DoEvents
Post by: Aurel on March 31, 2012, 03:01:37 PM
Quote
If local Bstrings are left to accumulate, they will eventually fill the entire memory space while the program is running. The problem does not usually reveal itself in short-run programs, but task-manager is useful for spotting memory leaks of this kind.

-Ok, i understand what you mean but as is local veriable why is not destroyed when
end sub executed.I see that you say that is not destroyed with garbage colector.
In my case i test 100000 iteration inside edit control and watch mem-footprint in task
manager and footprint is same about cca 2245k which looks fine to me.

Quote
Peter's win64.inc and my MinWin.inc both have some API calls - low level, without prototypes which mean that the parameters have to be a perfect match.

- Mine include is not something special just same thing derived from Peter header with
some api calls for creating controls .
But without WndProc.

Here is code:
Code: [Select]
Include "awinh.inc"
#lookahead ' for procedures
% LR_LOADTRANSPARENT = &H20
% LR_LOADMAP3DCOLORS = &H1000
INT TransparentMap3D = LR_LOADTRANSPARENT or LR_LOADMAP3DCOLORS
INT win
INT winstyle
INT button1,button2
INT edit1,edit2,edit3
INT Lbox,static1,static2,static3
INT ed1ID,ed2ID,ed3ID
INT b1ID,b2ID,b3ID,b4ID,b5ID,b6ID,b7ID
INT LboxID = 300
INT st1ID,st2ID
b1ID=100
b1ID=101
b1ID=102
b1ID=103
b1ID=104
b1ID=105
'-----------------
ed1ID=200
ed2ID=201
ed3ID=202
'----------------
st1ID=350
st2ID=351
st3ID=352
'----------------
'loadbmp
'##########################################
INT bmpB1,bmpS1
bmpB1 = LoadImage(0,"data/xpBopen.bmp",0,76,20,16)
bmpS1 = LoadImage(0,"data/xpStatic.bmp",0,82,82,16)
'##########################################

winstyle = WS_MINMAXSIZE or WS_CLIPCHILDREN
'create window
win = SetWindow("Test AwinH",100,100,640,480,winstyle)

'create buttons
button1 = SetButton(win,280,20,80,24,"",0x50000080,0x200,b1ID)
'set bitmap on button 1
SendMessage button1 , BM_SETIMAGE, 0, bmpB1

button2 = SetButton(win,380,20,80,24,"button_2",0x50000000,0x200,b2ID)

'create edit control
edit1 = SetEditBox(win,200,80,180,24,"edit 1",0x50004000,0x200,ed1ID)

'create listbox
Lbox = SetListBox(win,200,140,180,150,"LB 1",0x50000140,0x200,LboxID)
'create static control
static1 = SetStatic(win,10,20,254,16," This is a STATIC text control with EX_CLIENTEDGE",0,0x200,st1ID)
static2 = SetStatic(win,10,40,254,13," This is a STATIC text control without ex_ClientEdge     ",0,0,st1ID)
'crete static control with bitmap
static3 = SetStatic(win,10,60,82,82,"",0x5000030E,0,st3ID)
SendMessage static3 ,370, 0, bmpS1
'---------------------------------------------------------------------
GoSub AddListboxItems
'WHILE GetMessage (&wm,0,0,0)<>0
'TranslateMessage &wm
'DispatchMessage &wm
'WEND
sys bRet
  '
  Do While bRet := GetMessage (&wm, 0, 0, 0)
    If bRet = -1 then
      'show an error message
    Else
      TranslateMessage &wm
      DispatchMessage &wm
    End If
  Wend



Function WndProc(byval hWnd as long,byval wMsg as long, byval wParam as long,byval lparam as long) as long callback

SELECT wMsg
'----------------------------

CASE WM_DESTROY
PostQuitMessage 0
'-------------------------------------------------------------
CASE WM_COMMAND
controlID = LoWord(wParam) 'get control ID
notifyCode = HiWord(wParam) 'get notification message

Select controlID
   Case b1ID
If notifycode=0 
Beep(1660,50)
    Print "Button 1 Clicked!"
End If
   Case b2ID
     If notifycode=0         
    Gosub SetControlText
End If



End Select
'-----------------------------------------------------
END SELECT


FUNCTION = DefWindowProc hwnd,wMsg,wParam,lParam


END FUNCTION

'########################################################
SUB AddListboxItems
bstring i$ : i$=""

For n = 0 To 100
i$=Str(n) + "..listbox item"
SendMessage Lbox,LB_ADDSTRING,0,i$
Next n
END SUB
'#########################################################
SUB SetControlText
bstring n$
n$=""

'loop
For i = 0 To 100000
n$ = Str(i)
SendMessage edit1,WM_SETTEXT,0,n$
UpdateWindow(edit1)
Next


END SUB


Title: Re: DoEvents
Post by: Charles Pegge on March 31, 2012, 09:55:54 PM
Quote
In my case i test 100000 iteration inside edit control and watch mem-footprint in task
manager and footprint is same about cca 2245k which looks fine to me.

Hi Aurel,

I need to explain a little further

In your SetControlText procedure the compiler can see n$ being reused 10000 times, so it frees the previous bstring and creates a new one for each iteration of the loop.

When the routine ends, only one n$ Bstring remains in memory.

So, if you call your SetControlText procedure 10000 times instead, you will end up with 10000 bstrings in system memory. And you should be able to see that in Task Manager.

Charles
Title: Re: DoEvents
Post by: Aurel on April 01, 2012, 03:45:59 AM
Quote
I ask me, if he understands that.
He still uses Version 034, which is faulty and has extra memory leaks.
Yeah,yeah...o
Ok ,maybe i dont understand and mybe im completely stupid.
But if you don't belive try executable from attachment and you will see that memory not grow up.
On my computer stay on 2540k.
I even test 100x10000 iteration and is still same.
Code: [Select]
Case b2ID
     If notifycode=0
             again:         
    Gosub SetControlText
count=count+1
IF count < 100 then goto again

End If

Title: Re: DoEvents
Post by: Charles Pegge on April 01, 2012, 06:43:18 AM
I like the grass Peter, this is how Football pitches are laid.
Title: Re: DoEvents
Post by: Aurel on April 01, 2012, 07:20:55 AM
Of course that you get crush even you move mouse,because WM_MOUSEMOVE messasge is sended
and is not intercepted when loop run.
So just clik on buton and leave mouse,and don't tuch anything ;D
Ok i maybe made to much interating ,so i decrease looping to 10x10000 by clicking on button_2.
I think that i must add function like WaitWindowMessages inside long loops which can intercept win
message inside runing loop.
I must look into CB source or DCompiler source and see how is solwed there.
About mem-leak ...nothing ,task.manager display still 2540k of used.
Title: Re: DoEvents
Post by: Aurel on April 02, 2012, 11:05:30 AM
Quote
But the OPEN BUTTON  is fishy

heh,what you mean fishy?
Do you mean on classic control theme button?
This button is classic bitmap button which only can have this style.
I don't know how to create themed (xpstyle button) yet :-\
Title: Re: DoEvents
Post by: Aurel on April 09, 2012, 02:34:53 PM
After few hours of searching for a right style i finally add RichEdit control.
Code: [Select]
'create Rich Edit control
INT reStyle = WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_WANTRETURN|WS_VSCROLL|WS_HSCROLL|ES_AUTOVSCROLL|ES_AUTOHSCROLL|ES_SUNKEN
'INT reStyle = 0x508010C4
richedit1 = SetRichEdit(win,300,80,200,150,"Text in Richedit...",reStyle ,0x200,reID)

Function from header:
Code: [Select]
Dim kernel32,user32,gdi32,riched32
kernel32 = LoadLibrary "kernel32.dll"
user32   = LoadLibrary "user32.dll"
gdi32    = LoadLibrary "gdi32.dll"
riched32 =  LoadLibrary "riched32.dll"

Code: [Select]
unction SetRichEdit(byval _ehwnd as int,byval _ex as int,byval _ey as int,byval _ew as int,byval _eh as int, byval _etext as string,byval _eflag as int,byval _ext as int,byval _cID as INT) as int
INT _hfont
If _eflag=0
'0x50800080 single , 0x50B010C4 multiline
    _eflag = 0x50800080 or ES_SUNKEN
EndIf
hRichEdit = CreateWindowEx(_ext,"richedit20a",_etext,_eflag,_ex,_ey,_ew,_eh,_ehwnd,_cID,0,0)
_hfont = GetStockObject(17)
SendMessage hRichEdit,WM_SETFONT,_hfont,0
UpdateWindow _ehwnd
Function = hRichEdit
End Function