Introduction to the Win32 Library
A library is a set of published documents. It could consist of a piece of paper, a book, or a group of books used as a (written) reference for a specific purpose. The programs that are on a Microsoft Windows operating system follow a set of rules and suggestions defined in a library called Win32 (Windows 32-bits). Win32 is a group of functions, objects, variables, and constants that govern how the Microsoft Windows (95 and above) operating systems function. As a reference, it allows individuals and companies to know what is necessary in order to create or develop applications for this specific platform.
|In order to write programs or good and effective
applications for a Microsoft Windows operating system, you do not have to
use a compiler or development environment published by Microsoft or a
company affiliated with Microsoft. Many people fall into that assumption
or misconception. I read in a book once stating that Microsoft Visual C++
was the best environment to create Windows applications BECAUSE MSVC was
published by Microsoft. The author supported the idea that since MSVC is
written by people from inside the company, they are closer to the (Win32) source
code and their MFC library enjoys a better collaboration with the
operating system. This is extremely false. First of all there is
absolutely nothing you can do in MSVC that you cannot do using another
compiler. For example, although Delphi is written in Pascal while Win32 is
written in C, Delphi understand Win32 100% and there is no
function of the Win32 library that Delphi does not understand or cannot access. Secondly, in the world of
Rapid Application Environment (RAD), MSVC is one of the poorest
development environments around, at least as compared to Borland compilers
(C++ Builder and Delphi). All you have to do is open both MSVC and C++
Builder and compare.
At the time of this writing (November 2002), the new Microsoft Visual C++ .NET has been around for a year or so but everything you need to do in MSVC .NET using the new .NET technology has to be done manually: you cannot create a single control by click-n-drop (I know this might not be a big deal; after all, it enables programmers to have a job). Thirdly, the Win32 library is available to every company that wants to develop for Windows, and Win32 is fairly (not highly) documented.
Over all, it is not strictly necessary to know Win32 thoroughly to write programs; but it is highly valuable to know some or most of the intricacies of its implementations. Since Win32 “tells” Microsoft Windows what to do, it is important to know how Windows functions.
In order to create a Win32 application in Borland C++ Builder, you would call the New Items dialog box. From the General property page, click the Console Application icon and click OK. From the Console Wizard dialog box, click the C++ radio button and make sure the Console Application check box is unchecked. When writing a Win32 application, Borland C++ Builder displays a syntax of the WinMain() function.
Just like every C++ application starts from a function called main(), every Win23 application starts with a function called WinMain(). The syntax of the WinMain() function is:
The first argument, hInstance, represents the current instance of the running application.
The second argument, hPrevInstance, represents a previous instance of the application. In our applications, this parameter will always be ignored or set to NULL.
The third argument, lpCmdLine, is a 32-bit long pointer to a null-terminated string that represents the attribute(s) of the command line when running the application.
The last argument, nCmdShow, is an integer that directs how the window should appear. It is a constant integer that can have one of the following values:
The first thing you do when creating a Win32 application is to create a window. A window, or the main window, is created using the WNDCLASS or the WNDCLASSEX structures. Although still available and used, the WNDCLASS structure was mainly used with previous versions of Microsoft Windows. Since everything in WNDCLASS is also available in WNDCLASSEX and more, we will use the latter for our application.
The WNDCLASS and the WNDCLASSEX structures are defined as follows:
In order to use one of these structures, you must first declare it. The name of the variable could be any you like but you should make it easy for the name to reflect the structure you are using. This could be done as follows:
The cbSize (Class-Byte Size) member variable of the WNDCLASSEX structure represents the byte size of the object. To find its value, you will use the sizeof operator like this:
Both structures use a set of constant integers that specify the attributes of the window style. The attributes are defined as follows:
When using these attributes, one of them may be enough for your application. You can use one attribute as follows:
The lpfnWndProc (Long-Pointer-To-A-Function-Window-Procedure) member defines the window procedure. It is provided from an external function that we will review later.
The cbClsExtra (Class-Byte-Class-Extra) and the cbWndExtra (Class-Byte-Window-Extra) members specify the number of extra bytes to provide to the object. Both members receive a value of 0 for regular programs.
The hInstance (Handle-Instance) represents the instance of the current window.
The hIcon (Handle-Icon) variable represents an icon for the current application. If you do not have an icon or you do not want to specify an icon, set this value to NULL. In that case the application would use the default icon. Otherwise, you can use the LoadIcon() function to include an icon.
The hCursor (Handle-Cursor) member is used to specify a cursor for the application. You mostly use the LoadCursor() function to specify a cursor for the application.
The hbrBackground (Handle-Brush-Background) member is used to set a color for the background of the window.
If you decide to display a menu, you can set its identifier using the lpszMenuName (Long-Pointer-To-A-String-As-The-Menu's-Name). If you do not have a menu, set this variable to NULL.
Every window must have a name in your application. This allows you and the application to refer to that window. The name of the window is a null-terminated string set with the lpszClassName (Long-Pointer-To-A-String-As-The-Class'-Name) member.
The WNDCLASSEX structure allows you to specify a small icon for the application. This icon is used when the application is displaying in Windows Explorer using the list, details, or small icons views. This is handled by the hIconSm (Handle-Icon-Small) member variable.
After building a window, you must let the operating system know that you have built a window and intend to use it. Letting the operating system be aware of the window is referred to as registering it. To register a window, you can use either the RegisterClass() or the RegisterClassEx() functions. Their respective syntaxes are:
ATOM RegisterClass(CONST WNDCLASS *lpWndClass );
ATOM RegisterClassEx(CONST WNDCLASSEX *lpwcx );
The use of the WNDCLASS or the WNDCLASSEX structures allow you to "build" a window. In other words, you lay the foundation of a window as a structural object. To create the actual window, you use either the CreateWindow() or the CreateWindowEx() functions and fill it out.
The CreateWindow() function is declared as follows:
The CreateWindowEx() function has the following arguments:
For this tutorial, we will use the CreateWindowEx() version. This function takes quite a few arguments:
The dwExStyle (Window-Extended-Style) argument specifies the style that would control the window.
The lpClassName (Long-Pointer-to-the-Class'-Name) is a pointer to a null-terminated string that specifies or represents the name of the class as the lpszClassName member that was passed to the WNDCLASS or the WNDCLASSEX structures..
The lpWindowName (Long-Pointer-to-the-Window's-Name) is a string that would display as the caption of the window. If you do not want a caption, you can set this argument to NULL or type two double-quotes (that would represent an empty string).
The dwStyle (Window-Style) is an unsigned integer that specifies how to display the window or what style should be used.
The X (X-axis-coordinate) represents the horizontal distance of the top-left corner of the window from the top left corner of the monitor when the window appears (See the following picture). If you do not know or cannot make up your mind on the value of X, you can give it a value of CW_USEDEFAULT (Class-Window-Use-The-Default-Value). If you set the X argument to CW_USEDEFAULT, the operating system would use a default value. The CW_USEDEFAULT value can be selected randomly.
The Y (Y-axis coordinate) represents the vertical distance of the top-left corner of the window from the top-left corner of the monitor when the window appears. If you do not know or cannot make up your mind on the value of Y, you can give it a value of CW_USEDEFAULT. If you set the Y argument to CW_USEDEFAULT, the operating system would use a default value. The CW_USEDEFAULT value can be selected randomly.
Both the X and Y arguments represent the Location of the window:
The Width argument specifies the horizontal measurement of the window. If you do not know or cannot make up your mind on the width of the window, you can give it a value of CW_USEDEFAULT. If you set the Width argument to CW_USEDEFAULT, the operating system would use a default width.
The Height argument specifies the vertical measurement of the window. If you do not know or cannot make up your mind on the height of the window, you can give it a value of CW_USEDEFAULT. If you set the Height argument to CW_USEDEFAULT, the operating system would use a default height.
The Width and the Height represents the Size of the window:
The hWndParent (Handle-to-the-Window's-Parent) argument can be used if the window you are creating will be "owned" by another window. Such a second window would be considered the parent of the window you are creating. In that case, use the hWndParent argument to specify the parent of the window you are creating.
The hMenu (Handle-to-a-Menu) specifies the menu to be used with the current window. If you do not have a menu, pass this argument as NULL.
The hInstance (Handle-Instance) argument is the instance of the current window, the same that was specified in the window structure.
The lpParam (Long-Pointer-to-a-Parameter) is a long pointer to a value passed to another class, in case your application is made of various objects, such as various windows.
Every time you create an object in your program, like the window we have created using the WNDCLASSEX structure, such an object needs to find a way to communicate with the operating system. It is not the job of the WinMain() function to let the operating system know what an object wants to do. As it happens, Microsoft Windows is a message-oriented operating system. Each object of your program sends messages to Microsoft Windows. Whenever the operating system receives one of those messages, it must analyze and process it.
To send its messages to the operating system, an object, such as a window, must send four pieces of information to the operating system. To send these pieces of information as one request (instead of sending four disparate requests), the object must put them in a function that would carry them as arguments. The name of the function is not important but there are rules the object (actually it is your responsibility) must follow. The function that carries the message of the object must
As stated already, the name of the function is not important but the name of the function must be exactly assigned to the lpfnWndProc member of the object you are creating. The syntax used for the function is:
LRESULT CALLBACK MyMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT WINAPI MyMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
By tradition or pure habit, most programmers define and declare this function using words or suffixes like Wind, Wnd, Proc, and Procedure. Therefore, it is usual to create this function with a name like WndProc or WindowProc. The syntax of the function can be written as follows:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
The hWnd (Handle-Window) argument is a handle to the object or window that is sending the message(s).
The uMsg (Message) is an unsigned integer that represents the message that is being sent. Most or all messages are represented by a map of integral values of the Win32 library.
The wParam (Parameter, the w does not necessarily mean window) is an additional piece of information that can accompany the uMsg argument. The value of wParam depends on the type of message that is being sent. It would mean different things to the operating system if the message sent has to do with an action on the keyboard (for example if the message was sent because the user pressed a key on the keyboard) or an action on the mouse (for example if the message was sent because the user pressed the right button on the mouse).
The lParam (Parameter, the l does not necessarily mean window or long integer) is an additional piece of information that can be sent with the uMsg argument.
To make application development easy, that is, to provide Rapid Application Development (RAD), Borland simpliefied the above steps.
C++ Builder uses the same WinMain() function to create an application. Instead of defining a window class structure and creating a window using the CreateWindow() function, you can simply add a form and use the TApplication::CreateForm() function to start the application by displaying a form.
When creating applications using Borland C++ Builder, you will essentially be choosing objects that are necessary for your application. The objects are provided in a pool, ranging from very simple to fairly complicated. To manage all these objects, Borland created a library called the Visual Component Library (VCL) based on the Pascal language but fully adhering to the C++ language.
The VCL is a set of functions, classes, variables, and libraries that provide the application developer to choose which objects are appropriate to respond to a particular scenario.
The Visual Component Library is organized like a tree (upside-down) with objects inheriting from earlier ones:
A class called TObject is the ancestor or the parent of all classes used in the VCL. This class provides the starting point for the other objects. When you will be implementing an object in your application, you can use either the Help files or the poster that ships with C++ Builder to trace the ancestry of the object: but this is not always important.
There are three categories of objects you will be using when creating your programs: the VCL objects, your own objects, and Win32 objects. A program can include one category. Many of the programs we will be writing essentially consist of VCL objects. A program can also combine data types and objects of any of the three categories.
Here are examples of two objects that implement two geometric figures, namely a trapezoid and a parallelogram:
This would produce:
TObject is the ancestor of all objects and classes you will be using when writing your applications using the VCL. Like any library, the VCL has some implementations and syntaxes that are particular to it. There are some details you should be aware of about objects that are part of the VCL. One of those details involves deriving an object from TObject.
To inherit an object from the TObject class:
Based on these rules, the above classes can be made children of the TObject as follows:
Following the hierarchy of VCL objects, most of the objects we will use in this book will be derived from a class of the VCL. Your object does not have to use any of the features of VCL or any of the access techniques of C++ Builder.
|Home||Copyright © 2005-2007 FunctionX, Inc.|