Liberty Basic is develeopped by Carl Gundel
Original Newsletter compiled by Alyce Watson and Brosco
Translation to HTML: Raymond Roumeas

The Liberty Basic Newsletter - Issue #55 - NOV 99

© 1999, Alyce Watson All Rights Reserved

In this issue:

  1. Request
  2. A real Windows status bar!
  3. A multi-part status bar!
  4. An interesting status bar demo.


1 - REQUEST

I am soliciting contributions for newsletter articles. Some possible subjects follow, but articles of any kind that deal with programming are welcome. Please send submissions to me at

mailto:awatso-@wctc.net

Submissions become the property of the LB Newsletter. Not all submissions may be published. Submissions may be edited for publication.

Ideas:

Thank you,

Alyce Watson


2 - A REAL WINDOWS STATUS BAR!

Recently, Brent Thorn shared an example that created a real Windows status bar. Thanks, Brent! I have added to that routine, but please credit Brent (lbgui) if you use these methods in your code.

Contact Brent Thorn mailto:lbgu-@aol.com

Also, special thanks to John Worthington for supplying the values for the status bar constants.

 

You may create a status bar with this method on Win95 and Win98. You may also do this on later versions of Win3.1. To use Win3.1, you must have Win32s on your system. If you are not sure whether you have Win32s, do a search of your Windows directories.

 

Steps to create a simple status bar:

1) Get the handle of the program window with LB's HWND function.

hwnd = hwnd(#1)

2) Open commctrl.dll and user.dll

open "commctrl.dll" for dll as #cctl
open "user" for dll as #user

3) Initialize the commctrl.dll

calldll #cctl, "InitCommonControls", re as void

4) Set up style variables. These are Windows constants that are put together with OR. In this case, the minimum needed is:

style = _WS_VISIBLE or _WS_CHILD

5) Make a null terminated string that contains the text that appears on the status bar at start-up:

text$ = "I'm a real status bar!" + chr$(0)

6) Assign an ID number to the status bar. This number is not used in Liberty BASIC, but must be part of the API function call:

id = 1

7) Make the API call that creates the status bar. If successful, the function returns the status bar handle:

calldll #cctl, "CreateStatusWindow", _
style as long, _
text$ as ptr, _
hwnd as word, _
id as word, _
stat.hwnd as word

8) Set up a routine that allows the status bar to resize itself when the window is resized by a user. This is done by sending a windows message to the status bar. The message to send is _WM_SIZE. The word parameter in this case is 0. The long parameter contains the desired new width in its loword, and the desired new height in its hiword. We do not need to tell the status bar what height it should be, so that part of the long parameter is 0. The width should be equal to the WindowWidth, so that is all the long parameter should contain.

calldll #user, "SendMessage", _
stat.hwnd as word, _
_WM_SIZE as word, _
0 as word, _
WindowWidth as long, _
re as long

Steps to change the status text:

1) This requires that a Windows message be sent. You must have the handle of the status bar as the first parameter. The second parameter is the value for the Windows constant SB_SETTEXT.

This value is not set within Liberty BASIC, so it must be passed into the call as 1025. The word parameter is 0. The long parameter contains a pointer to the address of the null terminated string containing the new status bar caption. In Liberty BASIC, the syntax is:

text$ = "Changed!" + chr$(0)
 
calldll #user, "SendMessage", _
stat.hwnd as word, _
1025 as word, _
0 as word, _
text$ as ptr, _
r as dword


And now, here is some sample code that uses this method:

' Original Code for Status Bar by Brent Thorn:
' lbgu-@aol.com
'
' This is a simple example that creates a
' status bar and demonstrates how to
' change the text it contains.
'
 
nomainwin
' Open DLLs
open "commctrl.dll" for dll as #cctl
open "user" for dll as #user
 
 
' Open window
WindowWidth=200:WindowHeight=150
button #1.b, "Change Status Text",[change],UL,10,50
open "Status Bar Test" for window as #1
 
 
' Set up events
print #1, "trapclose [quit]"
print #1, "resizehandler [size]"
 
 
' Get window handles
hwnd = hwnd(#1)
 
 
' Init common controls
calldll #cctl, "InitCommonControls", _
re as void
 
 
' Flags for status window creation -
' these are the minimum:
style = _WS_VISIBLE or _WS_CHILD
 
 
' Text to appear on status bar -
' must be null terminated
text$ = "I'm a real status bar!" + chr$(0)
 
 
' Windows and controls created via API
' must be assigned an ID number
' which is not used in LB.
id = 1
 
 
' create status bar
' output style, text$, hwnd, id
' input stat.hwnd
 
GOSUB [create.status.bar]
 
' the status bar handle is now = stat.hwnd
 
 
 
[loop]
input a$ ' Wait for events
 
 
[create.status.bar]
' input style, text$, hwnd, id
' output stat.hwnd
 
calldll #cctl, "CreateStatusWindow", _
style as long, _
text$ as ptr, _
hwnd as word, _
id as word, _
stat.hwnd as word
 
RETURN
 
 
[change]'put new text on status bar
' input text$, stat.hwnd
' output: none
' 1025 is the constant value to change status bar text
 
IF text$ = "Changed!" + chr$(0) then
text$ = "I'm different!" + chr$(0)
ELSE
text$ = "Changed!" + chr$(0)
END IF
 
calldll #user, "SendMessage", _
stat.hwnd as word, _
1025 as word, _
0 as word, _
text$ as ptr, _
r as dword
 
GOTO [loop]
 
 
 
[size]
' Tell the status bar to resize itself
' input stat.hwnd
' output: none
 
calldll #user, "SendMessage", _
stat.hwnd as word, _
_WM_SIZE as word, _
0 as word, _
WindowWidth as long, _
re as long
goto [loop]
 
 
[quit]
' Tell status bar to kill itself
' input stat.hwnd
 
calldll #user, "SendMessage", _
stat.hwnd as word, _
_WM_DESTROY as word, _
0 as word, _
0 as long, _
re as long
' Close handles
close #1
close #cctl
close #user
 
end


3 - A MULTI-PART STATUS BAR!

Steps to create a multi-part status bar:

1) All steps in the first example must be done.

2) Build a STRUCT that will contain the X location for the end of each part, or segment of the status bar. Here it is called prt and contains information for three segments:

struct prt,end1 as short, end2 as short,end3 as short

3) Fill the struct with the values for the X location for the end of each segment. The last value should be set to -1, so that the last segment will always continue to the right edge of the window.

prt.end1.struct=140
prt.end2.struct=230
prt.end3.struct=-1

4) Determine the total number of parts to set in the status bar. This will probably be equal to the number of items in the struct.

number.parts=3

5) Send a Windows message to SET the parts of the status bar. The first parameter will be the handle of the status bar. The second parameter will be 1028, which is the value for SB_SETPARTS. The word parameter is the number of parts you want to make. The long parameter is a pointer to the struct containing the X - END values for the parts.

calldll #user, "SendMessage", _
stat.hwnd as word, _
1028 as word, _
number.parts as word, _
prt as struct, _
r as dword

6) The text for the first part is set when the status bar is created. The text for the remaining parts must be set as in the earlier example, with a Windows message, but this time, we must be sure to include the ID for the part we want to set text on. The positions are numbered beginning with 0, so when setting text on the first part, use an ID of 0. The second part has an ID of 1, the third part has an ID of 2, and so on.

calldll #user, "SendMessage", _
stat.hwnd as word, _
1025 as word, _
segment.ID as word, _
text$ as ptr, _
r as dword


And here is an example program that includes a multi-part status bar:

' Original Code for Status Bar by Brent Thorn:
' lbgu-@aol.com
'
' This example creates a multi-part
' status bar and demonstrates how to
' set the text in the segments.
'
 
nomainwin
' Open DLLs
open "commctrl.dll" for dll as #cctl
open "user" for dll as #user
 
 
' Open window
WindowWidth=600:WindowHeight=150
statictext #1, "Resize this window.",10,10,300,30
open "Status Bar Test" for window as #1
 
 
' Set up events
print #1, "trapclose [quit]"
print #1, "resizehandler [size]"
 
 
' Get window handles
hwnd = hwnd(#1)
 
 
' Init common controls
calldll #cctl, "InitCommonControls", _
re as void
 
 
' Flags for status window creation -
' these are the minimum:
style = _WS_VISIBLE or _WS_CHILD
 
 
' Text to appear on status bar -
' must be null terminated
text$ = "I'm a real status bar!" + chr$(0)
 
 
' Windows and controls created via API
' must be assigned an ID number
' which is not used in LB.
id = 1
 
 
' create status bar
' output style, text$, hwnd, id
' input stat.hwnd
 
GOSUB [create.status.bar]
 
' the status bar handle is now = stat.hwnd
 
 
' create a struct to hold the length of
' the segments in the status bar:
struct prt,end1 as short, end2 as short,end3 as short
 
' fill the struct with x values for length of segments
' a value of -1 will create a segment
' which ends at the right edge of the window
prt.end1.struct=140
prt.end2.struct=230
prt.end3.struct=-1
 
'determine the number of segments:
number.parts=3
 
' output stat.hwnd, number.parts, prt
GOSUB [set.parts]
 
' set text to be contained in segments
' segment ID numbers begin at 0,
' so the ID of the second segment is 1
' output segment.ID, stat.hwnd, text$
 
segment.ID=1
text$="Second Part"+chr$(0)
GOSUB [set.text]
 
segment.ID=2
text$="Third Part"+chr$(0)
GOSUB [set.text]
 
 
[loop]
input a$ ' Wait for events
 
 
[create.status.bar]
' input style, text$, hwnd, id
' output stat.hwnd
 
calldll #cctl, "CreateStatusWindow", _
style as long, _
text$ as ptr, _
hwnd as word, _
id as word, _
stat.hwnd as word
 
RETURN
 
 
[set.parts]
' input stat.hwnd, number.parts, prt
' output: none
' 1028 is SB_SETPARTS
 
calldll #user, "SendMessage", _
stat.hwnd as word, _
1028 as word, _
number.parts as word, _
prt as struct, _
r as dword
 
RETURN
 
 
 
[set.text]
' input text$, stat.hwnd, segment.ID
' output: none
' 1025 is SB_SETTEXT
 
calldll #user, "SendMessage", _
stat.hwnd as word, _
1025 as word, _
segment.ID as word, _
text$ as ptr, _
r as dword
 
RETURN
 
 
 
 
 
[size]
' Tell the status bar to resize itself
' input stat.hwnd
' output: none
 
calldll #user, "SendMessage", _
stat.hwnd as word, _
_WM_SIZE as word, _
0 as word, _
WindowWidth as long, _
re as long
goto [loop]
 
 
[quit]
' Tell status bar to kill itself
' input stat.hwnd
 
calldll #user, "SendMessage", _
stat.hwnd as word, _
_WM_DESTROY as word, _
0 as word, _
0 as long, _
re as long
' Close handles
close #1
close #cctl
close #user
 
end


4 - AN INTERESTING STATUS BAR DEMO:

No steps here, since they are already documented. Have fun!

' Original Code for Status Bar by Brent Thorn:
' lbgu-@aol.com
'
' This example creates a multi-part
' status bar and demonstrates how to
' set the text in the segments.
' It includes a dynamic display change.
 
nomainwin
' Open DLLs
open "commctrl.dll" for dll as #cctl
open "user" for dll as #user
 
 
' Open window
WindowWidth=300:WindowHeight=150
statictext #1, "Watch the Clock!",10,10,300,30
open "Status Bar Test" for window as #1
 
 
' Set up events
print #1, "trapclose [quit]"
print #1, "resizehandler [size]"
 
 
' Get window handles
hwnd = hwnd(#1)
 
 
' Init common controls
calldll #cctl, "InitCommonControls", _
re as void
 
 
' Flags for status window creation -
' these are the minimum:
style = _WS_VISIBLE or _WS_CHILD
 
 
' Text to appear on status bar -
' must be null terminated
text$ = DATE$() + chr$(0)
 
 
' Windows and controls created via API
' must be assigned an ID number
' which is not used in LB.
id = 1
 
 
' create status bar
' output style, text$, hwnd, id
' input stat.hwnd
 
GOSUB [create.status.bar]
 
' the status bar handle is now = stat.hwnd
 
 
' create a struct to hold the length of
' the segments in the status bar:
struct prt,end1 as short, end2 as short
 
' fill the struct with x values for length of segments
' a value of -1 will create a segment
' which ends at the right edge of the window
prt.end1.struct=140
prt.end2.struct=-1
 
'determine the number of segments:
number.parts=2
 
' output stat.hwnd, number.parts, prt
GOSUB [set.parts]
 
 
[loop]'make a clock display
SCAN
segment.ID=1
 
IF text$<>TIME$()+chr$(0) THEN
text$=TIME$()+chr$(0)
GOSUB [set.text]
END IF
 
goto [loop]
 
 
[create.status.bar]
' input style, text$, hwnd, id
' output stat.hwnd
 
calldll #cctl, "CreateStatusWindow", _
style as long, _
text$ as ptr, _
hwnd as word, _
id as word, _
stat.hwnd as word
 
RETURN
 
 
[set.parts]
' input stat.hwnd, number.parts, prt
' output: none
' 1028 is SB_SETPARTS
 
calldll #user, "SendMessage", _
stat.hwnd as word, _
1028 as word, _
number.parts as word, _
prt as struct, _
r as dword
 
RETURN
 
 
 
[set.text]
' input text$, stat.hwnd, segment.ID
' output: none
' 1025 is SB_SETTEXT
 
calldll #user, "SendMessage", _
stat.hwnd as word, _
1025 as word, _
segment.ID as word, _
text$ as ptr, _
r as dword
 
RETURN
 
 
 
 
 
[size]
' Tell the status bar to resize itself
' input stat.hwnd
' output: none
 
calldll #user, "SendMessage", _
stat.hwnd as word, _
_WM_SIZE as word, _
0 as word, _
WindowWidth as long, _
re as long
goto [loop]
 
 
[quit]
' Tell status bar to kill itself
' input stat.hwnd
 
calldll #user, "SendMessage", _
stat.hwnd as word, _
_WM_DESTROY as word, _
0 as word, _
0 as long, _
re as long
' Close handles
close #1
close #cctl
close #user
 
end


mailto:awatso-@wctc.net