Developed by: John Walker, JSW Technology
Distributed by: Aonix
Copyright John Walker & JSW Technology 1999.
All Rights Reserved.
The information contained herein is subject to change without notice.
ObjectAda is a trademark of Aonix
Microsoft, Visual C++, Win32 and Windows NT are trademarks of Microsoft, Inc.
Last updated: 29 September 1999
This page will be used to post ongoing work on more samples for the benefit of existing and potential customers. These samples are derived from the examples in Programming Windows 95 Edition 4 by Charles Petzold and published by Microsoft Press.
Go back to Ada Binding to Win32 (WinAPI)
Go back to start of JSW Technology Home Page
These samples are intended to help Ada programmers who are using Petzold Programming Windows 95 Edition 4 to learn about Win32. The Ada code is kept as close to the C samples as possible. This is intended to assist with cross-referencing between Petzold and the Ada code. When developing real Ada applications it is expected that a stronger Ada flavour will be adopted, particularly for string handling.
This document makes reference to some Microsoft articles. You can obtain these articles by e-mail from mshelp@microsoft.com. Enter the Article ID number (Qnnnnnn) in the Subject line of your message.
These samples have been built as described using:
Edition 4 has been added to the directory tree to make provision for the development of samples derived from Petzold Programming Windows Fifth Edition.
The constants IDI_APPLICATION, IDC_ARROW and IDC_WAIT are converted to type WinAPI.LPCSTR in package ExtraConstants. In the first release of these samples the conversion was applied when the constants were used.
The samples can be downloaded using petzold4.zip (351 KB) into objectada\winapi.
The sources can be extracted directly into the samples directories set up by the product installation. For example, assuming that ObjectAda is installed in c:\program files\aonix\objectada then the files can be extracted as follows:
>c: >cd \"program files"\aonix\objectada\winapi >..\bin\unzip petzold4.zipNote that unzip.exe is supplied with ObjectAda in objectada\bin.
That should have installed the following samples directories:
objectada\winapi\samples\petzold\edition4 objectada\winapi\samples\petzold\edition4\ch2 objectada\winapi\samples\petzold\edition4\ch2\hellowin objectada\winapi\samples\petzold\edition4\ch3 objectada\winapi\samples\petzold\edition4\ch3\sysmets1 objectada\winapi\samples\petzold\edition4\ch3\sysmets2 objectada\winapi\samples\petzold\edition4\ch3\sysmets3 ... etcPrevious releases of Petzold Samples were installed in:
objectada\winapi\samples\petzoldThese samples can be deleted to avoid pollution and potential confusion.
This section provides a step by step guide to setting up a project for the sample HelloWin. Similar steps are required to set up projects for the other samples.
Create a project using ObjectAda File New Project. Set Project name to hellowin. Choose a directory for the project, for example:
C:\Program Files\Aonix\ObjectAda\WinAPI\Samples\petzold\edition4\HelloWin
Use Project Files to add the Ada sources described in Petzold Chapter 2. Note that petzold\edition4\extracon.ads and petzold\edition4\gnatcon.ads are alternates. Extracon.ads is required for ObjectAda, gnatcon.ads is required for GNAT.
Use Project Setting Search Add to add the WinAPI library:
..\winapi\binding\lib
Use Project Settings Build to set the Main unit to HelloWin.
Use Project Settings Link to set the Application type to Windows and set Remove uncalled code.
Select Project Compile All Files.
Use Project Build to build the application and Project Execute to run it.
By default that will build an application with debug options. Use Project Target Win32(Intel)Release to build without debug options.
Resource files (*.res) are included with the Ada sources where required. They should be included in Project Files. The resource files can be rebuilt from their source files using the resource compiler provided with ObjectAda as described in Programming Windows 95 Edition 4.
The following DLLs should be installed in order to run executables on Windows 95:
OpenGL.dll Glu32.dllNote that error messages relating to missing DLLs are displayed when running Windows applications directly but not when invoked using Project Execute in the ObjectAda IDE.
The WinAPI bindings are generated using the general purpose C++ to Ada Binding Technology. The package Helpers includes extensions to the bindings which have been found useful in the development of the Petzold samples. Helpers is included in the following source files:
petzold\edition4\helpers.ads petzold\edition4\helpers.adbHelpers includes the following functions which are bound to Ada runtime functions which return the arguments available to WinMain in C and C++ programs:
hInstance hPrevInstance lpCmdLine nCmdShowThe Character nul provides the null character used at the end of Win32 null terminated strings.
The function To_AddressOfChar returns a pointer, of type VC.AddressOfChar, to the first character of the string parameter. This is the correct type and value for Win32 strings of type char * in C and C++. Typically a null terminated Ada string can be passed to a Win32 function as follows:
Helpers.To_AddressOfChar ("An Ada string" & Helpers.nul)
The remainder of package Helpers includes implementations of some Win32
macros as Ada subprograms.
The package ExtraConstants includes additional constants to those generated by the C++ to Ada Binding Technology in WinAPIConstants. These constants have been found useful in the development of the Petzold samples. ExtraConstants is included in the source file:
petzold\edition4\extracon.adsThe following constants provide null values for some Win32 types:
Null_HINSTANCE Null_HWND Null_HMENUThe specification of these types changed between version 4.2 and 6.0 of Visual C++ causing an incompatibility when using GNAT 3.10p. The constants are provided to ease migration from 4.2 to 6.0 using GNAT.
The remainder of the package ExtraConstants includes some Win32 constants not included in WinAPIConstants.
The function wsprintfA, used in many of the samples, has variable arguments in C. It is used in Ada by copying the specification from WinAPI and adding the variable arguments required as shown in petzold\edition4\sysmets1\wndpack.adb (for example). The pragma Import has been modified so that it will work with GNAT 3.10p as well as ObjectAda.
The Link_Name used for some functions is incorrect in versions of WinAPI previous to 3.1 (see Release Note - Link Names). This affects the function strlen which is used in several places in the Petzold samples. The workaround described in Release Note - Link Names is used in the samples.
The Link_Name used for some functions is incorrect in versions of WinAPI previous to 3.2 (see Release Note - Optimisation). This affects the function toupper in sample HexCalc. The workaround described in Release Note - Optimisation is used.
In some cases, such as strupr and ltoa also used in HexCalc, the optimisation is valid.
The components of records will be aliased in a future release of WinAPI. In the meantime the sample OwnerDrw illustrates a workaround for the current release.
The sample HelloWin requires the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adb petzold\edition4\ch2\hellowin\hellowin.adb petzold\edition4\ch2\hellowin\wndproc.ads petzold\edition4\ch2\hellowin\wndproc.adbThe packages ExtraConstants and Helpers are described above.
HelloWin is the main subprogram. It reflects the C code described by Petzold. Note the use of Helpers to obtain the parameters to WinMain and for string handling. The exception handler has been added as an aid to debugging.
WndProc is the window procedure. Note that it must be exported with calling convention stdcall. This procedure is called by Windows through the pointer in the class structure registered by the main subprogram, HelloWin.
In this simple example the window procedure is implemented as a library subprogram. In more complex examples the window procedure may be encapsulated within a package.
The samples SysMets1, SysMets2 and SysMets3 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adb petzold\edition4\wndpack.ads petzold\edition4\sysmets.ads : package SystemMetricsand the source files from the relevant directory below:
petzold\edition4\ch3\sysmets1 petzold\edition4\ch3\sysmets2 petzold\edition4\ch3\sysmets3
The packages ExtraConstants and Helpers are described above.
The package SystemMetrics maps to the C header file sysmets.h. It is used by SysMets1, SysMets2 and SysMets3.
Note that WndProc assumes the array index runs from 0 and that NUMLINES is the length of the array sysmetrics.
The package WndPack is used to encapsulate the window procedure WndProc which uses static variables. The specification of WndPack is common to SysMets1, SysMets2 and SysMets3. However the implementations are different.
The function wsprintfA, used in the body of WndPack, has variable arguments in C. It is used in Ada by copying the specification from WinAPI and adding the variable arguments required as shown in the body of WndPack. The pragma Import has been modified so that it will work with GNAT 3.10p as well as ObjectAda.
The function strlen must be specified in WndPack to work around a bug in the versions of WinAPI previous to 3.1 (see Release Note - Link Names).
The implementation of WndProc is chosen to reflect the code described by Petzold. An "Ada" application might choose a different implementation, particularly for the creation of the strings for painting.
The samples in chapter 4 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adbMost of the samples, except Scramble, require:
petzold\edition4\ch4\wndpack.adsThe samples also require the source files from the relevant directory below:
petzold\edition4\ch4\bezier petzold\edition4\ch4\clover petzold\edition4\ch4\devcaps1 petzold\edition4\ch4\emf1 petzold\edition4\ch4\emf2 petzold\edition4\ch4\endjoin petzold\edition4\ch4\justify1 petzold\edition4\ch4\linedemo petzold\edition4\ch4\metafile petzold\edition4\ch4\randrect petzold\edition4\ch4\scramble petzold\edition4\ch4\sinewave petzold\edition4\ch4\whatsize
There is an unresolved problem in the sample Clover. The last turn (361) of the loop in the code for handling WM_PAINT produces an extra line on the horizontal radius of the right-hand leaf.
Note that Scramble does not use a window procedure.
Scramble seems to run as intended on Windows 95 but not on Windows NT. A comment to this effect has been added to the sample described by Petzold.
When initially translated from C a range error was raised on Text (EndIndex - 1) in procedure WndPack.Justify while eliminating trailing blanks when the window width was resized to a minimum. This problem was removed by adding the condition EndIndex > BeginIndex.
The C code seems to work because pointers are used instead of array indices.
The samples in chapter 5 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adb petzold\edition4\wndpack.adsSysMets also requires:
petzold\edition4\sysmets.adsas described in Petzold Chapter 3.
The samples also require the source files from the relevant directory below:
petzold\edition4\ch5\keylook petzold\edition4\ch5\sysmets petzold\edition4\ch5\typer
The samples in chapter 6 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adbMost of the samples, except Checker3, require:
petzold\edition4\wndpack.adsThe samples also require the source files from the relevant directory below:
petzold\edition4\ch6\blokout1 petzold\edition4\ch6\blokout2 petzold\edition4\ch6\checker1 petzold\edition4\ch6\checker2 petzold\edition4\ch6\checker3 petzold\edition4\ch6\connect
The samples in chapter 7 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adbThe samples also require the source files from the relevant directory below:
petzold\edition4\ch7\anaclock petzold\edition4\ch7\beeper1 petzold\edition4\ch7\beeper2 petzold\edition4\ch7\bounce petzold\edition4\ch7\digclock
The samples in chapter 8 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adbThe samples BtnLook, Environ and Head also require:
petzold\edition4\wndpack.adsThe samples also require the source files from the relevant directory below:
petzold\edition4\ch8\btnlook petzold\edition4\ch8\colors1 petzold\edition4\ch8\environ petzold\edition4\ch8\head petzold\edition4\ch8\ownerdrw petzold\edition4\ch8\poppad1
The processing of WM_DRAWITEM in WndPack.adb requires Unchecked_Access to the record component rcItem. The components of records will be aliased in a future release of WinAPI. In the meantime this sample illustrates a workaround for the current release.
The samples in chapter 9 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adband the source and resource (.res) files from the relevant directory below:
petzold\edition4\ch9\poepoem petzold\edition4\ch9\resourc1 petzold\edition4\ch9\resourc2The resource files can be rebuilt from their source files using the resource compiler provided with ObjectAda as described in Programming Windows 95 Edition 4.
There is a problem in the sample PoePoem. An access error occurs when attempting to write to the string resource. This is resolved by using the character count in DrawText instead of a terminating null, avoiding the need to write to the string resource. See the comments in WndPack.adb.
The samples in chapter 10 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adband the source and resource (.res) files from the relevant directory below:
petzold\edition4\ch10\menudemo petzold\edition4\ch10\popmenu petzold\edition4\ch10\poormenu petzold\edition4\ch10\nopopups petzold\edition4\ch10\grafmenu petzold\edition4\ch10\poppad2NoPopups also requires:
petzold\edition4\wndpack.adsThe resource files can be rebuilt from their source files using the resource compiler provided with ObjectAda as described in Programming Windows 95 Edition 4.
The samples in chapter 11 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adband the source and resource (.res) files from the relevant directory below:
petzold\edition4\ch11\about1 petzold\edition4\ch11\about2 petzold\edition4\ch11\about3 petzold\edition4\ch11\colors2 petzold\edition4\ch11\hexcalc petzold\edition4\ch11\poppad3 petzold\edition4\ch11\colors3About1 and HexCalc also require:
petzold\edition4\wndpack.adsThe resource files can be rebuilt from their source files using the resource compiler provided with ObjectAda as described in Programming Windows 95 Edition 4.
The workaround described in Release Note - Optimisation is used.
See also "Optimisation" on toupper et al
The samples in chapter 12 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adband the source and resource (.res) files from the relevant directory below:
petzold\edition4\ch12\gadgets petzold\edition4\ch12\propertyThe resource files can be rebuilt from their source files using the resource compiler provided with ObjectAda as described in Programming Windows 95 Edition 4.
There are no samples in Chapter 13.
The samples in chapter 14 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adband the source files from the relevant directory below:
petzold\edition4\ch14\rndrctmt petzold\edition4\ch14\multi1 petzold\edition4\ch14\multi2 petzold\edition4\ch14\bigjob1 petzold\edition4\ch14\bigjob2Multi1, Multi2, BigJob1 and BigJob2 also require:
petzold\edition4\wndpack.ads
The samples in chapter 15 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adband the source and resource (.res) files from the relevant directory below:
petzold\edition4\ch15\devcaps2 petzold\edition4\ch15\formfeed petzold\edition4\ch15\print1 petzold\edition4\ch15\print2 petzold\edition4\ch15\print3 petzold\edition4\ch15\poppad petzold\edition4\ch15\print4Print1, Print2, Print3 and Print4 also require:
petzold\edition4\ch15\print.ads petzold\edition4\ch15\print.adbThe resource files can be rebuilt from their source files using the resource compiler provided with ObjectAda as described in Programming Windows 95 Edition 4.
The implementation of GetPrinterDC in Petzold Edition 4 does not work for Windows NT. The sample FormFeed is implemented using the function PrintDlg as used by Petzold in PopPad. The samples Print1-4 use the implementation in Petzold Edition 5.
Windows NT doesn't print a blank page. The Petzold sample has been modified to print a line of text.
The Petzold sample has been modified to print two pages to increase the chance of using Cancel before printing has got too far.
The Petzold and Ada samples failed to print on test systems under Windows NT. ExtEscape returns 0 from the NEXTBAND query.
The sample in chapter 16 requires the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adb petzold\edition4\wndpack.ads petzold\edition4\ch16\clipview.adb petzold\edition4\ch16\wndpack.adb
The samples in chapter 17 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adband the source files from the relevant directory below:
petzold\edition4\ch17\ddepop1 petzold\edition4\ch17\showpop1 petzold\edition4\ch17\ddepop2 petzold\edition4\ch17\showpop2DDEPop1 and DDEPop2 also require:
petzold\edition4\ch17\ddepop.ads petzold\edition4\ch17\ddepop.adbShowPop1 and ShowPop2 also require:
petzold\edition4\ch17\showpop.ads
The samples, DDEPop1 and ShowPop1, include the corrections described in Microsoft Article Q165887 PRB: Petzold DDE Sample Applications Contain Errors. The article can be obtained as described in Microsoft Articles.
The samples in chapter 18 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adband the source and resource (.res) files from the directory:
petzold\edition4\ch18\mdidemo
The resource files can be rebuilt from their source files using the resource compiler provided with ObjectAda as described in Programming Windows 95 Edition 4.
The samples in chapter 19 require the following source files:
petzold\edition4\extracon.ads : package ExtraConstants for ObjectAda petzold\edition4\gnatcon.ads : package ExtraConstants for GNAT petzold\edition4\helpers.ads petzold\edition4\helpers.adband the source and resource (.res) files from the relevant directory below:
petzold\edition4\ch19\edrlib petzold\edition4\ch19\edrtest petzold\edition4\ch19\edrdyn petzold\edition4\ch19\strlib petzold\edition4\ch19\strprog petzold\edition4\ch19\bitlib petzold\edition4\ch19\showbit
The project, EdrLib, builds the DLL, EdrLib.dll. Set Project Settings Link Application type to DLL. The main program takes the name of the DLL and must with the package Edr, which implements the DLL. Project Build generates EdrLib.dll and EdrLib.lib. EdrLib.dll can be copied into the same directories as EdrTest.exe and EdrDyn.exe, which are generated by projects EdrTest and EdrDyn. Petzold describes alternative directories and the search path used to find DLLs.
The project, EdrTest, builds the executable, EdrTest.exe. Set Project Settings Link Application type to Windows in the usual way. Project Files must include EdrLib.lib which is generated by project EdrLib. Also the DLL generated by EdrLib must be in one of the directories in the DLL search path as described by Petzold.
EdrTest includes the package Edr, which imports the subprograms exported by package Edr in the project EdrLib.
The sample EdrDyn is additional to the Petzold samples. It shows how to modify EdrTest to load the DLL as described in Petzold Dynamic Linking without Imports using LoadLibrary, GetProcAddress and FreeLibrary.
The project, EdrDyn, builds the executable, EdrDyn.exe. Set Project Settings Link Application type to Windows in the usual way. The DLL generated by EdrLib must be in one of the directories in the DLL search path as described by Petzold.
EdrDyn includes the package Edr. Edr does not import the function EdrCenterText but specifies a corresponding access function which is used in package WndProc to call EdrCenterText using the address returned by GetProcAddress.
The project, StrLib, builds the DLL, StrLib.dll. Set Project Settings Link Application type to DLL. The main program takes the name of the DLL and must with the package Str, which implements the DLL. Project Build generates StrLib.dll and StrLib.lib. StrLib.dll can be copied into the same directory as StrProg.exe, which is generated by project StrProg. Petzold describes alternative directories and the search path used to find DLLs.
Petzold uses a shared data segment for pszStrings and iTotal. ObjectAda does not support shared data segments and so a named memory mapped file is used instead.
The implementation in Petzold Edition 4 assumes that the pointers to the file views are common across multiple processes but it is not clear that this is a safe assumption so only one memory mapped file is used and that contains the complete string array as implemented in Petzold Edition 5.
Rather than replace the default DllMain produced by ObjectAda, and to keep all the implementation of the DLL local to package STR, the DLL_PROCESS_ATTACH code is implemented in the body of STR and the DLL_PROCESS_DETACH code is implemented in the exported procedure Detach. Detach is called by the client StrProg as part of its WM_DESTROY processing.
The project, StrProg, builds the executable, StrProg.exe. Set Project Settings Link Application type to Windows in the usual way. Project Files must include StrLib.lib which is generated by project StrLib. Also the DLL generated by StrLib must be in one of the directories in the DLL search path as described by Petzold.
StrProg includes the package Str, which imports the subprograms exported by package Str in the project StrLib.
The resource file, StrProg.res, can be rebuilt using the resource compiler provided with ObjectAda as described in Programming Windows 95 Edition 4.
The project, BitLib, builds the DLL, BitLib.dll. Set Project Settings Link Application type to DLL. Project Files include just BitLib.adb and BitLib.res. Project Build generates BitLib.dll but there is no corresponding BitLib.lib. BitLib.dll can be copied into the same directory as ShowBit.exe, which is generated by project ShowBit. Petzold describes alternative directories and the search path used to find DLLs.
The resource file, BitLib.res, can be rebuilt using the resource compiler provided with ObjectAda as described in Programming Windows 95 Edition 4.
The project, ShowBit, builds the executable, ShowBit.exe. Set Project Settings Link Application type to Windows in the usual way. The DLL generated by project BitLib must be in one of the directories in the DLL search path as described by Petzold.
Samples derived from Petzold Chapter 20 are in development but have not been included in this release because they depend on the support for COM interfaces in Ada Binding to Win32 (WinAPI) Version 3.1.