home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
dho.zip
/
DHO
/
TUTORIAL
/
TUTORIAL.TXT
< prev
Wrap
Text File
|
1995-09-03
|
23KB
|
785 lines
Developer Helper Tutorial
-------------------------
This tutorial demonstrates the basic operations required to
begin to develop an application with the Developer Helper
Application Framework. While it is not a primer on OS/2
Presentation Manager programming, those who are familliar
with C++, and with object oriented techniques should be
able to understand this tutorial, and possibly glean some
OS/2 programming techniques.
====================================================================
Part 1: Creating a skeleton Application.
It's pretty simple to create the base for you application. The
following code will create an application, along with a main window.
--------------------------------------------------------------------
// example1.cc
#include<applicat.h>
#define kAppId 100
//=========================================
// program entry point
INT main(void)
{
TApplication app(kAppId);
app.init(); // initialize object
app.run(); // begin event loop
return 0;
}
--------------------------------------------------------------------
The main event loop creates an application object, which
in turn initializes itself and creates a main window in the
member function init. The event loop is then executed, and
proceeds untill the application is terminated. Notice the
parameter sent to the application obkect's constructor --
it will be the resource id for all major resources in future
examples.
Note -- most objects in Developer Helper have an initialization
function along with a constructor. The constructor will set up the
object to a safe state, but the initializer will perform the actual
memory allocations, etc. The init function members all return
BOOL values -- TRUE upon object creation success, and FALSE upon failure.
====================================================================
Part 2: Redefining the type of Main Window
Once the skeleton application is created, the next major step is to
customize the kind of main window the application creates. The function
TApplication::CreateMainWindow is called during application initialization
and it is here where one can change the type of the window which is to be
the application's main window.
--------------------------------------------------------------------
// example2.cc
// This example demonstrates how to customize
// an application object, specifically how to modify
// the type of main window for the application
//DHO application object header file
#include<applicat.h>
#include<framewin.h>
#define kAppId 100
class TExampleApp : public TApplication
{
public:
TExampleApp(ULONG res):TApplication(res){;};
virtual void CreateMainWindow()
{
MainWin=new TFrameWindow(fResource, "DHO Tutorial App");
}
};
//=========================================
// program entry point
INT main(void)
{
TExampleApp app(kAppId);
app.init(); // initialize object
app.run(); // begin event loop
return 0;
}
--------------------------------------------------------------------
The only difference in this example from the default inirialization
is in the name of the main window. However, in the next example we will
redefine the main window's default behavior, further customizing the
application
====================================================================
Part 3: Redefining Window Behavior
By automating the window registration procedures required by
the OS/2 Presentation Manager, the Developer Helper framework
makes it easy to define window behaviors. The following example
demonstrates some simple customization by having the main window
include a frame window icon in the system menu.
--------------------------------------------------------------------
class TExampleFrameWin : public TFrameWindow
{
public:
TExampleFrameWin(ULONG id, char *title):TFrameWindow(id, title)
{ fShellPos = TRUE;};
virtual BOOL init()
{
if (TFrameWindow::init())
{ // add a frame icon
this->setIcon(WinQuerySysPointer(HWND_DESKTOP,
SPTR_ICONINFORMATION, FALSE));
return TRUE;
}
return FALSE;
}
};
class TExampleApp : public TApplication
{
public:
TExampleApp(ULONG res):TApplication(res){;};
virtual void CreateMainWindow()
{
MainWin=new TExampleFrameWin(fResource, "DHO Tutorial App");
}
};
--------------------------------------------------------------------
The sample application now has a main window which is starting to
define it's own appearance and behaviors.
====================================================================
Part4: Adding a client window to a frame window
In the Developer Helper Application framework, the class function
members for windows which begin with the word do are called in response
to a message from the OS/2 Presentation Manager. For example, the doSize
function of the class TWindow will be called as a direct result of the
window receiving a WM_SIZE message from PM. It is easy to define
window behavior in response to these operating system messages. In the
next example, we add a client window to our main window which defines
behavior in response to the WM_SIZE and WM_PAINT messages.
--------------------------------------------------------------------
class TExampleClientWin : public TWindow
{
SHORT sPageX, sPageY;
public:
TExampleClientWin(ULONG id, TWinBase *parent):TWindow(id, parent){;};
virtual void doSize(WinMsg wm)
{
sPageX = SHORT1FROMMP(wm.mp2);
sPageY = SHORT2FROMMP(wm.mp2);
}
virtual void paintWindow(HPS ps, RECTL rcl)
{
POINTL ptl;
SHORT w;
if ((sPageX == 0) && (sPageY == 0))
{
sPageX = rcl.xRight - rcl.xLeft;
sPageY = rcl.yTop - rcl.yBottom;
}
if (sPageX > sPageY)
w = sPageY / 2;
else
w = sPageX / 2;
WinFillRect(ps, &rcl, CLR_BLUE);
rcl.xLeft = (sPageX/2) -(w/2);
rcl.xRight = rcl.xLeft +w;
rcl.yBottom = (sPageY /2) -(w/2);
rcl.yTop = rcl.yBottom+w;
WinFillRect(ps, &rcl, CLR_YELLOW);
}
};
class TExampleFrameWin : public TFrameWindow
{
public:
TExampleFrameWin(ULONG id, char *title):TFrameWindow(id, title)
{ fShellPos = TRUE;};
virtual BOOL init()
{
if (TFrameWindow::init())
{ // add a frame icon
this->setIcon(WinQuerySysPointer(HWND_DESKTOP,
SPTR_ICONINFORMATION, FALSE));
TExampleClientWin *client = new
TExampleClientWin(FID_CLIENT, this);
return client->init();
}
return FALSE;
}
};
--------------------------------------------------------------------
The example program now has a more complex, as well as a more
colorful main window. One minor note to mention here -- the
function TWindow::paintWindow is called by the function
TWindow::doPaint. This is becase of some preliminary behavior
that the class TWindow performs to alleviate some tediousness
of drawing in windows. For those who are more interested,
examine the source code for the function TWindow::doPaint
in the DHO source code file window.cc
====================================================================
Part 5: Adding a menu to the frame window
The TFrameWindow class has an attribute structure which is
used in the init member to set various features of the window.
Various fields of this structure can be modified at any point
from the object's creation untill the initialization of the
OS/2 window in the init call, and these changes will manifest
themselves in the appearance and behavior of the window.
For example, by setting the field menu of the fFrAttr member
of the class TFrameWindow, the init function will attempt to
load and bind a menu resource to the menu. In this example,
our sample application will load a memu resource which is defined
in the file example5.rc
--------------------------------------------------------------------
// example5.cc
class TExampleFrameWin : public TFrameWindow
{
public:
TExampleFrameWin(ULONG id, char *title):TFrameWindow(id, title)
{
fShellPos = TRUE;
fFrAttr.menu = TRUE;
};
};
/* example5.rc */
#include<os2.h>
MENU 100
BEGIN
SUBMENU "~File", 101
BEGIN
MENUITEM "Change Colors", 102
MENUITEM "", 5, MIS_SEPARATOR
MENUITEM "E~xit", 103
END
SUBMENU "~Help", 201
BEGIN
MENUITEM "Product Information", 104
END
END
--------------------------------------------------------------------
Other behaviors which can be modified in this way are:
TFrameWindowAttr field Behavior
----------------------- ---------------
BOOL titlebar TRUE -- has titlebar *
FALSE -- no titlebar
BOOL sysmenu TRUE -- has system menu *
FALSE -- no system menu
BOOL menu TRUE -- Load menu
FALSE -- do not load menu *
BOOL icon TRUE -- Load icon
FLASE -- Do not load icon *
BOOL minbutton TRUE -- has min button *
FALSE -- no min button
BOOL maxbutton TRUE -- has max button *
FLASE -- no max button
BOOL sizeborder TRUE -- has a size border *
FALSE -- no size border
BOOL tasklist TRUE -- included in task list
FLASE -- not included in task list *
BOOL vscroll TRUE -- include vertical scroll
FALSE -- no vertical scroll bar *
BOOL hscroll TRUE -- include horizontal scroll
FALSE -- no horizontal scroll bar *
BOOL acceltable TRUE -- load accelerator table
FALSE -- no accelerator table *
BOOL shellPos TRUE -- shell positions window *
FALSE -- window positions self
ULONG x initial x axis position
DEFAULT -- 0
ULONG y initial y axis position
DEFAULT -- 0
ULONG width initial width
DEFAULT -- 0
ULONG height initial height
DEFAULT -- 0
* denotes the default for the class TFrameWindow
====================================================================
Part 6: Responding to Command Events
In the OS/2 presentation managers, messages from various controls
(such as menus and push buttons) are sent to a window in the form
of a WM_COMMAND message. In Developer Helper, the doCommand function
is called in reponse to a WM_COMMAND message, and it is here where most
of the functionality of an application is fleshed out.
In this next example, we will override TExampleFrameWin's member
doCommand to provide functionality for each of the selections in
the frame window's menu.
--------------------------------------------------------------------
// example6.cc
class TExampleFrameWin : public TFrameWindow
{
// various members
virtual void doCommand(WinMsg wm)
{
SHORT command = SHORT1FROMMP(wm.mp1);
if (command == 103)
{
WinPostMsg(wm.hwnd, WM_QUIT, 0,0);
}
else if (command == 104)
{
WinMessageBox(HWND_DESKTOP, hwnd, (PSZ)aboutText,
(PSZ)"Product Information", 0, MB_MOVEABLE | MB_OK
| MB_ICONEXCLAMATION);
}
}
// more various members
};
--------------------------------------------------------------------
The macro SHORT1FROMMP is called a 'cracker' macro, and is
supplied in os2.h. In this case, it is used to extract the
command id from the message structure.
====================================================================
Part 7: introduction To Dialogs
There are two types of dialog boxes in the OS/2 Presentation
Manager -- Modal Dialogs and Non-Modal Dialogs. Modal dialogs
seize the applications focus, and retain it untill they are
dismissed. Non-modal dialogs can gain and loose the applications
focus much like normal windows do.
In this example, we will be addding a modal dialog to our
example program. The DHO class which handles the modal dialog
is called TNonModalDialog, and is created and initialized much
like a normal window. However, a dialog will not be displayed
until the member function TModalDialof::Execute is called.
--------------------------------------------------------------------
// example7.cc
class TColorSelectDlog : public TModalDialog
{
TValueSet *fBkgndColors, *fShapeColors;
public:
TColorSelectDlog(ULONG resource, TWinBase *owner, void *buffer):
TModalDialog(resource, owner, buffer){;};
virtual BOOL init()
{
ULONG index, i, j;
if (TModalDialog::init())
{
fBkgndColors=new TValueSet(201, this);
fShapeColors=new TValueSet(202, this);
index = 1;
j=1;
for (i=1; i<4; i++)
{
for (j=1; j<6; j++)
{
fBkgndColors->setItem(i,j,(VOID*)index);
fShapeColors->setItem(i,j,(VOID*)index);
index++;
}
}
return TRUE;
}
return FALSE;
}
};
class TExampleFrameWin : public TFrameWindow
{
public:
TExampleFrameWin(ULONG id, char *title):TFrameWindow(id, title)
{
fShellPos = TRUE;
fFrAttr.menu = TRUE;
fFrAttr.icon = TRUE;
};
virtual BOOL init()
{
if (TFrameWindow::init())
{
TExampleClientWin *client = new
TExampleClientWin(FID_CLIENT, this);
return client->init();
}
return FALSE;
}
virtual void doCommand(WinMsg wm)
{
SHORT command = SHORT1FROMMP(wm.mp1);
if (command == 102)
{
TColorSelectDlog dlog(200, this, NULL);
dlog.init();
dlog.Execute();
}
if (command == 103)
{
WinPostMsg(wm.hwnd, WM_QUIT, 0,0);
}
else if (command == 104)
{
WinMessageBox(HWND_DESKTOP, hwnd, (PSZ)aboutText,
(PSZ)"Product Information", 0, MB_MOVEABLE | MB_OK
| MB_ICONEXCLAMATION);
}
}
};
--------------------------------------------------------------------
This example, in addition to creating a modal dialog also creates
two Value Set controls. The resource code to create this dialog
follows:
--------------------------------------------------------------------
/* example7.rc */
DLGTEMPLATE 200 LOADONCALL MOVEABLE DISCARDABLE
BEGIN
DIALOG "Window Colors", 200, 30,10, 150, 125, WS_VISIBLE,
FCF_TITLEBAR
BEGIN
LTEXT "Background Colors", 203, 3, 114, 80, 8
CONTROL "", 201, 10, 73, 130, 40, WC_VALUESET,
VS_COLORINDEX | VS_BORDER | VS_ITEMBORDER |
WS_TABSTOP | WS_VISIBLE
CTLDATA 8, 0, 3, 5
LTEXT "Shape Colors", 204, 3, 65, 80, 8
CONTROL "", 202, 10, 25, 130, 40, WC_VALUESET,
VS_COLORINDEX | VS_BORDER | VS_ITEMBORDER |
WS_TABSTOP | WS_VISIBLE
CTLDATA 8, 0, 3, 5
PUSHBUTTON "Cancel", DID_CANCEL, 34, 3, 55, 15
DEFPUSHBUTTON "OK", DID_OK, 92, 3, 55, 15
END
END
--------------------------------------------------------------------
Notice the code in TExampleFrameWin::doCommand which actually
creates and executes the dialog -- only 3 lines of code are required
to perform this operation.
====================================================================
Part 8: Finishing Touches
Now, all that is left to do in order to finish this demo
application is to initialize the value set objects in the
color select dialog class and to change the Frame Window's
client window's colors according to the inputs in these
value sets.
The final code for the application is:
--------------------------------------------------------------------
/****************************************/
/* Developer Helper Object Set */
/* (C) 1994-95 Thomas E. Bednarz, Jr. */
/* All rights reserved */
/***************************************/
/* $Id: tutorial.txt 1.1 1995/09/03 00:49:18 teb Exp $ */
/*******************************************
* Example8.cc
*
*******************************************/
#define INCL_WIN
#include<os2.h>
//DHO application object header file
#include<applicat.h>
#include<framewin.h>
#include<moddlog.h>
#include<vset.h>
#define kAppId 100
#define aboutText "Developer Helper Sample App\n (c) 1994-95 Tom Bednarz\n All Rights Reserved."
class TColorSelectDlog : public TModalDialog
{
TValueSet *fBkgndColors, *fShapeColors;
public:
TColorSelectDlog(ULONG resource, TWinBase *owner, void *buffer)
TModalDialog(resource, owner, buffer){;};
virtual~TColorSelectDlog()
{
if(fBkgndColors)
delete fBkgndColors;
if(fShapeColors)
delete fShapeColors;
}
virtual BOOL init()
{
ULONG index, i, j;
if (TModalDialog::init())
{
fBkgndColors=new TValueSet(201, this);
fShapeColors=new TValueSet(202, this);
index = 1;
j=1;
for (i=1; i<4; i++)
{
for (j=1; j<6; j++)
{
fBkgndColors->setItem(i,j,(VOID*)index);
fShapeColors->setItem(i,j,(VOID*)index);
index++;
}
}
return TRUE;
}
return FALSE;
}
virtual void doControl(WinMsg wm)
{
if (SHORT2FROMMP(wm.mp1) == VN_SELECT)
{
USHORT i,j;
fBkgndColors->getSelection(i,j);
fBackground=((i-1)*5)+j;
fShapeColors->getSelection(i,j);
fShape=((i-1)*5)+j;
}
else
TModalDialog::doControl(wm);
}
void getColors(ULONG &bgnd, ULONG &shape)
{
bgnd = fBackground;
shape = fShape;
}
};
class TExampleClientWin : public TWindow
{
SHORT sPageX, sPageY;
ULONG fBkgColor, fShapeColor;
public:
TExampleClientWin(ULONG id, TWinBase *parent):TWindow(id, parent)
{
fBkgColor = CLR_BLUE;
fShapeColor = CLR_YELLOW;
};
virtual void doSize(WinMsg wm)
{
sPageX = SHORT1FROMMP(wm.mp2);
sPageY = SHORT2FROMMP(wm.mp2);
}
virtual void paintWindow(HPS ps, RECTL rcl)
{
POINTL ptl;
SHORT w;
if ((sPageX == 0) && (sPageY == 0))
{
sPageX = rcl.xRight - rcl.xLeft;
sPageY = rcl.yTop - rcl.yBottom;
}
if (sPageX > sPageY)
w = sPageY / 2;
else
w = sPageX / 2;
WinFillRect(ps, &rcl, fBkgColor);
rcl.xLeft = (sPageX/2) -(w/2);
rcl.xRight = rcl.xLeft +w;
rcl.yBottom = (sPageY /2) -(w/2);
rcl.yTop = rcl.yBottom+w;
WinFillRect(ps, &rcl, fShapeColor);
}
void setColors(ULONG bgnd, ULONG shape)
{
fBkgColor = bgnd;
fShapeColor = shape;
}
void getColors(ULONG &bgnd, ULONG &shape)
{
bgnd = fBkgColor;
shape = fShapeColor;
}
};
class TExampleFrameWin : public TFrameWindow
{
TExampleClientWin *client;
public:
TExampleFrameWin(ULONG id, char *title):TFrameWindow(id, title)
{
fShellPos = TRUE;
fFrAttr.menu = TRUE;
fFrAttr.icon = TRUE;
};
virtual BOOL init()
{
if (TFrameWindow::init())
{
client = new TExampleClientWin(FID_CLIENT, this);
return client->init();
}
return FALSE;
}
virtual void doCommand(WinMsg wm)
{
SHORT command = SHORT1FROMMP(wm.mp1);
if (command == 102)
{
TColorSelectDlog dlog(200, this, NULL, 1, 1);
dlog.init();
if (dlog.Execute() == MBID_OK)
{
ULONG i,j;
dlog.getColors(i,j);
client->setColors(i,j);
client->forceUpdate();
}
}
if (command == 103)
{
WinPostMsg(wm.hwnd, WM_QUIT, 0,0);
}
else if (command == 104)
{
WinMessageBox(HWND_DESKTOP, hwnd, (PSZ)aboutText,
(PSZ)"Product Information", 0, MB_MOVEABLE | MB_OK
| MB_ICONEXCLAMATION);
}
}
};
class TExampleApp : public TApplication
{
public:
TExampleApp(ULONG res):TApplication(res){;};
virtual void CreateMainWindow()
{
MainWin=new TExampleFrameWin(fResource, "DHO Tutorial App");
}
};
//=========================================
// program entry point
INT main(void)
{
TExampleApp app(kAppId);
app.init(); // initialize object
app.run(); // begin event loop
return 0;
}
--------------------------------------------------------------------