Developed by: John Walker, JSW Technology
Distributed by: Aonix
Copyright John Walker & JSW Technology 1999-2000.
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: 8 September 2000
The Fourth Release of Petzold Edition 4 Samples is available from this web site and is also distributed with Aonix ObjectAda OpenPack Version 7.2. This page completes that release with the samples from Chapter 20 of 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:
The samples can be downloaded using petzold420.zip (25 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 petzold420.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\ch20 objectada\winapi\samples\petzold\edition4\ch20\caller objectada\winapi\samples\petzold\edition4\ch20\callpub objectada\winapi\samples\petzold\edition4\ch20\imalloc objectada\winapi\samples\petzold\edition4\ch20\pubmem objectada\winapi\samples\petzold\edition4\ch20\regpubmemThis file (petzold420.htm) is included in:
objectada\winapi\samples\petzold\edition4
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.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.
Create a project using ObjectAda File New Project. Set Project name to IMalloc. Choose a directory for the project, for example:
c:\program files\aonix\objectada\winapi\samples\petzold\edition4\ch20\imalloc
Use Project Add Files to add the Ada sources:
petzold\edition4\extracon.ads petzold\edition4\helpers.ads petzold\edition4\helpers.adb petzold\edition4\ch20\imalloc\imalloc.adb petzold\edition4\ch20\imalloc\dmalloc.ads petzold\edition4\ch20\imalloc\dmalloc.adb
Use Project Settings Search to add the WinAPI library:
..\winapi\binding\lib
Use Project Settings Build to set the Main unit to imalloclib.
Use Project Settings Link to set the Application type to DLL and set Remove uncalled code.
Select Build Compile All to compile all files.
Use Build imalloclib.dll to generate IMallocLib.dll and IMallocLib.lib.
By default that will build an application with debug options. Use Project Target Win32(Intel)Release to build without debug options.
The package DMalloc implements the class DAlloc and the exported function CreateAllocator from IMALLOC.CPP. Note that only the function CreateAllocator is exported from the DLL.
The interface functions are accessed through the VFT of an object created by CreateAllocator using the interface package IMalloc which forms part of the WinAPI bindings (see the implementation of the client Caller). The specification of the IMalloc interface requires that the calling convention for these functions is stdcall.
The main program, IMallocLib, takes the name of the DLL and must with the package DMalloc, which implements the DLL. The C++ name, IMalloc, cannot be used in Ada because that already refers to an Ada package referenced by the application.
IMallocLib.dll can be tested by copying it to a directory containing caller.exe and invoking caller.exe. If caller.exe is the Ada version then imalloclib.dll can be used directly. If using caller.exe from the Petzold CD then imalloclib.dll should be renamed imalloc.dll since that is what is expected. Petzold describes alternative directories and the search path used to find DLLs.
Create a project using ObjectAda File New Project. Set Project name to Caller. Choose a directory for the project, for example:
c:\program files\aonix\objectada\winapi\samples\petzold\edition4\ch20\caller
Use Project Add Files to add the Ada sources:
petzold\edition4\extracon.ads petzold\edition4\helpers.ads petzold\edition4\helpers.adb petzold\edition4\ch20\caller\caller.adb petzold\edition4\ch20\caller\dmalloc.ads petzold\edition4\ch20\caller\wndpack.ads petzold\edition4\ch20\caller\wndpack.adbUse Project Add Files to add the resource file:
petzold\edition4\ch20\caller\caller.resThe resource file can be rebuilt from its source files using the resource compiler provided with ObjectAda as described in Programming Windows 95 Edition 4.
Use Project Add Files to add the library imalloclib.lib generated by the project IMalloc (see above), for example:
petzold\edition4\ch20\imalloc\imalloc-Win32(Intel)-Debug\imalloclib.lib
Use Project Settings Search to add the WinAPI library:
..\winapi\binding\lib
Use Project Settings Build to set the Main unit to caller.
Use Project Settings Link to set the Application type to Windows and set Remove uncalled code.
Copy imalloclib.dll from the project IMalloc to the target directory for caller, for example:
from: petzold\edition4\ch20\imalloc\imalloc-Win32(Intel)-Debug to: petzold\edition4\ch20\caller\caller-Win32(Intel)-DebugPetzold describes alternative directories and the search path used to find DLLs.
Select Build Compile All to compile all files.
Use Build Build caller.exe to build the application and Build Execute caller.exe to run it.
By default that will build an application with debug options. Use Project Target Win32(Intel)Release to build without debug options.
Caller includes the package DMalloc, which imports the function CreateAllocator exported by package DMalloc in the project IMalloc. Unfortunately there seems to be no way of sharing the specification of DMalloc between the two projects because one needs to export the function and the other to import it.
Notice that WndPack.adb accesses the interfaces IUnknown, IMalloc and IMarshal using the interface class packages provided in the bindings. WinAPI Version 3.1 or later is required for these packages.
Caller.exe can be tested by copying it to a directory containing IMallocLib.dll and invoking caller.exe. If IMallocLib.dll is the Ada version then it can be used directly. If using IMalloc.dll from the Petzold CD then it should be renamed imalloclib.dll since that is what is expected. Petzold describes alternative directories and the search path used to find DLLs.
Create a project using ObjectAda File New Project. Set Project name to PubMem. Choose a directory for the project, for example:
c:\program files\aonix\objectada\winapi\samples\petzold\edition4\ch20\pubmem
Use Project Add Files to add the Ada sources:
petzold\edition4\extracon.ads petzold\edition4\helpers.ads petzold\edition4\helpers.adb petzold\edition4\ch20\imalloc\dmalloc.ads petzold\edition4\ch20\imalloc\dmalloc.adb petzold\edition4\ch20\pubmem\pubmem.adb petzold\edition4\ch20\pubmem\pubmeminterface.ads petzold\edition4\ch20\pubmem\compobj.ads petzold\edition4\ch20\pubmem\compobj.adb petzold\edition4\ch20\pubmem\dclassfactory.ads petzold\edition4\ch20\pubmem\dclassfactory.adb
Use Project Settings Search to add the WinAPI library:
..\winapi\binding\lib
Use Project Settings Build to set the Main unit to pubmem.
Use Project Settings Link to set the Application type to DLL and set Remove uncalled code.
Select Build Compile All to compile all files.
Use Build pubmem.dll to generate pubmem.dll and pubmem.lib.
By default that will build an application with debug options. Use Project Target Win32(Intel)Release to build without debug options.
PubMem uses the same implementation for DMalloc as project IMalloc. That is CreateAllocator and class DAlloc in PUBMEM.CPP.
The package DClassFactory implements the class DClassFactory in CLASSFAC.CPP.
The package CompObj implements the Component Object Registration from COMPOBJ.CPP.
The class ID from PUBMEM.H is declared in package PubMemInterface.
The main program, PubMem, takes the name of the DLL and must with the packages DMalloc, DClassFactory and CompObj.
The DLL exports the following functions:
CompObj.DllGetClassObject CompObj.DllCanUnloadNow DMalloc.CreateAllocator
DllGetClassObject and DllCanUnloadNow use the DLL_stdcall calling convention as required by OLE. CreateAllocator uses the DLL calling convention, which is equivalent to DLL_cdecl, as defined by DMalloc. The exported names can be verified using:
dumpbin /exports pubmem.dllDumpBin is included in objectada\bin.
Create a project using ObjectAda File New Project. Set Project name to RegPubMem. Choose a directory for the project, for example:
c:\program files\aonix\objectada\winapi\samples\petzold\edition4\ch20\regpubmem
Use Project Add Files to add the Ada sources:
petzold\edition4\helpers.ads petzold\edition4\helpers.adb petzold\edition4\ch20\regpubmem\regpubmem.adb
Use Project Settings Search to add the WinAPI library:
..\winapi\binding\lib
Use Project Settings Build to set the Main unit to regpubmem.
Use Project Settings Link to set the Application type to console and set Remove uncalled code.
Select Build Compile All to compile all files.
Use Build Build regpubmem.exe to build the application and Build Execute regpubmem.exe to run it.
By default that will build an application with debug options. Use Project Target Win32(Intel)Release to build without debug options.
RegPubMem uses the code in Figure 20-6 of Petzold Programming Windows 95 Edition 4 to register PUBMEM.DLL. RegPubMem.lpValue assumes the location:
c:\program files\aonix\objectada\winapi\samples\petzold\edition4\chap20\pubmem\pubmem-win32(intel)-debug\pubmem.dllThe declaration should be changed, if necessary, to match the actual location.
The key can be checked using the Registry Editor. Note that rerunning RegPubMem with a different value will not change the registry. The existing value should be deleted using the Registry Editor before rerunning RegPubMem.
Create a project using ObjectAda File New Project. Set Project name to CallPub. Choose a directory for the project, for example:
c:\program files\aonix\objectada\winapi\samples\petzold\edition4\ch20\callpub
Use Project Add Files to add the Ada sources:
petzold\edition4\extracon.ads petzold\edition4\helpers.ads petzold\edition4\helpers.adb petzold\edition4\ch20\pubmem\pubmeminterface.ads petzold\edition4\ch20\callpub\callpub.adb petzold\edition4\ch20\callpub\wndpack.ads petzold\edition4\ch20\callpub\wndpack.adbUse Project Add Files to add the resource file:
petzold\edition4\ch20\callpub\callpub.resThe resource file can be rebuilt from its source files using the resource compiler provided with ObjectAda as described in Programming Windows 95 Edition 4.
Use Project Settings Search to add the WinAPI library:
..\winapi\binding\lib
Use Project Settings Build to set the Main unit to callpub.
Use Project Settings Link to set the Application type to Windows and set Remove uncalled code.
Select Build Compile All to compile all files.
Use Build Build callpub.exe to build the application and Build Execute callpub.exe to run it. Note that pubmem.dll must be registered before executing callpub.exe. That can be done using RegPubMem as described in RegPubMem.
By default that will build an application with debug options. Use Project Target Win32(Intel)Release to build without debug options.