Liberty Basic is develeopped by Carl Gundel Original Newsletter compiled by Alyce Watson and Brosco Translation to HTML: Raymond Roumeas
In this issue:
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
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
' 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
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
' 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
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