May 01, 2024, 08:23:44 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


For Starters ..

Started by GWS, December 17, 2006, 12:20:29 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

GWS

Hi folks,

For anyone just beginning to program in EBasic, and wondering what on earth is going on, here's a simple example .ÂÃ, 

It creates a single fixed-size window with one control (a button which the user can click to exit the program).

About the hardest thing to grasp about Windows programming, is the concept of Windows messages.

As soon as you create a Window using the OpenWindow statement, lots of messages relating to the window and all it's controls, are generated by Windows, and can be intercepted by your program's message handling subroutine.

That is, your program becomes event driven.

The first part of the message handling subroutine for this simple example, will catch the message when you click the window 'Close' button at the top right of the window.ÂÃ,  The window will then close, and this will be detected by the 'WaitUntil' statement in the main part of the program. The program will then end.

When you first create the window, the message handler will detect the create message, and will center the window.

If you press the 'ESC'ape key on the keyboard, the keypress message will be detected and the window will be closed.

In the last part of the message handling subroutine, if the user Button is clicked (in this case control number 1),ÂÃ,  the 'button clicked' message is detected, and again the program closes.

Here's the example:


' define all the variables you will be using ..
window w
int wstyle

' specify the window style you require ..
wstyle = @MINBOX

' create the window ..
openwindow w,50,50,500,400,wstyle,0,"Example Window",&handler
setwindowcolor w,RGB(0,0,50)

' define the required controls and their positions ..
control w,@BUTTON,"Exit", 210, 300, 70, 35, 0, 1

' any other windows and their controls would be specified here ..

' initialisation of variables can go here as required ..


' wait until the window is closed ..
waituntil w = 0

' close the program ..
END

'------------------------------------------------------------
' Here we catch all the messages for this window as they occur ..
' All the work of the program is done in this subroutine, or other subroutines called from it ..
sub handler
select @message
case @idclosewindow
' closing the window sets w = 0
ÂÃ,  ÂÃ,  closewindow w
case @idcreate
' when the window is first created, you can do initialising things here ..
centerwindow w
case @idchar
' pressing the 'ESC'(ape) key (Key Code 27 in decimal, or 0x1B in Hexadecimal) will abort the program ...
if (@wparam = 27) then closewindow w
case @idcontrol
' this section picks up the messages from all the controls in this window ..
select @controlid
' this part decides which control sent the message ..
case 1
' user clicked the Exit button ...
closewindow w
' any other controls go here ...
endselect
endselect
return
endsub

' Any other subroutines would go here ..



That's all there is to it really ..ÂÃ,  :)

all the best,

Graham


Tomorrow may be too late ..

Dennisc

Nice Graham - will most certainly help those just setting out and looking for a quick start. :)

Do you remember the restaurant example that was on the Pyxia website? It gave me the start I needed about 3 years ago. I must see if I still have it and convert it to EBasic as a sort of a starter app.

Regards
Dennis
Failure is only the opportunity to begin again more intelligently
www.denniscomninos.com

GWS

December 17, 2006, 02:29:59 PM #2 Last Edit: December 18, 2006, 03:33:03 AM by GWS
OK, if you haven't been fazed by the simple window example, let's do something with it.

This version of the program has removed most of the comments ('cos you know what's happening now .. :))

It draws a few colored circles, and displays some text ..


window w
int wstyle

wstyle = @MINBOX

openwindow w,50,50,500,400,wstyle,0,"Example Window",&handler
setwindowcolor w,RGB(0,0,50)

control w,@BUTTON,"Exit", 210, 300, 70, 35, 0, 1

' draw some circles by calling a subroutine ..
circles()

' display some text ..
setfont w, "Ariel", 20, 700, @SFITALIC
frontpen w,rgb(130,130,230)
drawmode w,@transparent
move w,20,20
print w,"EBasic is Easy"

waituntil w = 0

END

sub handler
select @message
case @idclosewindow
ÂÃ,  ÂÃ,  closewindow w
case @idcreate
centerwindow w
case @idchar
if (@wparam = 27) then closewindow w
case @idcontrol
select @controlid
case 1
closewindow w
endselect
endselect
return
endsub

sub circles
' draw some colored circles ..
int i,col
for i = 1 to 10
col=RGB(rand(205) + 50,rand(205)+ 50,rand(205)+ 50)
size=rand(50)+10
circle w,rand(400)+50,rand(300)+50,size,col,col
next i

return
endsub



That's it .. you can do lots of useful things with those few frequently occurring statements.

all the best, :)

Graham
Tomorrow may be too late ..

GWS

December 19, 2006, 03:33:04 AM #3 Last Edit: December 19, 2006, 07:24:26 AM by GWS
Hi folks,

Hope you don't mind me moving to this section - I realised it shouldn't have been in the 'Questions' section.
Also, I wanted to keep it as simple as possible for those just starting programming. The added contributions (which are most welcome) are in a separate thread, since they were a little too advanced for beginners.

To that end, I realised also that my second post was getting a liitle bit more complicated than it should, so for those just starting, I'd better explain the random color selection process.

Colors are made by setting Red, Green, and Blue components - each of which can have a value between 0 and 255.

If all the components are set to 255, as in RGB(255,255,255) - you will get White.ÂÃ,  If they are all set to zero, RGB(0,0,0), you will get Black.

So to generate a mix of colors for the circles, we can use the Random number function, to give values between 0 and 255 for each of the Red, Green, and Blue values.

There are two random number functions, and the one we want for integer values is RAND(255).

This will give a random value between 0 and 255.ÂÃ,  ÂÃ, We can put these values in our color selection for a circle, as in:

col=RGB(rand(255), rand(255), rand(255))

The snag with that, is that if you happen to get three small random numbers (for example RGB(5,10,12)), the color is so dark it may not be visible over a dark background.

So if we write:

col=RGB(rand(205) + 50, rand(205) + 50, rand(205) + 50)

then even if the random values all turn out to be zero, the '+50' ensures you will always be able to see the random color.
Note that when added together, the (random value + 50) does not exceed 255.

It's not the end of the world if you do set the RGB() values to greater than 255, but the colors you get are not so easily predictable.

all the best, :)

Graham







Tomorrow may be too late ..

Jerry Muelver

Sheesh... It's hard to keep up with you, Graham. Do I have it right, here? (I left the comments in...)

GWS

Hi Jerry,

Yes that's fine.ÂÃ,  :)

Only one error (my fault) .. I left a closing bracket out of the Green setting in the first col = .. statement.ÂÃ,  I've corrected it in my post above.

all the best, :)

Graham
Tomorrow may be too late ..

GWS

December 19, 2006, 07:54:22 AM #6 Last Edit: December 19, 2006, 09:42:14 AM by GWS
Now let us try putting text into a window in two ways - directly in the window, and in a text box (otherwise known as a 'static' control).

Here's the program:


window w
int wstyle,key,textw,texth
string a$,b$

autodefine "OFF"

wstyle = @MINBOX
OPENWINDOW w,50,50,500,400,wstyle,0,"Window Title",&handler
SETWINDOWCOLOR w,RGB(0,0,50)

CONTROL w,@button, "Exit", (500-70)/2, 300, 70, 35, 0, 1
CONTROL w,@static,"",(500-200)/2,36,200,100,@CTEDITCENTER,2
' set the foreground and background colors for the static text box ..
SETCONTROLCOLOR w, 2,rgb(50,170,255), rgb(0,0,150)

a$="The above text is in a Text Box."
b$="This text is in the main window."

frontpen w, RGB(90,190,255)
drawmode w,@TRANSPARENT
setfont w, "Arial",10,600, @SFITALIC
gettextsize w, a$, textW, textH
move w,(500-textW)/2,180

PRINT w,a$

move w,(500-textW)/2, 200
PRINT w,b$

setfont w, "Arial", 8, 600, 0, 2
a$=chr$(10)+chr$(10)+"Text in a Box."+ chr$(10)
b$="Placed wherever you like."
setcontroltext w,2,a$+b$

WAITUNTIL w = 0
END

SUB handler
SELECT @message
case @IDCLOSEWINDOW
        CLOSEWINDOW w
case @IDCHAR
    key = @wparam
if (key = 27) then CLOSEWINDOW w
case @IDCONTROL
select @CONTROLID
case 1
CLOSEWINDOW w
endselect
ENDSELECT
RETURN
ENDSUB



Mostly straightforward, but notice the centering of the text box control, the text, and the button, in the window.

For both the button and the text box, we set the 'x' (left) co-ordinate using the calculation (500 - controlwidth) / 2
Here 500 is the width of the window, and 'controlwidth' is whatever width you set the control to be.

The text is slightly more tricky.ÂÃ,  It's width depends on how many characters there are, the Font we choose, and whether it is Bold, Italic, or whatever ..

The statement:

GETTEXTSIZE w, a$, textW, textH

.. solves that problem, because once we know the width, we can use the statement

MOVE w,(500 - textW) / 2, 200

.. to position where the text will begin in order to be exactly centered in the window.

Only one other thing to notice - if you want to insert a 'carriage return' to place part of the text on the next line, just place chr$(10) in the string to be written to the screen.

That's it, you can write text all over the place now. :)

best wishes,

Graham
Tomorrow may be too late ..

Jerry Muelver

Graham, to get it to work on my system, I had to change the window and control creation to:

OPENWINDOW w,50,50,500,400,wstyle,0,"Window Title",&handler
SETWINDOWCOLOR w,RGB(0,0,50)

CONTROL w,@BUTTON, "Exit", (500 - 70) / 2, 300, 70, 35, 0, 1
CONTROL w,@STATIC, "",(500 - 200) / 2, 36, 200, 100, @CTEDITCENTER,2

and add an ENDSUB at the bottom.
???

GWS

OoopsÂÃ,  :) .. copied the wrong bit of code - just testing ..ÂÃ,  :)

I've copied the right bit in now ..

Thanks for spotting it Jerry .. :)

Graham

Tomorrow may be too late ..

Jerry Muelver

The exercise was a nice little mini-micro-tutorial on conversions, for me. I'm good to go on bring Ribbit into EBasic, now!  ;)

GWS

Now you know how to set up a window with text and controls, you will probably want to spread your wings and create a program with several windows.

This can be done in two ways. The first method works for simple programs, but I tend to use the second if I need more than two windows for an application.

Here's the simple method:

window w1,w2
int run, textW, textH
string a$

' create two windows ..
openwindow w1,50,50,500,400,@sysmenu,0,"Example Window 1",&handler1
openwindow w2,50,50,500,400,@sysmenu,0,"Example Window 2",&handler2
setwindowcolor w1,RGB(0,0,50)
setwindowcolor w2,RGB(0,100,50)
showwindow w2,@swhide

' define two buttons on each window ..
control w1,@BUTTON,"Exit", 290, 300, 120, 35, 0, 1
control w1,@BUTTON,"Next Window", 90, 300, 120, 35, 0, 2

control w2,@BUTTON,"Exit", 290, 300, 120, 35, 0, 1
control w2,@BUTTON,"Previous Window", 90, 300, 120, 35, 0, 2

frontpen w1, RGB(90,190,255)
drawmode w1,@TRANSPARENT
setfont w1, "Arial",40,600, @SFITALIC
a$ = "Window 1"
gettextsize w1, a$, textW, textH
move w1,(500 - textW) / 2, 100
print w1, a$

frontpen w2, RGB(90,190,255)
drawmode w2,@TRANSPARENT
setfont w2, "Arial",40,600, @SFITALIC
a$ = "Window 2"
gettextsize w2, a$, textW, textH
move w2,(500 - textW) / 2, 100
print w2, a$

run = 1

' wait until any window is closed ..
waituntil run = 0
' close all windows ..
closewindow w1
closewindow w2

' close the program ..
END

'------------------------------------------------------------
' catch the messages for window 1 ..
sub handler1
select @message
case @idclosewindow
ÂÃ,  ÂÃ,  run = 0
case @idcontrol
' pick up the messages from controls in window 1..
select @controlid
case 1
run = 0
case 2
' show number 2 window ..
showwindow w2,@swrestore
showwindow w1,@swhide
endselect
endselect
return
endsub

'------------------------------------------------------------
' catch the messages for window 2 ..
sub handler2
select @message
case @idclosewindow
run = 0
case @idcontrol
' pick up the messages from controls in window 1..
select @controlid
case 1
run = 0
case 2
' return to window 1 ..
showwindow w1,@swrestore
showwindow w2,@swhide
endselect
endselect
return
endsub


In this method, the two windows are entirely independent.ÂÃ,  There is a message handling subroutine for each of them, so a button clicked on Window 2 will send it's message to the Window 2 message handler.

Now here's method 2, which I prefer:


window frame, c1, c2
int run, textW, textH
string a$

autodefine "OFF"

' open a main frame window and two child windows of the frame ..
OPENWINDOW frame,50,50,500,400,@sysmenu,0,"Example of Multiple Windows",&framehandler
OPENWINDOW c1,0,0,500,400,@nocaption,frame,"",&childhandler
OPENWINDOW c2,0,0,500,400,@nocaption,frame,"",&childhandler

setwindowcolor c1,RGB(0,0,50)
setwindowcolor c2,RGB(0,100,50)
showwindow c2,@swhide

' define two buttons on each window ..
control c1,@BUTTON,"Exit", 290, 300, 120, 35, 0, 1
control c1,@BUTTON,"Next Window", 90, 300, 120, 35, 0, 2

control c2,@BUTTON,"Exit", 290, 300, 120, 35, 0, 1
control c2,@BUTTON,"Previous Window", 90, 300, 120, 35, 0, 2

frontpen c1, RGB(90,190,255)
drawmode c1,@TRANSPARENT
setfont c1, "Arial",40,600, @SFITALIC
a$ = "Window 1"
gettextsize c1, a$, textW, textH
move c1,(500 - textW) / 2, 100
print c1, a$

frontpen c2, RGB(90,190,255)
drawmode c2,@TRANSPARENT
setfont c2, "Arial",40,600, @SFITALIC
a$ = "Window 2"
gettextsize c2, a$, textW, textH
move c2,(500 - textW) / 2, 100
print c2, a$

run = 1

waituntil run = 0
CLOSEWINDOW frame
end

SUB framehandler
select @message
case @idclosewindow
run = 0
endselect
return
ENDSUB

SUB childhandler
select @message
case @idcontrol
' Note: @hitwindow contains a pointer to the window originating the message ..
select #<WINDOW>@HITWINDOW :' determines which window the message is from ..
case c1
' a button on child window 1 was clicked ..
select @controlid
case 1
' exit button clicked ..
run = 0
case 2
' show number 2 child window ..
showwindow c2,@swrestore
showwindow c1,@swhide
endselect
case c2
' a button on child window 1 was clicked ..
select @controlid
case 1
run = 0
case 2
' return to child window 1 ..
showwindow c1,@swrestore
showwindow c2,@swhide
endselect
endselect
endselect
return
ENDSUB


The advantage of this method is that all messages are processed within one subroutine for all child windows.
Also, if your project uses a menu system, this can be attached to the frame window, and can be accessed from all the child windows.

So now you can have as many windows in a project as you like ..

all the best, :)

Graham



Tomorrow may be too late ..

GWS

I don't know if anyone has any tips for using Dialog windows - I hardly ever use them myself ..

And maybe someone has found another way of handling multiple windows - that would be interestingÂÃ,  :)

Graham
Tomorrow may be too late ..

Doc

Graham,
Thanks for posting the sample code for that second method!
I've been kicking around a few ideas for a first EB project that would be very messy to do without the use of tabs, but now it appears that I have at least one more very possible option. :)

Much appreciated!

-Doc-

GWS

You're welcome Doc ..ÂÃ,  :)

I did see a Tabbed window example somewhere in my files - I think it might have been one of Larry's experiments ..
I'll look for it if it would suit your application better ..

all the best, :)

Graham
Tomorrow may be too late ..

Dennisc

Here's the tab examples I've got
Regards
Dennis
Failure is only the opportunity to begin again more intelligently
www.denniscomninos.com

GWS

Excellent .. your filing system is much better than mine Dennis ..ÂÃ,  :)

It was the TabbedWin example by LarryA that I remembered.

best wishes, :)

Graham
Tomorrow may be too late ..

LarryA

Quote from: GWS on December 20, 2006, 10:53:45 AM

It was the TabbedWin example by LarryA that I remembered.


If I recall correctly, I never did upload later, improved tab stuff.  I'm still doing my own tabs... never have liked dealing with the MS API derived tabs or their appearance so I'm rolling my own.  I like a good thick heavy duty plastic tab  ;D

This is in my current project... covers the bottom third of screen leaving the top 2/3s as unencumbered (no menu at top) drawing area.  Not much use of the available space on the FILE tab page but all the others have several sub-pages (panels) full of controls... which sub-page is visible is dependent on choices/context.  Prototyped with IBasicPro/GDI, final version VB.net/GDI+

"Aerodynamics are for people who can't build engines." -- Enzo Ferrari
"Turbochargers were for people who can't build engines" -- Keith Duckworth

Barney

Wow! I like those tabs! Great work LarryA.

Barney