C++ - ObjectWindows Library

Introduction

ObjectWindows Library (OWL) is a set of classes that define a programmatic front-end to the Microsoft Windows operating system. These classes give rise to a set of objects that are event-driven and correspond to the visual elements of the OS. The object-oriented nature makes individual elements easier to manipulate. The event-driven nature allows for the multi-tasking capabilities of the OS to be built into the API.

Since MS-Windows does not support pre-emptive multi-tasking, any multi-tasking has to be cooperative. Thus it is especially important that event-processing is time-sliced.

MS-Windows can easily access and manipulate certain types of pre-defined resources. These are edited with a resource editor (eg. Resource Workshop) and linked into the executable. Thereafter they can be loaded and used on demand. Some of the resources used commonly are dialog boxes, icons and menus.

Common Classes

TApplication is the API part of the kernel. The OS has a built-in event-driven kernel which uses a system of messages to communicate among its various windows. However, this interface to the OS is through a classical set of functions and procedures. OWL not only provides templates for the various visual elements, but also makes calling of event-processing procedures automatic.

TWindow is the basic window object. It has a well-defined interface but is not of much use since all it creates is a blank window. It normally serves as the base class for user-defined windows. Windows can be either modal or modeless. Modal windows do not allow the user to switch to other windows, while modeless windows do.

TDialog is the equivalent of a dialog box. It contains within it many dialog box controls, which may be push buttons, text input lines, check boxes, etc. These can be inserted using a visual programming tool (eg. Resource Workshop) or manually by inserting the code to create the objects into the dialog box's constructor. Dialog box controls are all self-driven objects, capable of processing their own events. Thus they need no further programming. All the programmer has to do is set up the initial values and read off the final values when the dialog box is about to close. Intermediate changes can be explicitly set by including functions with specific attributes that will be called automatically by the event-driven kernel.

TWindowsObject is the greastest common divisor of all the visual element objects. It contains the properties that are common to all objects. Thus, all visual objects have this as their ultimate base class.

TButton, TExit, TStatic and other controls are defined as classes so that they can be overridden for unique behaviour in special instances.

Sample OWL Program

#define WIN31 
#include <owl.h> 
class MWindow : public TWindow 
{ 
public: 
   MWindow ( PTWindowsObject AParent, LPSTR ATitle, 
             PTModule AModule = NULL )
    : TWindow (AParent, ATitle, AModule) 
   { 
      AssignMenu ("MAINMENU"); 
   }; 
   virtual void HandleAbout ( RTMessage ) = [ CM_FIRST + 1 ] 
   { 
      GetApplication ()->ExecDialog (new TDialog (this, "ABOUT")); 
   }; 
}; 
class MApplication : public TApplication 
{ 
public: 
   MApplication ( LPSTR AName, HANDLE AnInstance, HANDLE APrevInstance, 
                  LPSTR ACmdLine, int ACmdShow)
    : TApplication (AName, AnInstance, APrevInstance, ACmdLine, ACmdShow) 
      {}; 
protected: 
   virtual void InitMainWindow (); 
}; 
void MApplication::InitMainWindow () 
{ 
   MainWindow = new MWindow (NULL, "Hello World"); 
} 
int PASCAL WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                     LPSTR lpCmdLine, int nCmdShow ) 
{ 
   MApplication M ("test", hInstance, hPrevInstance, lpCmdLine, nCmdShow); 
   M.Run (); 
   return M.Status; 
}

This is the basic skeleton for all OWL applications. The TApplication class must be overridden so that the InitMainWindow can take on a different meaning. In this case InitMainWindow is made to create a window of a user type, rather than the built-in TWindow type. The user window class MWindow does only two new things compared to its base class. The first is that it uses a built-in menu resource and the second is an event-handler which responds to the user selecting the About option from the menu.

The main part of the program for all windows programs is found in WinMain instead of the standard main function. For most simple applications the main program only has to initialize the kernel and Run it.

TWindow

TWindow has the basic characteristics of all windows, so it can be used as a generalisation for the way in which all windows in OWL function. It has a number of functions that are called at particular times by the kernel to do particular things. This can be exploited by the programmer to perform tasks at those times.

The constructor only stores the values for the initialization and does not create the visual element.

SetupWindow calls the kernel functions to set up the visual elements. Only after SetupWindow has been called can the window or dialog box communicate with any of its controls.

Paint is called by the kernel when it notices that the window has not been painted yet. Only then does the window appear on the screen.

AssignMenu automatically adds a menu to the window. This must be called from the constructor.

Parent is a pointer to the parent of the window - NULL if it has none.

HWindow is the MS-Windows unique identifier given to the window. This is needed to call some native MS-Windows functions.

GetApplication retrieves a pointer to the TApplication for that program.

TDialog

Dialog boxes that have active controls must be created using user classes based on TDialog or one of its descendants. These classes can then override the SetupWindow function to initialize variables using SendDlgItemMsg after setting up the window.

SendDlgItemMsg sends a message to the window - the relevant event processor processes the message. It can also be used to retrieve values from the dialog box. This can be done in the CloseWindow function.

Automatic functions can be set up to respond to button clicks and other notification events.

Example:
   virtual void HandleOk ( RTMessage Msg ) = [ ID_FIRST + 1];

All event-handlers take this form, whether they handle a dialog box, menu or internal message. The name of the function is not relevant - only the last two numbers are. The first indicates the type of the event. ID_FIRST indicates that it handles dialog box notifications. WM_FIRST is used for internal messages and CM_FIRST for menu item selections. The single parameter contains the data of the message and is useful for passing parameters and receiving data.

TApplication

IdleAction is a function that gets called when the application and system are not busy. This can be over-ridden to do useful work.

InitMainWindow is absolutely essential and must be over-ridden in every program !

Conclusion

ObjectWindows is just one example of an advanced object-oriented event-driven API that allows easy interfacing to a GUI. MFC (Microsoft Foundation Classes) is another popular interface to MS-Windows. All these APIs are extremely complex and not the effort poring over their details. A better approach is to concentrate on using the help files and sample applications whenever you cannot accomplish something that you know possible but cant seem to get right.