Open Class Library (OCL) FAQ: Difference between revisions
Line 250: | Line 250: | ||
=OCL - Miscellaneous= | =OCL - Miscellaneous= | ||
==Application dies when starting== | |||
If your application compiles and links without problems, but it then dies during startup (you may or may not see the frame window start to come up) then check for the following common mistakes: | |||
* is more than one resource using the same number in your .RC or .DLG file? | |||
* are you trying to allocate/create a resouce in your .CPP file -- say an IPushButton -- when in reality it has been defined as something else in your .RC or .DLG file? | |||
* Bill Law (law@netscape.com) also says: The most common occurrence is that your app is throwing an (uncaught) exception during construction of the first (frame) window. This terminates silently, unless you take steps to capture the exception information. To do that, follow the instructions provided in the on-line VACPP FAQ (in the section "Coding With User Interface Classes"->"Exceptions"->"Why Does My Program Just Exit"). | |||
<code>[Editor's note: the VACPP FAQ is D:\IBMCPP\HELP\CPPFAQ.INF]</code> | |||
* did you specify the type of application when linking? If the application is compiled with the default value of <code>/pmtype:vio</code> then your window will not come up. Make certain you use <code>/pmtype:pm</code> from the linker, or <code>/B" /pmtype:pm"</code> when linking directly from the compiler. | |||
==Application-modal windows== | ==Application-modal windows== | ||
To create an application modal dialog window, the parent and the owner of the window being created must be different. The parent should be the desktop window handle, while the owner should be the calling dialog window's handle. For example: | |||
IFrameWindow *anotherDlg = | |||
new IFrameWindow( MY_RES_ID, /* resource id of new window */ | |||
desktopWindow(), /* parent window handle */ | |||
this ); /* owner window handle */ | |||
anotherDlg->showModally(); | |||
==System-modal windows== | ==System-modal windows== | ||
(Nothing here yet...feel free to submit something) | |||
==How to convert a native PM item to OCL== | ==How to convert a native PM item to OCL== | ||
Most native PM windows have an equivalent in OCL, and an item that already exists on a window can at any time be "converted" to OCL. This is advantageous for example if some of the functionality you need has already been implemented using OCL. For example: | |||
> Can a pointer to a 'low-level' listbox be converted into a pointer to an | |||
> Open Class listbox? | |||
[[Dave Briccetti]] says: | |||
Most of the OC UI controls have a constructor that takes the HWND of an | |||
existing control. In this case, the constructor looks like | |||
IListBox (const IWindowHandle &) | |||
IWindowHandle is an "alias" for HWND. | |||
[[Bill Law]] (law@netscape.com) also adds the following: | |||
Perhaps you should add that if an OCL window already exists for a given HWND, then constructing another one from its HWND will result in an exception being thrown. Generally, if there is a chance that an existing OCL window exists (or you know that one does and you just want to locate it), then you can use IWindow::fromHandle to get the existing IWindow (or derived-class) object. If that returns 0, then you can safely construct another IWindow (or derived-class) object. | |||
==How to create a thread== | ==How to create a thread== | ||
==How to assign an icon to a window== | ==How to assign an icon to a window== |
Revision as of 18:21, 29 November 2012
General Information
History of the Open Class Library FAQ
The revision history is as follows:
Version | Comment | Author | Date |
0.1 | initial write-up in OS/2's IPF (.INF) format | SC | 1997June20-21 |
0.1a | added table of files at Hobbes | SC | 1997June24 |
0.1b | converted the FAQ to HTML format | SC | 1997June28 |
0.1d | Added animation sample Added LNK2029 information Updated fixpak information Created "Errors in IBM's include files" |
SC | 1997Sept05 |
0.1e | Changed e-mail address Added POV_Launch to the Hobbes index Added custom-draw container information |
SC | 1997Nov02 |
How to obtain a copy of the FAQ
To obtain a HTML copy of the FAQ for local installation, download the file ftp://hobbes.nmsu.edu/pub/os2/dev/cplusplus/ocl_faq.zip.
Unzip this file in it's own directory (if using PKUNZIP, remember to use the /D option to create the subdirectories) and use your favorite web browser to access the files locally.
Where to obtain additional information
The on-line reference for OCL is located in your VisualAge folder, under the VisualAge C++ Information
folder. The reference .INF file should be titled Open Class Library Reference
(D:\IBMCPP\HELP\CLREF.INF
) while a second .INF user's guide is called Open Class Library User's Guide
(D:\IBMCPP\HELP\CPPCLSUG.INF
).
The first book, Open Class Library Reference
has all of the documented methods, objects, and necessary include files. The easiest way to find what you need is probably to click on Classes By Name
, normally the second option from the top (may depend on the version of the documentation).
Note that one of the most useful .INF books which IBM ships with VisualAge can easily be overlooked; in the VisualAge C++ Information
folder is a book called VisualAge C++ Frequently Asked Questions
which deals with quite a few OCL topics.
Additional information on programming using OCL can be obtained from a variety of sources. There is an increase in books published (some of which by IBM) which deal with OCL, as well as numerous sources on the Internet.
For more information, consult:
D:\IBMCPP\SAMPLES\IOC\*
- ocl*.zip ([hobbes_index.html index of samples])
- ftp://service.boulder.ibm.com/ps/products/visualagecpp/tools (IBM VB and OCL sample code)
- http://??? (Chinese version of the OCL-FAQ)
- http://www.davebsoft.com/Programming/tips (Dave Briccetti's OS/2 Warp Programming Tips and Samples)
- news://comp.os.os2.programmer.oop
- news://productnews.taligent.com/taligent.products.openclass (Taligent's OCL News Server)
Books which deal with OCL are:
- OS/2 Class Library
- Power GUI programming with C/Set++
- Written by Leon, Law, Love Tsuji & Olson
Published by John Wiley & Sons
ISBN 0-471-13117-2
(Obsolete and replaced by the following book) - Power GUI Programming with VisualAge C++
- Written by Law, Love, Olson & Tsuji
Published by John Wiley & Sons
ISBN 0-471-16482-8
(recommended by Mark Anderson, os2team@romeop03.fishkill.ibm.com)
Index of samples on Hobbes
tarting mid-June, 1997, I have begun to upload to ftp://hobbes.nmsu.edu/pub/os2/dev/cplusplus
a series of Open Class Library samples that I have written. The following table is the index of these samples.
Filename | Description | Classes Used |
---|---|---|
animation sample | IApplication, IColor, IDrawingCanvas, IEvent, IFrameWindow, IGBitmap, IGList, IRectangle, ITimer | |
details view container sample | IApplication, IContainerColumn, IContainerControl, IContainerObject, IFrameWindow, IString | |
thread and timer sample (minimized icon fix explained) | IApplication, ICommandEvent, ICommandHandler, IFrameWindow, IListBox, IPushButton, IString, ISystemMenu, IThread, IThreadFn, ITimer | |
animation sample #2 | IApplication, ICommandEvent, ICommandHandler, IColor, IControlEvent, IDrawingCanvas, IFrameWindow, IFrameEvent, IFrameHandler, IGBitmap, IGList, IGraphicContext, IMouseClickEvent, IMouseHandler, IPopUpMenu, ITimerMemberFn0 | |
custom drawing in a details-view container | IApplication, ICnrDrawHandler, IContainerColumn, IContainerControl, IContainerObject, IFrameWindow | |
POV front-end | Some of almost all classes available, including threads, canvases, icons, bitmaps, standard controls, profiles and exceptions. |
- Note
- See also #Where to Obtain Additional Information
OCL - Compiling
How to Compile
If you wish to correctly compile your OCL application, then the following should be used:
- if you are using the project templates and WorkFrame that come with Visual Age, then
- click on
Tools
- make certain that
View
is set toActions
- expand the
Compile
subtree - right-mouse-click on
C++ Compiler
- select
File Options
- select the
Object
tab - select the
Multithread
option forLibrary selection
(this sets the /Gm+ flag) - click on
OK
- close the tools setup
- regenerate the makefile and recompile
- click on
- if you are compiling from the command-line, or using your own makefiles, then
- use the command
icc.exe /Gm+ /C <other optional compiler flags> myfile.cpp
- use the command
- Note
- See also #/Gm+, #How to Link, #Static Linking and #Dynamic Linking
Required compiler flag
There is one flag that absolutely must be specified when compiling source code which uses OCL calls. This flag is described as follows in the on-line help:
/Gm+ Link with multithread runtime libraries.
The default for ICC is to use /Gm- (no support for the multithreaded libraries) so the /Gm+ flag must be specified. Typical compiler behavior when this flag is not specified is:
D:\IBMCPP\INCLUDE\ibase.hpp(226:3) : error EDC3086: Error: Use of IBM Open Class Library requires the /Gm+ compiler option. D:\IBMCPP\INCLUDE\ibase.hpp(227:3) : error EDC3086: Check the makefile (or its profile) for a missing /Gm+ option.
Note: See also #How to Compile and #Error EDC3086
Errors in IBM's include files
If your source code has the extension .c and you are including some OCL #includes, then the compiler may generate many errors which seem to come from the IBMCPP include files. These errors are generated because the compiler assumes that .c files only contain C code, not C++, and the OCL include files require the compiler to be in the C++ mode.
To get around this problem, use the compiler flag /Tdp to tell the VAC++ to treat all files as C++ files.
Some of the errors you may be seeing include the following:
imsgtext.hpp(24:1) : error EDC0166: Definition of function class requires parentheses. imsgtext.hpp(24:7) : error EDC0275: Unexpected text IMessageText encountered. imsgtext.hpp(27:19) : error EDC0046: Syntax error. imsgtext.hpp(28:33) : error EDC0045: Undeclared identifier messageFileName. imsgtext.hpp(29:33) : error EDC0045: Undeclared identifier textInsert1.
- Note
- See also #How to Compile
OCL - Linking
How to link
The recommended method of linking when some or all of the object files have references to OCL function calls is to use ICC, and not LINK386, ILINK, etc.
To link an object file (.OBJ) which makes use of OCL, the following should be used:
- if you are using the project templates and WorkFrame that come with VisualAge C++, then
- click on
Tools
- make certain that
View
is set toActions
- right-mouse-click on
Link
- click on
Add
- make certain that:
- general.class ==
Link
- general.name ==
Link (OCL)
- general.program ==
ICC.EXE
- general.session ==
MONITOR
- general.action applies to
FILE
, notPROJECT
- types.source ==
LinkerIn
- types.target ==
LinkerOut
- support.name ==
CPPICL30
- support.entrypoint ==
LINK
- click on
OK
- general.class ==
- close the tools setup
- regenerate the makefile to use the new link method, recompile and link
- click on
- if you are linking from the command-line, or using your own makefiles, then
- use the command
icc.exe <other optional compiler flags> /B" /pmtype:pm" myfile.obj
- use the command
- Note
- See also #How to Compile, #Static Linking and #Dynamic Linking
Static linking
Static linking will combine the IBM Open Class Library files with your object files to create a stand-alone application. This means that you are not required to have a copy of the X:\IBMCPP\DLL\DDE4*.DLL
files on your system in order to run the application.
The side effect of using this will be that your application may appear to be quite enormous in size.
To use 'static linking' you must specify the /Gd-
(this is the default) option when compiling your .CPP files. You can change this setting by one of the following methods:
- if you are using the project templates and WorkFrame that come with VisualAge, then
- click on
Tools
- make certain that
View
is set toActions
- expand the
Compile
subtree - right-mouse-click on
C++ Compiler
- select
File Options
- select the
Object
tab - select the
Static
option forLibrary linkage
- click on
OK
- close the tools setup
- regenerate the makefile and recompile
- click on
- if you are compiling from the command-line, or using your own makefiles, then
- make certain that the
/Gd-
option is specified
- make certain that the
- Note
- See also [dynamic_linking.html Dynamic Linking] and [how_to_link.html How to Link]
- Note
- Need info on rights, etc...are you allowed to distribute an application that was statically linked? Isn't there something in the docs? I haven't had the time to look it up yet -- if someone has references handy, please let me know.
Dynamic linking
Dynamic linking will setup your application to call the necessary OCL functions dynamically using DLLs. This assumes that the required DLL files are already referenced somewhere in LIBPATH before the application will run.
This is much faster to link, and the resulting application will be much smaller than using static linking. Of course, if the IBM VisualAge DLLs are not on the system which will be using this application, then it will fail to run. A typical application nearing 800Kb when linked statically may barely surpass 40Kb when linked dynamically.
To use 'dynamic linking' you must specify the /Gd+
(this is not the default) option when compiling your .CPP files. You can change this setting by one of the following methods:
- if you are using the project templates and WorkFrame that come with Visual Age, then
- click on
Tools
- make certain that
View
is set toActions
- expand the
Compile
subtree - right-mouse-click on
C++ Compiler
- select
File Options
- select the
Object
tab - select the
Dynamic
option forLibrary linkage
- click on
OK
- close the tools setup
- regenerate the makefile and recompile
- click on
- if you are compiling from the command-line, or using your own makefiles, then
- make certain that the /Gd+ option is specified.
- Note
- See also [static_linking.html Static Linking] and [how_to_link.html How to Link]
- Note
- Need info on rights, etc...are you allowed to distribute the DLLs with an application that was dynamically linked? Isn't there something in the docs? I haven't had the time to look it up yet -- if someone has references handy, please let me know.
OCL - Miscellaneous
Application dies when starting
If your application compiles and links without problems, but it then dies during startup (you may or may not see the frame window start to come up) then check for the following common mistakes:
- is more than one resource using the same number in your .RC or .DLG file?
- are you trying to allocate/create a resouce in your .CPP file -- say an IPushButton -- when in reality it has been defined as something else in your .RC or .DLG file?
- Bill Law (law@netscape.com) also says: The most common occurrence is that your app is throwing an (uncaught) exception during construction of the first (frame) window. This terminates silently, unless you take steps to capture the exception information. To do that, follow the instructions provided in the on-line VACPP FAQ (in the section "Coding With User Interface Classes"->"Exceptions"->"Why Does My Program Just Exit").
[Editor's note: the VACPP FAQ is D:\IBMCPP\HELP\CPPFAQ.INF]
- did you specify the type of application when linking? If the application is compiled with the default value of
/pmtype:vio
then your window will not come up. Make certain you use/pmtype:pm
from the linker, or/B" /pmtype:pm"
when linking directly from the compiler.
Application-modal windows
To create an application modal dialog window, the parent and the owner of the window being created must be different. The parent should be the desktop window handle, while the owner should be the calling dialog window's handle. For example:
IFrameWindow *anotherDlg = new IFrameWindow( MY_RES_ID, /* resource id of new window */ desktopWindow(), /* parent window handle */ this ); /* owner window handle */ anotherDlg->showModally();
System-modal windows
(Nothing here yet...feel free to submit something)
How to convert a native PM item to OCL
Most native PM windows have an equivalent in OCL, and an item that already exists on a window can at any time be "converted" to OCL. This is advantageous for example if some of the functionality you need has already been implemented using OCL. For example:
> Can a pointer to a 'low-level' listbox be converted into a pointer to an > Open Class listbox?
Dave Briccetti says:
Most of the OC UI controls have a constructor that takes the HWND of an existing control. In this case, the constructor looks like
IListBox (const IWindowHandle &) IWindowHandle is an "alias" for HWND.
Bill Law (law@netscape.com) also adds the following:
Perhaps you should add that if an OCL window already exists for a given HWND, then constructing another one from its HWND will result in an exception being thrown. Generally, if there is a chance that an existing OCL window exists (or you know that one does and you just want to locate it), then you can use IWindow::fromHandle to get the existing IWindow (or derived-class) object. If that returns 0, then you can safely construct another IWindow (or derived-class) object.
How to create a thread
How to assign an icon to a window
How to prevent the minimized icon from being overwritten
How to print
Valuesets (WC_VALUESET)
Custom-drawing in a container
OCL - Errors
Error EDC3086
Error LNK2029
Error EDC0166, EDC0275, EDC0045 and EDC0046
OCL - Fixpacks and CSDs
Contributors
This document is (will be?!) the result of input from many sources. These include the following people who have been kind enough to submit hints, tips, examples, and other contributions:
- Stéphane Charette
- Charlie Choc, cchoc@mindspring.com
- Mark Anderson, os2team@romeop03.fishkill.ibm.com
- Dave Briccetti
- Bill Law, law@netscape.com
- Tsung-Hsun Yang, u7924811@cc.nctu.edu.tw