Posted: Sat Aug 10, 2002 1:02 am
Restored from previous forum. Originally posted by Art Sentinel.
============
============
============
oooOO Read/Write Status Bar API Tutorial in 4 EASY Steps OOooo
.
.
============
Introduction
============
I found an interesting article in the Encyclopedia Britannica this morning. It speaks of the
fascinating history of the Windows API. I thought some of you may be interested in reading this,
so I included a particularly interesting excerpt below:
"Born in 627 AD on a small remote farm in Western Pennsylvania, USA, Chester Finnious
Copperpot spent the early part of his childhood isolated from the modern 'going-ons' of the day.
When at the young age of three, Chester took used toilet paper tubes and built an accurate
prototype of a snapping turtle DNA strand, his parents realized that their son was destined for
greater things than their small farm could provide him. So they shipped him off to Rome. There a
youthful Chester Copperpot spent the next 10 years of his life learning from the great Roman
intellectual masters: Socrates, Hipparchus, Euclid, and Jon Bon Jovi.
Eventually Chester's curiosity of the world overcame him. He bid farewell to his new
friends, and armed with just the clothes on his back and his sharp intellect, he set forth into
the world in search for his calling in life.
Not long after he left, Chester became enamored by the oldest daughter of a gypsy high
wire circus family. Overcome by love he joined the circus too. All was going well for the now
teenage Chester Copperpot until one day Bertha the Giant Elephant accidentally sat on him and
crushed 90% of the bones in his body..."
Interesting story, huh! The Encyclopedia Britannica goes on to describe Chester's miraculous
recovery. During which time he had his great vision of writing the world's first API. After two
more decades of amazing adventures--including fighting blood thirsty pirates on the open
sea--Chester decided to settle down and go to college. His roommate at college was a man named
'Bill Gates', and from that point on, well.. the story is common history.
You never know what intriguing things you will learn from reading an Encyclopedia. I would
recommend that the next time you are looking for a good book to relax at night with, you consider
pulling the 'C' Edition of your Encyclopedia from the shelf and reading more about Chester
Finnious Copperpot--the man who invented the API, and thusly changed the world as we know it
forever..
.
==============
Tutorial Start
==============
OK, I have rotted your brain with my introduction, now it is tutorial time! In this lesson I will
attempt to introduce you to the concept of using the API common controls. To be precise, we will
be working with the status bar common control located within the Comctl32.dll. (The Comctl32.dll
is one of the several Dynamic-Link Libraries that comprise the WinAPI; this one being the
repository where you will find the functions for adding many visual windows elements to your
projects.) Before we begin, I like to note that this tutorial is dedicated to skypa for inspiring
me to even be interested in these specific API functions.
And a sincere thanks goes to freak
and Pupil for helping my blind eyes see the silly typo I made in my testing application.
.
Important Tips to Remember
-The ComCtl32.ocx used by Visual Basic to add a status bar to your VB application is in
excess of 500KB! Can you seriously imagine a 500kb PureBasic executable that contains only an
empty window and a status bar?? Haha.. That is a scary thought, isn't it? For the simplicity of
'dragging' a status bar onto your project window, you save about 2 minutes of typing and lose
your creative freedom, power, and possibly even your profits. That is why understanding how to
effectively use the WinAPI is so important--whether you use Visual Basic or PureBasic. (And you
better be using PB or I will send Big Bertha to accidentally sit on you too..) Using the
API common controls within your applications will in most cases give you greater control of what
you want done, and reduce your overall executable size. If you want power and TINY
exe's, this is the way to go.
-The WinAPI was developed as a means of helping application programmers incorporate
standardized and optimized controls and functions within their applications. This can be an
immense help when you are working on a project that needs to be finished fast and without as
many bugs. Believe me, it is when you do not fully comprehend what exactly a command is doing,
that you have the greatest difficulty figuring out what you programmed wrong.
-This brings up a related topic: The PureBasic manual says the following concerning the
creation of a Status Bar..
Result = CreateStatusBar(#StatusBar, WindowID)
Description
Create and add an empty StatusBar to the specified WindowID. If the Result is 0, the
StatusBar creation has failed, else it's fine. Once the bar is created, AddStatusBarField() can
be used to setup the different parts of the bar.
In this statement, an experienced programmer would probably realize (without it having been
stated) that the Result variable has a much more important role than simply letting you know if
the command failed. In truth, the Result variable will store the handle of the created status bar
window! This mean if you want to later refer to that status bar using the WinAPI, you will need
to use the value set in Result, not the hWnd of the main application itself. Be aware that
the status bar is actually another window inside of your main application window. And being such,
it has its own identifier.
-Even though you may not find a desired constant or function in the Win32.hlp file, try
clicking the 'Find' tab. After a brief one time wait while the word list is being written, you
will have a more powerful method of searching for the terms you require. I know this is a basic
tip, but many people do not use the 'Find' feature, and as such they miss out using the Win32.hlp
to its fullest.
-When coding using the API, you will often need to set a pointer to an array in PureBasic.
Do not point to the main array name such as @MyArray(). Instead point to the first element of
the array and you will be fine: @MyArray(0).
.
.
Step One
Open and save a new PB project. Name it 'SetStatusBar.pb'. Then add the following variable
declarations at the top:
.
.
The first group of constants are for setting up our several text gadgets. Each text gadget
requires a unique number, so this is sorted out here. (The reason I added the text gadgets with
incrementing values of 1 will become apparent later on in this tutorial.)
The second group of string variables hold the text we will add to our 5 status bar parts.
The third group is our array. The API call we will be using wants to speak to an array. The
number of the elements in our array and their values depends upon the specific API function and
its requirements. You can find this information out by checking your API docs.
.
Step Two
Open a 300 x 300 window, and add the text gadgets to it. (See below.) The layout of this
window and its contents is purely aesthetic and has little to do with its functionality. If you
prefer, use your own artistic freedom to play with the code sample and design an even better
layout than the one I chose.
.
.
Step Three
Here are the meat and potatoes of our tutorial. In this step we call the API functions
(actually several of them!). Don't panic, they are not nearly as difficult as you may at first
believe. Add this code to your project now.
.
.
.
.
We start this block of code off by calling: InitCommonControls_() . What this
does is make sure that the common control dynamic-link library (DLL) is loaded. This is just
here to prevent some weird errors you may experience later on.
Secondly we add: StatushWnd = CreateStatusWindow_(#WS_VISIBLE | #WS_CHILD, NULL, hWnd, #wID) .
This adds a status bar to our application and sets its window handle equal to the variable we
chosen called 'StatushWnd'.
- #WS_CHILD and #WS_VISIBLE are style parameters. You may chose from a few other styles
also, but you must have #WS_CHILD and should have #WS_VISIBLE set.
- The NULL is simply there because we have no need right now for a Pointer to a null-
terminated string that specifies the status text for the first part. (We will be adding the text
ourselves in a minute.) If we wanted to use this parameter, we would place something like
@MyStatusBarText in place of the NULL.
- hWnd is what it says: It is the handle to the parent window of our application. (We
specified its value above right after opening our window in Step Two.)
- #wID is the control identifier for the status window. The window procedure uses this
value to identify messages it sends to the parent window. When you get more advanced, you will
find many important uses for this identifier.
Now we have a series of SendMessage_() calls. Note how they are each directed to the handle
of our status bar, and not hWnd. These are the message we are sending to our application
to control the appearance of our newly added status bar. #SB_SETPARTS will set the number of
separate parts we desire in our SB: 5. And here is where we make use of our array we dimensioned
and declared earlier. The values of the elements of our array match the parts we want in our
status bar. There are 5 parts and 5 array elements. (This needs to be the same number!) Each
element contains the value for its right edge position within the status bar as it relates to
the client coordinates of our application. So you see, the first partition line will be at 60
pixels from the left edge of the window; the next will be at 120, and so on..
We use the #SB_SETTEXT constant parameter to set the text of our specified status bar part.
You need to realize that most of windows programming is 'zero based'. This means that your number
one part is actually index 0, and the 5th part is index 4. To specify the text variable you want
used for the new status bar text, simply set up the variable ahead of time (as we already did)
and add a pointer to it. Note: This pointer step is not necessary since PureBasic always uses
the address of the variable when it passes it to the API function, but if you get in the habit of
using the common convention, you will avoid later confusion and help yourself better learn the
way the API thinks. (After all, adding a '@' takes just .3 seconds longer. Don't get
Visual Basic Lazy on me.)
#SB_GETTEXT does the opposite of #SB_SETTEXT, adding the value of the part's text to a
specified variable for you to use any way you like later on.
Length.l = SendMessage_(StatushWnd, #SB_GETTEXTLENGTH, i, 0) will retrieve the length of
the text (characters) within the particular status bar part. The length is returned as a value
of the function, so make sure to have it set equal to a variable you can later use.
The rest of our code block simply takes the text and length of each part and adds it to
our text gadgets to demonstrate how reading/writing to the status bar is easily possible using
PB and the WinAPI. As you can see, I used a For..Next statement. This is the reason I set the
text gadget constants incrementally by one at the beginning of the tutorial.
If you like to use the built in PureBasic commands for creating a status bar, that is fine.
Such as:
.
.
Just make sure you remember to use StatushWnd as the handle for your reading/writing API
routines.
.
Step Four
Add your main loop, thank the caffeine God that you are finally done, and do the dance of
eternal exuberance! Congratulations. You are no longer a WinAPI status bar nerd. You have just
progressed to official geek status. Haha..
.
==========
Conclusion
==========
Here is what your final code may look like:
.
.
.
.
I hope you enjoyed this tutorial--and maybe actually learned a thing or two?
By now I think it
is becoming clearly obvious how powerful and enjoyable PureBasic programming can be! Far easier
and faster than Visual Basic, tiny highly optimized true-compiled executables (no temperamental
runtime DLL's), a very friendly community of skilled code-a-holics always willing to help
you out when you're in a pinch, and a honest price tag you can definitely afford. That is why it
is no wonder that those other 'super-amazing programming languages' rapidly drop like the
byte-size flies they are when compared to pure power of PureBasic...
Have fun!
- Art Sentinel
http://www.artsentinel.net
.
.
.
===================
Related WinAPI Docs
===================
InitCommonControls QuickInfo Overview Group
[New - Windows NT]
The InitCommonControls function ensures that the common control dynamic-link library (DLL) is loaded.
void InitCommonControls(VOID);
Return Value
This function does not return a value.
.
============
CreateStatusWindow QuickInfo Overview Group
[New - Windows NT]
The CreateStatusWindow function creates a status window, which is typically used to display the status of an application. The window generally appears at the bottom of the parent window, and it contains the specified text.
HWND CreateStatusWindow(
LONG style,
LPCTSTR lpszText,
HWND hwndParent,
UINT wID
);
Parameters
style
Window styles for the status window. This parameter must include the WS_CHILD style and should also include the WS_VISIBLE style.
lpszText
Pointer to a null-terminated string that specifies the status text for the first part.
hwndParent
Handle to the parent window.
wID
Control identifier for the status window. The window procedure uses this value to identify messages it sends to the parent window.
Return Value
If the function succeeds, the return value is the handle for the status window.
If the function fails, the return value is NULL.
Remarks
The CreateStatusWindow function calls the CreateWindow function to create the window. It passes the parameters to CreateWindow without modification and sets the position, width, and height parameters to default values.
Windows 95 only: The system can support a maximum of 16,364 window handles.
See Also
CreateWindow
.
============
SendMessage QuickInfo Overview Group
The SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts a message to a thread's message queue and returns immediately.
LRESULT SendMessage(
HWND hwnd, // handle of destination window
UINT uMsg, // message to send
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
Parameters
hwnd
Identifies the window whose window procedure will receive the message. If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows.
uMsg
Specifies the message to be sent.
wParam
Specifies additional message-specific information.
lParam
Specifies additional message-specific information.
Return Value
The return value specifies the result of the message processing and depends on the message sent.
Remarks
If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, Windows switches to that thread and calls the appropriate window procedure.
See Also
InSendMessage, PostMessage, SendDlgItemMessage
.
============
SB_SETPARTS QuickInfo Overview Group
[New - Windows NT]
SB_SETPARTS
wParam = (WPARAM) nParts;
lParam = (LPARAM) (LPINT) aWidths;
The SB_SETPARTS message sets the number of parts in a status window and the coordinate of the right edge of each part.
Parameters
nParts
Number of parts to set. The number of parts cannot be greater than 255.
aWidths
Pointer to an integer array that has the same number of elements as parts specified by nParts. Each element in the array specifies the position, in client coordinates, of the right edge of the corresponding part. If an element is - 1, the position of the right edge for that part extends to the right edge of the window.
Return Value
If the operation succeeds, the return value is TRUE.
If the operation fails, the return value is FALSE.
.
============
SB_SETTEXT QuickInfo Overview Group
[New - Windows NT]
SB_SETTEXT
wParam = (WPARAM) iPart | uType;
lParam = (LPARAM) (LPSTR) szText;
The SB_SETTEXT message sets the text in the specified part of a status window.
Parameters
iPart
Zero-based index of the part to set. If this value is 255, the status window is assumed to be a simple window having only one part.
uType
Type of drawing operation. This parameter can be one of the following values:
Value Meaning
0 The text is drawn with a border to appear lower than the plane of the window.
SBT_NOBORDERS The text is drawn without borders.
SBT_OWNERDRAW The text is drawn by the parent window.
SBT_POPOUT The text is drawn with a border to appear higher than the plane of the window.
SBT_RTLREADING Windows 95 only: Displays text using right-to-left reading order on Hebrew or Arabic systems.
szText
Pointer to a null-terminated string that specifies the text to set. If uType is SBT_OWNERDRAW, this parameter represents 32 bits of data. The parent window must interpret the data and draw the text when it receives the WM_DRAWITEM message.
Return Value
If the operation succeeds, the return value is TRUE.
If the operation fails, the return value is FALSE.
Remarks
The message invalidates the portion of the window that has changed, causing it to display the new text when the window next receives the WM_PAINT message.
See Also
WM_DRAWITEM, WM_PAINT
.
============
SB_GETTEXT QuickInfo Overview Group
[New - Windows NT]
SB_GETTEXT
wParam = (WPARAM) iPart;
lParam = (LPARAM) (LPSTR) szText;
The SB_GETTEXT message retrieves the text from the specified part of a status window.
Parameters
iPart
Zero-based index of the part from which to retrieve text.
szText
Pointer to the buffer that receives the text. This parameter is a null-terminated string.
Return Value
Returns a 32-bit value that consists of two 16-bit values. The low word specifies the length, in characters, of the text. The high word specifies the type of operation used to draw the text. The type can be one of these values:
Value Meaning
0 The text is drawn with a border to appear lower than the plane of the window.
SBT_NOBORDERS The text is drawn without borders.
SBT_POPOUT The text is drawn with a border to appear higher than the plane of window.
SBT_RTLREADING Windows 95 only: Displays text using right-to-left reading order on Hebrew or Arabic systems.
If the text has the SBT_OWNERDRAW drawing type, this message returns the 32-bit value associated with the text instead of the length and operation type.
.
============
SB_GETTEXTLENGTH QuickInfo Overview Group
[New - Windows NT]
SB_GETTEXTLENGTH
wParam = (WPARAM) iPart;
lParam = 0;
The SB_GETTEXTLENGTH message retrieves the length, in characters, of the text from the specified part of a status window.
Parameters
iPart
Zero-based index of the part from which to retrieve text.
Return Value
Returns a 32-bit value that consists of two 16-bit values. The low word specifies the length, in characters, of the text. The high word specifies the type of operation used to draw the text. The type can be one of these values:
Value Meaning
0 The text is drawn with a border to appear lower than the plane of the window.
SBT_NOBORDERS The text is drawn without borders.
SBT_OWNERDRAW The text is drawn by the parent window.
SBT_POPOUT The text is drawn with a border to appear higher than the plane of the window.
SBT_RTLREADING Windows 95 only: Displays text using right-to-left reading order on Hebrew or Arabic systems.
.
============
.
.
Quit = 1
--------------
Top Ten Reasons Not To Procrastinate:
Coming Soon...
Edited by - Art Sentinel on 10 August 2002 02:07:40
============
============
============
oooOO Read/Write Status Bar API Tutorial in 4 EASY Steps OOooo
.
.
============
Introduction
============
I found an interesting article in the Encyclopedia Britannica this morning. It speaks of the
fascinating history of the Windows API. I thought some of you may be interested in reading this,
so I included a particularly interesting excerpt below:
"Born in 627 AD on a small remote farm in Western Pennsylvania, USA, Chester Finnious
Copperpot spent the early part of his childhood isolated from the modern 'going-ons' of the day.
When at the young age of three, Chester took used toilet paper tubes and built an accurate
prototype of a snapping turtle DNA strand, his parents realized that their son was destined for
greater things than their small farm could provide him. So they shipped him off to Rome. There a
youthful Chester Copperpot spent the next 10 years of his life learning from the great Roman
intellectual masters: Socrates, Hipparchus, Euclid, and Jon Bon Jovi.
Eventually Chester's curiosity of the world overcame him. He bid farewell to his new
friends, and armed with just the clothes on his back and his sharp intellect, he set forth into
the world in search for his calling in life.
Not long after he left, Chester became enamored by the oldest daughter of a gypsy high
wire circus family. Overcome by love he joined the circus too. All was going well for the now
teenage Chester Copperpot until one day Bertha the Giant Elephant accidentally sat on him and
crushed 90% of the bones in his body..."
Interesting story, huh! The Encyclopedia Britannica goes on to describe Chester's miraculous
recovery. During which time he had his great vision of writing the world's first API. After two
more decades of amazing adventures--including fighting blood thirsty pirates on the open
sea--Chester decided to settle down and go to college. His roommate at college was a man named
'Bill Gates', and from that point on, well.. the story is common history.
You never know what intriguing things you will learn from reading an Encyclopedia. I would
recommend that the next time you are looking for a good book to relax at night with, you consider
pulling the 'C' Edition of your Encyclopedia from the shelf and reading more about Chester
Finnious Copperpot--the man who invented the API, and thusly changed the world as we know it
forever..
.
==============
Tutorial Start
==============
OK, I have rotted your brain with my introduction, now it is tutorial time! In this lesson I will
attempt to introduce you to the concept of using the API common controls. To be precise, we will
be working with the status bar common control located within the Comctl32.dll. (The Comctl32.dll
is one of the several Dynamic-Link Libraries that comprise the WinAPI; this one being the
repository where you will find the functions for adding many visual windows elements to your
projects.) Before we begin, I like to note that this tutorial is dedicated to skypa for inspiring
me to even be interested in these specific API functions.

and Pupil for helping my blind eyes see the silly typo I made in my testing application.
.
Important Tips to Remember
-The ComCtl32.ocx used by Visual Basic to add a status bar to your VB application is in
excess of 500KB! Can you seriously imagine a 500kb PureBasic executable that contains only an
empty window and a status bar?? Haha.. That is a scary thought, isn't it? For the simplicity of
'dragging' a status bar onto your project window, you save about 2 minutes of typing and lose
your creative freedom, power, and possibly even your profits. That is why understanding how to
effectively use the WinAPI is so important--whether you use Visual Basic or PureBasic. (And you
better be using PB or I will send Big Bertha to accidentally sit on you too..) Using the
API common controls within your applications will in most cases give you greater control of what
you want done, and reduce your overall executable size. If you want power and TINY
exe's, this is the way to go.
-The WinAPI was developed as a means of helping application programmers incorporate
standardized and optimized controls and functions within their applications. This can be an
immense help when you are working on a project that needs to be finished fast and without as
many bugs. Believe me, it is when you do not fully comprehend what exactly a command is doing,
that you have the greatest difficulty figuring out what you programmed wrong.
-This brings up a related topic: The PureBasic manual says the following concerning the
creation of a Status Bar..
Result = CreateStatusBar(#StatusBar, WindowID)
Description
Create and add an empty StatusBar to the specified WindowID. If the Result is 0, the
StatusBar creation has failed, else it's fine. Once the bar is created, AddStatusBarField() can
be used to setup the different parts of the bar.
In this statement, an experienced programmer would probably realize (without it having been
stated) that the Result variable has a much more important role than simply letting you know if
the command failed. In truth, the Result variable will store the handle of the created status bar
window! This mean if you want to later refer to that status bar using the WinAPI, you will need
to use the value set in Result, not the hWnd of the main application itself. Be aware that
the status bar is actually another window inside of your main application window. And being such,
it has its own identifier.
-Even though you may not find a desired constant or function in the Win32.hlp file, try
clicking the 'Find' tab. After a brief one time wait while the word list is being written, you
will have a more powerful method of searching for the terms you require. I know this is a basic
tip, but many people do not use the 'Find' feature, and as such they miss out using the Win32.hlp
to its fullest.
-When coding using the API, you will often need to set a pointer to an array in PureBasic.
Do not point to the main array name such as @MyArray(). Instead point to the first element of
the array and you will be fine: @MyArray(0).
.
.
Step One
Open and save a new PB project. Name it 'SetStatusBar.pb'. Then add the following variable
declarations at the top:
.
Code: Select all
;Declare variables
#wID = 66
#TextField = 198
#SizeOfField = 199
#Field1 = 200
#Field2 = 201
#Field3 = 202
#Field4 = 203
#Field5 = 204
#Size1 = 205
#Size2 = 206
#Size3 = 207
#Size4 = 208
#Size5 = 209
szText$ = Space(12)
SetText1$ = "A1"
SetText2$ = "BEE2"
SetText3$ = "C-Three"
SetText4$ = "DEE 4"
SetText5$ = "EEE!5"
Dim SetParts.l(5)
SetParts(0) = 60
SetParts(1) = 120
SetParts(2) = 180
SetParts(3) = 240
SetParts(4) = 300
The first group of constants are for setting up our several text gadgets. Each text gadget
requires a unique number, so this is sorted out here. (The reason I added the text gadgets with
incrementing values of 1 will become apparent later on in this tutorial.)
The second group of string variables hold the text we will add to our 5 status bar parts.
The third group is our array. The API call we will be using wants to speak to an array. The
number of the elements in our array and their values depends upon the specific API function and
its requirements. You can find this information out by checking your API docs.
.
Step Two
Open a 300 x 300 window, and add the text gadgets to it. (See below.) The layout of this
window and its contents is purely aesthetic and has little to do with its functionality. If you
prefer, use your own artistic freedom to play with the code sample and design an even better
layout than the one I chose.

.
Code: Select all
;Open window
If OpenWindow(0, 150, 150, 300, 300, #PB_Window_SystemMenu, "Read/Write Status Bar API Test")
hWnd = WindowID()
EndIf
;Set up gadgets
If CreateGadgetList(hWnd)
TextGadget(#TextField, 2, 63, 50, 20, "Part 1 (0)", #PB_Text_Center)
TextGadget(#TextField, 2, 103, 50, 20, "Part 2 (1)", #PB_Text_Center)
TextGadget(#TextField, 2, 143, 50, 20, "Part 3 (2)", #PB_Text_Center)
TextGadget(#TextField, 2, 183, 50, 20, "Part 4 (3)", #PB_Text_Center)
TextGadget(#TextField, 2, 223, 50, 20, "Part 5 (4)", #PB_Text_Center)
TextGadget(#TextField, 60, 40, 100, 20, "Status Bar Text", #PB_Text_Center)
TextGadget(#SizeOfField, 163, 40, 100, 20, "Text Length", #PB_Text_Center)
TextGadget(#Field1, 70, 60, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Field2, 70, 100, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Field3, 70, 140, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Field4, 70, 180, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Field5, 70, 220, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Size1, 180, 60, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Size2, 180, 100, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Size3, 180, 140, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Size4, 180, 180, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Size5, 180, 220, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
EndIf
Step Three
Here are the meat and potatoes of our tutorial. In this step we call the API functions
(actually several of them!). Don't panic, they are not nearly as difficult as you may at first
believe. Add this code to your project now.
.
.
Code: Select all
;Set up status bar
InitCommonControls_()
StatushWnd = CreateStatusWindow_(#WS_VISIBLE | #WS_CHILD, NULL, hWnd, #wID)
If StatushWnd NULL
;Call SendMessage API
SendMessage_(StatushWnd, #SB_SETPARTS, 5, @SetParts(0))
SendMessage_(StatushWnd, #SB_SETTEXT, 0, @SetText1$)
SendMessage_(StatushWnd, #SB_SETTEXT, 1, @SetText2$)
SendMessage_(StatushWnd, #SB_SETTEXT, 2, @SetText3$)
SendMessage_(StatushWnd, #SB_SETTEXT, 3, @SetText4$)
SendMessage_(StatushWnd, #SB_SETTEXT, 4, @SetText5$)
For i = 0 To 4
SendMessage_(StatushWnd, #SB_GETTEXT, i, @szText$)
Length.l = SendMessage_(StatushWnd, #SB_GETTEXTLENGTH, i, 0)
NextField.l = #Field1 + i
nextSize.l = #Size1 + i
SetGadgetText(NextSize, Str(Length))
SetGadgetText(NextField, szText$)
Next i
EndIf
.
We start this block of code off by calling: InitCommonControls_() . What this
does is make sure that the common control dynamic-link library (DLL) is loaded. This is just
here to prevent some weird errors you may experience later on.
Secondly we add: StatushWnd = CreateStatusWindow_(#WS_VISIBLE | #WS_CHILD, NULL, hWnd, #wID) .
This adds a status bar to our application and sets its window handle equal to the variable we
chosen called 'StatushWnd'.
- #WS_CHILD and #WS_VISIBLE are style parameters. You may chose from a few other styles
also, but you must have #WS_CHILD and should have #WS_VISIBLE set.
- The NULL is simply there because we have no need right now for a Pointer to a null-
terminated string that specifies the status text for the first part. (We will be adding the text
ourselves in a minute.) If we wanted to use this parameter, we would place something like
@MyStatusBarText in place of the NULL.
- hWnd is what it says: It is the handle to the parent window of our application. (We
specified its value above right after opening our window in Step Two.)
- #wID is the control identifier for the status window. The window procedure uses this
value to identify messages it sends to the parent window. When you get more advanced, you will
find many important uses for this identifier.
Now we have a series of SendMessage_() calls. Note how they are each directed to the handle
of our status bar, and not hWnd. These are the message we are sending to our application
to control the appearance of our newly added status bar. #SB_SETPARTS will set the number of
separate parts we desire in our SB: 5. And here is where we make use of our array we dimensioned
and declared earlier. The values of the elements of our array match the parts we want in our
status bar. There are 5 parts and 5 array elements. (This needs to be the same number!) Each
element contains the value for its right edge position within the status bar as it relates to
the client coordinates of our application. So you see, the first partition line will be at 60
pixels from the left edge of the window; the next will be at 120, and so on..
We use the #SB_SETTEXT constant parameter to set the text of our specified status bar part.
You need to realize that most of windows programming is 'zero based'. This means that your number
one part is actually index 0, and the 5th part is index 4. To specify the text variable you want
used for the new status bar text, simply set up the variable ahead of time (as we already did)
and add a pointer to it. Note: This pointer step is not necessary since PureBasic always uses
the address of the variable when it passes it to the API function, but if you get in the habit of
using the common convention, you will avoid later confusion and help yourself better learn the
way the API thinks. (After all, adding a '@' takes just .3 seconds longer. Don't get
Visual Basic Lazy on me.)

#SB_GETTEXT does the opposite of #SB_SETTEXT, adding the value of the part's text to a
specified variable for you to use any way you like later on.
Length.l = SendMessage_(StatushWnd, #SB_GETTEXTLENGTH, i, 0) will retrieve the length of
the text (characters) within the particular status bar part. The length is returned as a value
of the function, so make sure to have it set equal to a variable you can later use.
The rest of our code block simply takes the text and length of each part and adds it to
our text gadgets to demonstrate how reading/writing to the status bar is easily possible using
PB and the WinAPI. As you can see, I used a For..Next statement. This is the reason I set the
text gadget constants incrementally by one at the beginning of the tutorial.
If you like to use the built in PureBasic commands for creating a status bar, that is fine.
Such as:
.
Code: Select all
StatushWnd = CreateStatusBar(#StatusBar, hWnd)
AddStatusBarField(60)
AddStatusBarField(60)
AddStatusBarField(60)
StatusBarText(#StatusBar, 2, Test$, 0)
Just make sure you remember to use StatushWnd as the handle for your reading/writing API
routines.
.
Step Four
Add your main loop, thank the caffeine God that you are finally done, and do the dance of
eternal exuberance! Congratulations. You are no longer a WinAPI status bar nerd. You have just
progressed to official geek status. Haha..

.
==========
Conclusion
==========
Here is what your final code may look like:
.
.
Code: Select all
;====================
;Read/Write Status Bar API Tutorial
;Art Sentinel August, 08, 2002
;For everyone at the PureBasic Forum
;====================
;ILYLCBD
;Declare variables
#wID = 66
#TextField = 198
#SizeOfField = 199
#Field1 = 200
#Field2 = 201
#Field3 = 202
#Field4 = 203
#Field5 = 204
#Size1 = 205
#Size2 = 206
#Size3 = 207
#Size4 = 208
#Size5 = 209
szText$ = Space(12)
SetText1$ = "A1"
SetText2$ = "BEE2"
SetText3$ = "C-Three"
SetText4$ = "DEE 4"
SetText5$ = "EEE!5"
Dim SetParts.l(5)
SetParts(0) = 60
SetParts(1) = 120
SetParts(2) = 180
SetParts(3) = 240
SetParts(4) = 300
;Open window
If OpenWindow(0, 150, 150, 300, 300, #PB_Window_SystemMenu, "Read/Write Status Bar API Test")
hWnd = WindowID()
Else
MessageRequester("Ouch", "Something is broke.", 0)
End
EndIf
;Set up gadgets
If CreateGadgetList(hWnd)
TextGadget(#TextField, 2, 63, 50, 20, "Part 1 (0)", #PB_Text_Center)
TextGadget(#TextField, 2, 103, 50, 20, "Part 2 (1)", #PB_Text_Center)
TextGadget(#TextField, 2, 143, 50, 20, "Part 3 (2)", #PB_Text_Center)
TextGadget(#TextField, 2, 183, 50, 20, "Part 4 (3)", #PB_Text_Center)
TextGadget(#TextField, 2, 223, 50, 20, "Part 5 (4)", #PB_Text_Center)
TextGadget(#TextField, 60, 40, 100, 20, "Status Bar Text", #PB_Text_Center)
TextGadget(#SizeOfField, 163, 40, 100, 20, "Text Length", #PB_Text_Center)
TextGadget(#Field1, 70, 60, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Field2, 70, 100, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Field3, 70, 140, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Field4, 70, 180, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Field5, 70, 220, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Size1, 180, 60, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Size2, 180, 100, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Size3, 180, 140, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Size4, 180, 180, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
TextGadget(#Size5, 180, 220, 100, 20, "", #PB_Text_Center | #PB_Text_Border)
Else
MessageRequester("Alert!", "This application is infected by a virus. Press 'OK' to reformat your hard drive.", 0)
End
EndIf
;Set up status bar
InitCommonControls_()
StatushWnd = CreateStatusWindow_(#WS_VISIBLE | #WS_CHILD, NULL, hWnd, #wID)
If StatushWnd NULL
;Call SendMessage API
SendMessage_(StatushWnd, #SB_SETPARTS, 5, @SetParts(0))
SendMessage_(StatushWnd, #SB_SETTEXT, 0, @SetText1$)
SendMessage_(StatushWnd, #SB_SETTEXT, 1, @SetText2$)
SendMessage_(StatushWnd, #SB_SETTEXT, 2, @SetText3$)
SendMessage_(StatushWnd, #SB_SETTEXT, 3, @SetText4$)
SendMessage_(StatushWnd, #SB_SETTEXT, 4, @SetText5$)
For i = 0 To 4
SendMessage_(StatushWnd, #SB_GETTEXT, i, @szText$)
Length.l = SendMessage_(StatushWnd, #SB_GETTEXTLENGTH, i, 0)
NextField.l = #Field1 + i
nextSize.l = #Size1 + i
SetGadgetText(NextSize, Str(Length))
SetGadgetText(NextField, szText$)
Next i
Else
MessageRequester("Error","API Status Bar Initialization Failed",0)
End
EndIf
;Main loop
Repeat
Select WaitWindowEvent()
Case #WM_ClOSE
Quit = 1
EndSelect
Until Quit = 1
;Finish up
MessageRequester("Surgeon General Warning:", "Using PureBasic can be very addicting. :wink:", 0)
End
.
I hope you enjoyed this tutorial--and maybe actually learned a thing or two?

is becoming clearly obvious how powerful and enjoyable PureBasic programming can be! Far easier
and faster than Visual Basic, tiny highly optimized true-compiled executables (no temperamental
runtime DLL's), a very friendly community of skilled code-a-holics always willing to help
you out when you're in a pinch, and a honest price tag you can definitely afford. That is why it
is no wonder that those other 'super-amazing programming languages' rapidly drop like the
byte-size flies they are when compared to pure power of PureBasic...
Have fun!
- Art Sentinel
http://www.artsentinel.net
.
.
.
===================
Related WinAPI Docs
===================
InitCommonControls QuickInfo Overview Group
[New - Windows NT]
The InitCommonControls function ensures that the common control dynamic-link library (DLL) is loaded.
void InitCommonControls(VOID);
Return Value
This function does not return a value.
.
============
CreateStatusWindow QuickInfo Overview Group
[New - Windows NT]
The CreateStatusWindow function creates a status window, which is typically used to display the status of an application. The window generally appears at the bottom of the parent window, and it contains the specified text.
HWND CreateStatusWindow(
LONG style,
LPCTSTR lpszText,
HWND hwndParent,
UINT wID
);
Parameters
style
Window styles for the status window. This parameter must include the WS_CHILD style and should also include the WS_VISIBLE style.
lpszText
Pointer to a null-terminated string that specifies the status text for the first part.
hwndParent
Handle to the parent window.
wID
Control identifier for the status window. The window procedure uses this value to identify messages it sends to the parent window.
Return Value
If the function succeeds, the return value is the handle for the status window.
If the function fails, the return value is NULL.
Remarks
The CreateStatusWindow function calls the CreateWindow function to create the window. It passes the parameters to CreateWindow without modification and sets the position, width, and height parameters to default values.
Windows 95 only: The system can support a maximum of 16,364 window handles.
See Also
CreateWindow
.
============
SendMessage QuickInfo Overview Group
The SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts a message to a thread's message queue and returns immediately.
LRESULT SendMessage(
HWND hwnd, // handle of destination window
UINT uMsg, // message to send
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
Parameters
hwnd
Identifies the window whose window procedure will receive the message. If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows.
uMsg
Specifies the message to be sent.
wParam
Specifies additional message-specific information.
lParam
Specifies additional message-specific information.
Return Value
The return value specifies the result of the message processing and depends on the message sent.
Remarks
If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, Windows switches to that thread and calls the appropriate window procedure.
See Also
InSendMessage, PostMessage, SendDlgItemMessage
.
============
SB_SETPARTS QuickInfo Overview Group
[New - Windows NT]
SB_SETPARTS
wParam = (WPARAM) nParts;
lParam = (LPARAM) (LPINT) aWidths;
The SB_SETPARTS message sets the number of parts in a status window and the coordinate of the right edge of each part.
Parameters
nParts
Number of parts to set. The number of parts cannot be greater than 255.
aWidths
Pointer to an integer array that has the same number of elements as parts specified by nParts. Each element in the array specifies the position, in client coordinates, of the right edge of the corresponding part. If an element is - 1, the position of the right edge for that part extends to the right edge of the window.
Return Value
If the operation succeeds, the return value is TRUE.
If the operation fails, the return value is FALSE.
.
============
SB_SETTEXT QuickInfo Overview Group
[New - Windows NT]
SB_SETTEXT
wParam = (WPARAM) iPart | uType;
lParam = (LPARAM) (LPSTR) szText;
The SB_SETTEXT message sets the text in the specified part of a status window.
Parameters
iPart
Zero-based index of the part to set. If this value is 255, the status window is assumed to be a simple window having only one part.
uType
Type of drawing operation. This parameter can be one of the following values:
Value Meaning
0 The text is drawn with a border to appear lower than the plane of the window.
SBT_NOBORDERS The text is drawn without borders.
SBT_OWNERDRAW The text is drawn by the parent window.
SBT_POPOUT The text is drawn with a border to appear higher than the plane of the window.
SBT_RTLREADING Windows 95 only: Displays text using right-to-left reading order on Hebrew or Arabic systems.
szText
Pointer to a null-terminated string that specifies the text to set. If uType is SBT_OWNERDRAW, this parameter represents 32 bits of data. The parent window must interpret the data and draw the text when it receives the WM_DRAWITEM message.
Return Value
If the operation succeeds, the return value is TRUE.
If the operation fails, the return value is FALSE.
Remarks
The message invalidates the portion of the window that has changed, causing it to display the new text when the window next receives the WM_PAINT message.
See Also
WM_DRAWITEM, WM_PAINT
.
============
SB_GETTEXT QuickInfo Overview Group
[New - Windows NT]
SB_GETTEXT
wParam = (WPARAM) iPart;
lParam = (LPARAM) (LPSTR) szText;
The SB_GETTEXT message retrieves the text from the specified part of a status window.
Parameters
iPart
Zero-based index of the part from which to retrieve text.
szText
Pointer to the buffer that receives the text. This parameter is a null-terminated string.
Return Value
Returns a 32-bit value that consists of two 16-bit values. The low word specifies the length, in characters, of the text. The high word specifies the type of operation used to draw the text. The type can be one of these values:
Value Meaning
0 The text is drawn with a border to appear lower than the plane of the window.
SBT_NOBORDERS The text is drawn without borders.
SBT_POPOUT The text is drawn with a border to appear higher than the plane of window.
SBT_RTLREADING Windows 95 only: Displays text using right-to-left reading order on Hebrew or Arabic systems.
If the text has the SBT_OWNERDRAW drawing type, this message returns the 32-bit value associated with the text instead of the length and operation type.
.
============
SB_GETTEXTLENGTH QuickInfo Overview Group
[New - Windows NT]
SB_GETTEXTLENGTH
wParam = (WPARAM) iPart;
lParam = 0;
The SB_GETTEXTLENGTH message retrieves the length, in characters, of the text from the specified part of a status window.
Parameters
iPart
Zero-based index of the part from which to retrieve text.
Return Value
Returns a 32-bit value that consists of two 16-bit values. The low word specifies the length, in characters, of the text. The high word specifies the type of operation used to draw the text. The type can be one of these values:
Value Meaning
0 The text is drawn with a border to appear lower than the plane of the window.
SBT_NOBORDERS The text is drawn without borders.
SBT_OWNERDRAW The text is drawn by the parent window.
SBT_POPOUT The text is drawn with a border to appear higher than the plane of the window.
SBT_RTLREADING Windows 95 only: Displays text using right-to-left reading order on Hebrew or Arabic systems.
.
============
.
.
Quit = 1
--------------
Top Ten Reasons Not To Procrastinate:
Coming Soon...
Edited by - Art Sentinel on 10 August 2002 02:07:40