home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
VSCPPv8.zip
/
VACPP
/
IBMCPP
/
samples
/
IOC
/
LANCELOT
/
LANCELOT.HLP
(
.txt
)
< prev
next >
Wrap
OS/2 Help File
|
1995-06-05
|
14KB
|
380 lines
ΓòÉΓòÉΓòÉ 1. What is Lancelot? ΓòÉΓòÉΓòÉ
Lancelot is a personnel data tracking tool. It tracks general personnel
information, badge, status, skills, system account information, projects,
tasks, and your timecard. This sample application is intended to show
integration rather than optimum performance or coding.
Lancelot was written by our QA group to utilize some of the more complex
objects provided by the IBM Open Class: User Interface Class Library. Lancelot
primarily utilizes these objects:
IFrameWindow
IMenuBar
Infoarea
IHelp
IFont
IResourceLibrary
IContainerControl
IContainerObject
IPopupMenu
INotebook
IMultiCellCanvas
ISetCanvas
IProfile
IEntryField
IPushButton
IGraphicPushButton
INumericSpinButton
IComboBox
ICheckBox
IMenuBar
ITitle
IString
ICommandHandler
ICnrHandler
ICnrMenuHandler
IDM* <Direct Manipulation (i.e. Drag/Drop)>
IToolBar
IToolBarButton
IFlyOverHelp
IFlyOverHelpHandler
IGPie
IGRectangle
IGString
In addition, Lancelot uses a simple flat database implemented with IProfile.
However, this flat database is used only to show data interaction with the GUI
objects and avoid requiring a relational database installed on your system.
Note: You should NOT use the flat database provided for any of your own
applications! We suggest you don't even look at the internals of the database
code. The files you should avoid are ld*.*pp. You should use a true
relational database for your applications.
ΓòÉΓòÉΓòÉ 2. Lancelot Usage ΓòÉΓòÉΓòÉ
To create Lancelot, you must first compile and link the application and it's
components.
On AIX, issue
make
On OS/2, issue
nmake
For other environments, issue
make
To execute Lancelot, simply issue
lancelot
ΓòÉΓòÉΓòÉ 2.1. Lancelot Main window ΓòÉΓòÉΓòÉ
Lancelot's main view is what you see when the application first comes up. It
contains the Query Personnel object and any private query objects you may have
created. The Query Personnel object queries employee information dependent on
your search criteria. You have the option of saving the search criteria in the
main view for faster access next time.
ΓòÉΓòÉΓòÉ 2.2. Lancelot Query Information window ΓòÉΓòÉΓòÉ
Lancelot's Query Information window contains a notebook with pages for
specifying personnel search criteria. The pages available are:
General Page General information for a person.
Accounts Page User accounts and systems for a person.
Skills Page Individual skills for a person.
Badge Page Badge information for a person.
Status Page Employement status information for a person.
The buttons available are:
Query Query the personnel database given your search
criteria. If persons are found matching your
criteria, a window appears with objects
representing each person.
Save Save your search criteria to the main view
window for each access next time.
Help Provide help for a specific page
ΓòÉΓòÉΓòÉ 2.3. Lancelot Personnel window ΓòÉΓòÉΓòÉ
Lancelot's Personnel view is what you see when the application finds personnel
matching your search criteria. It contains an object for each person. By
opening an object, the Employee Information window appears with specific
information for this person.
ΓòÉΓòÉΓòÉ 2.4. Lancelot Employee Information window ΓòÉΓòÉΓòÉ
Lancelot's Employee Information window is displayed to show employee
information for a single employee. Any changes to the employee information
will be saved in the database. However, the Undo button can undo any changes
you entered.
The pages available are:
General Page General information for the person.
Accounts Page User accounts and systems for the person.
Skills Page Individual skills for the person.
Badge Page Badge information for the person.
Status Page Employement status information for the person.
Project Page Projects the person has worked on.
Tasks Page Work tasks the person has worked on.
Timecard Page Timecard for the person.
The buttons available are:
Undo Undo any changes to the employee's information
you entered.
Help Provide help for a specific page
ΓòÉΓòÉΓòÉ 3. Lessons Learned ΓòÉΓòÉΓòÉ
In coding Lancelot, we learned alot by the fine nuances of coding GUI
applications.
ΓòÉΓòÉΓòÉ 3.1. General ΓòÉΓòÉΓòÉ
There are several general things we learned in coding Lancelot.
When instantiating IWindow objects with the new operator, you must make
sure to delete these objects when finished. However, there are times
when you don't know how many windows you will have. Therefore, you can
use setAutoDeleteObject(). This function deletes the IWindow object for
you.
Example:
IFrameWindow* myFrame = new IFrameWindow( ID_FRAME );
myFrame->setAutoDeleteObject( true );
IProfile changes are not visible until the IProfile object is destroyed.
There are two methodologies to using event handlers.
1. Create your own event handler class that inherits from an event
handler
2. Multiply inherit from some visual object and from an event handler
The first method is preferred. See LMainWindow (lmainwin.cpp) for an
example. However, the second method requires less coding. See LInfoWindow
(linfowin.cpp) for an example.
If you do not specify a title string or define an ITitle for a frame
window, the frame window will get its title from the resource file if the
resource Id for the frame window is specified in the string table.
ΓòÉΓòÉΓòÉ 3.2. Containers ΓòÉΓòÉΓòÉ
There are several things we learned about containers in coding Lancelot. Here
are some of the items we learned.
In order for a container to show detailsView, the container must know
about offset (binary location) information for individual fields in a
data class (data structure). There are two approaches for the container
to query a data class' fields:
1. Make the data class a friend of the container. Then the container
can use something like this when creating it's columns:
IContainerColumn lastNameColumn(
offsetof( EmployeeCnrObject, theLastName ) );
2. -or- A better solution is to create a function in the data class for
each data field. The function would do the following:
unsigned long EmployeeObject::lastNameOffset()
{
return ( offsetof( EmployeeCnrObject, theLastName ) );
}
The container column would then look like this:
IContainerColumn nameColumn(
EmployeeCnrObject::lastNameOffset() );
The only advantage to using option 2 is that any container can get the
data class field offsets without having to be friends. The disadvantage
is that if you have alot of data fields, you will have to code query
functions for each. A good example of each can be found in the class
LMainCnr (lmainwin.cpp) and LPersonnelCnr (lperswin.cpp).
If you have a container object that contains your own data class object
and you want your data class object's private data fields to appear in
the container, do not specify the offset for your data class object
itself. Instead, specify the offset of the container object's variable
name representing your your data class and reference the data class
object's internal data field.
Example:
IContainerColumn lastNameColumn(
offsetof( EmployeeCnrObject, privateData.theLastName ) );
In TreeIconView, the container allows only single selection. Therefore,
we must disallow the Select All function since only the last cnr object
will be selected. And we must disallow the Deselect All function since
an exception will be thrown.
ΓòÉΓòÉΓòÉ 3.3. Notebooks ΓòÉΓòÉΓòÉ
There are several things we learned about notebooks in coding Lancelot. Here
are some of the items we learned.
When a page is added to a notebook and using the autoPageSize style, the
pages are automatically resized to the current notebook size. Therefore,
we need to resize the notebook pages to their minimum size so that the
notebook can properly calculate it's minimum size. See LInfoNotebook
(linfonb.cpp) for an example.
In order to property size notebook tabs based on the current font size,
we sized the major tab width to be the
( average character width for the current font ) X ( number of characters
we want to display ).
ISized the major tab height to be the
( average uppercase height for the current font ) X 2.
setMajorTabSize( ISize( notebookFont.avgCharWidth() *
ID_INFO_NOTEBOOK_TAB_CHARS,
notebookFont.avgUppercase() * 2 ) );
See LInfoNotebook (linfonb.cpp) for an example.
ΓòÉΓòÉΓòÉ 3.4. Canvases ΓòÉΓòÉΓòÉ
There are several things we learned about canvases in coding Lancelot. Here are
some of the items we learned.
For aligning like objects such as radio buttons, ISetCanvas does the best
job aligning.
For aligning unlike objects such as entryfields and static text,
IMultiCellCanvas does the best job aligning.
When aligning unlike objects, a minimum size for one object is usually
too large for an unlike object in the same column. Therefore, place the
unlike object in a different column (usually one column more is
sufficient).
ΓòÉΓòÉΓòÉ 3.5. Help ΓòÉΓòÉΓòÉ
There are several things we learned about help in coding Lancelot. Here are
some of the items we learned.
General help is simply the panel associated with the HELPITEM in the help
table.
Example:
HELPITEM ID_MAIN, ......
Help index and using help are usually generic. So we can use the generic
system help by getting the id from IHelpWindow::index and
IHelpWindow::using.
Keys help is always specific to the application. Therefore, we must
write our own in the .IPF file. There can be two approaches to making
keys help work:
1. In the command() function, case off the id defined in the .RC for
the user selecting "Keys help" and then calling help.show( id ) that
is defined in the .IPF file. However, if the user selects "Help/Keys
help" inside the Keys Help help window, an error can occur since the
help window itself doesn't know about the id in the .IPF file.
2. -or- A better way is:
a. Identify the "Keys help" menu with SC_HELPKEYS and specify the
MIS_SYSCOMMAND attribute.
b. Create an IHelpHandler in your source code
c. Have the IHelpHandler object handleEventsFor the main window
d. Override the keysHelpId() function to specify the .IPF id for
keys help.
Example:
event.setResult( id-in-IPF-file );
Product information is your own dialog defined in the .CPP.
F1 help for Keys Help must match the id for SC_HELPKEYS. It is defined
for OS/2 PM in pmwin.h. It is defined for AIX Motif in ipmrc2X.
You don't have to create a new IHelpWindow object for each secondary
frame window you create. However if you don't, the following will occur:
1. When closing the secondary window, the help window doesn't close
2. When closing the help window, focus returns to the owner of the
secondary window. Nevertheless, these situations can be overcome by
using IHelpWindow::setAssociateWindow() for the current window that
has focus.
3. In order to have each notebook page show help when the Help button
is pressed, the notebook page must know about the frame window's
help window object so that it can call help.show(...). The static
function IHelpWindow::helpWindow() returns this object.
Example:
helpWin = IHelpWindow::helpWindow( this );
if ( helpWin )
helpWin->show( IResourceId( ID_xxx ) );
ΓòÉΓòÉΓòÉ 3.6. Toolbar ΓòÉΓòÉΓòÉ
There are several things we learned about toolbars and toolbar buttons in
coding Lancelot. Here are some of the items we learned.
If the toolbar appears in the header definition (.HPP) before the client,
the toolbar will take the focus.
Toolbar buttons by default have a standard size. But some words will not
fit inside the space provided. Therefore, we allowed each button to size
itself based on it's needs.
Since there doesn't exist a standard toolbar button bitmap for some of
Lancelot's functions, we created our own bitmaps. These bitmaps must be
20x17 in order to match height and width of the predefined library
toolbar button bitmaps.
ΓòÉΓòÉΓòÉ 3.7. 2D Graphics ΓòÉΓòÉΓòÉ
There are several things we learned about drawing with 2D graphics in coding
Lancelot. Here are some of the items we learned.
If you don't use the setClippingRect() function to explicity set the
boundardy of a graphic string (IGString), a graphic string may expand
into the area of another graphic string. Then the graphic string can be
seen through the other graphic string.