Stuff
OS/400 Edition
Volume 1, Number 17 -- September 26, 2002

Introduction to Win32 API Programming with VARPG


by Shannon O'Donnell

[The code for this article is available for download.]

display

Visual Basic and Visual C++ programmers have known for years that to get the most functionality out of their applications, sometimes they had to dip down into the bare metal and access the Microsoft Windows APIs that make up the core operating system. As you develop more and more applications with VisualAge for RPG, you may also discover that there are certain features that you need that can only be obtained by going to the metal.

The Win32 API

Everything that happens in any application that runs under Microsoft Windows (in any version), including Windows itself, ultimately uses one or more Windows-32 application programming interfaces, or APIs, to perform its function. The Win32 APIs are a group of thousands of functions that allow your application total access to every aspect of the Windows environment. Win32 API functions are typically grouped together into larger objects known as Dynamic Link Libraries, or DLLs. A DLL file, in this context, is a compiled binary object that contains one or more Win32 API functions. Your VARPG application can link to the various Win32 DLL files to gain access to those lower-level APIs.

What Can You Do with Win32?

The following is a very short list of just some of the functionality you can achieve by accessing the Win32 APIs:

  • Free-form drawing with different shaped and sized "pens" and custom colors on a window
  • Creating custom dialog panels for unique user interaction
  • Creating unique cursors
  • Manipulating Windows icons
  • Determining which Windows are currently open
  • Executing external PC applications from your own applications
  • Creating unique buttons
  • Determining System Language ID
  • Retrieving system information, such as disk space or operating system
  • Creating uniquely shaped forms using Windows regions
  • Custom bitmap and image manipulation
  • Creating custom menus
  • Manipulating Windows Registry and *.INI files

And this doesn't even begin to scratch the surface! Most of the Win32 APIs are combined in just a few common DLL files that are included as part of the Windows operating system. The following descriptions are taken from Dan Appleman's Visual Basic Programmer's Guide to the Win32 API, by Dan Appleman:

  • KERNEL32.DLL--Low Level Operating Functions. Memory management, task management, resource handling and related operations.
  • USER32.DLL--Functions relating to Windows management. Messages, menus, cursors, carets, timers, communications, and most other nondisplay functions.
  • GDI32.DLL--The Graphics Device Interface library. This DLL contains functions related to device output. Most drawing, display context, metafile, coordinate, and font functions are in this DLL.
  • COMDLG32.DLL, LZ32.DLL, and VERSION.DLL--These DLLs provide additional capabilities, including support for common dialogs, file compression, and version control.

All of these APIs can be found in the Windows\System directory on Windows 95/98/ME PCs, and in the WINNT\SYSTEM32 directory on Windows NT/2000/XP systems.

A VARPG Example

I could write volumes about what the Win32 API is and how to understand and use it. But I'll save that for future articles. For now, let's take a look at how to use a Win32 API by looking at a simple example.

In this example, we'll create a simple VARPG application that displays a VARPG Window with canvas part and a push button part and allows the user to execute the notepad.exe application from within the running VARPG application. To run the notepad.exe application, the VARPG application will link to the SHELLEXECUTE API. This Win32 API is used to execute PC commands, such as running executable files or opening Windows Explorer.

To begin, create a new VARPG project and ad a Window with canvas part and a push button part. Name the Window with canvas part WIN1. Name the push button part PSBRUN and give it a label of NOTEPAD.EXE. Add a "press" event to the push button part.

Next, copy the source code into your VARPG source file.

The Code

Let's take a look at the important pieces of the source code in a bit more detail. The first thing you'll notice is that I've defined a prototype to the SHELLEXECUTE API. Notice that the name used here is SHELLEXECUTEA. Most Win32 APIs that you'll be using have this same naming convention.

Creating a prototype to the Win32 API in your VARPG application is critical to making the API work. If your prototype is incorrect, then nothing will work correctly. So the secret, then, is making sure that you use the correct API parameters and that your parameters are of the data type expected by the API.

So immediately you realize that you have two problems: How do you know what the correct parameters are for a particular API, and how do you know what data type from the Win32 API maps to what VARPG data type?

Actually, the solution to both answers is pretty simple. To determine the correct parameter list, go to Microsoft's Web site, at www.microsoft.com, search on that API name (or equivalent), and you'll be taken to the Microsoft Software Developers Network (MSDN) Web site, where you can find a complete description of the API in question, as well as its parameter list.

Once you've found that parameter list, you can find out what data types the API is expecting for each parameter. You'll notice right off that the data types the API is expecting look nothing like the data types you've come to know in RPG. For example, you may see data types such as DWORD, TCHAR, or LONG. What the heck is that, you ask? Where are the Packed, Zoned and Character data types found in RPG? How do you know what to convert the API data type to? The solution to that is also pretty simple because I've given you table of the complete data type conversion. Simply map the API datatype to the VARPG equivalent within your VARPG prototype, and you're all set.

So let's see how this works. The parameter list for the SHELLEXECUTEA API is as follows:

  • ByVal hWnd As Long--Handle to the Window
  • ByVal lpOperation As String--Operation to perform
  • ByVal lpFile As String--File name or command to open/execute
  • ByVal lpParameters As String--Paramater(s) to file or command
  • ByVal lpDirectory As String--Full path of directory to file or command
  • ByVal nShowCmd As String--Specify how launched programs are displayed (full screen, normal, or minimized--0, 1, and 2 respectively)

The keyword ByVal indicates that you will be passing data to the API by value, rather than by reference. Passing data by value means that the API gets a "copy" of the data, so the data cannot be modified. "By reference" means that the API gets an address of where the data actually resides in memory, and that the API can then modify that data, should it so desire. You will almost always pass parameters "By Value" to Win32 APIs. To indicate that a parameter is to be passed "ByVal" in your VARPG prototype, add the keyword VALUE to the parameter definition.

The first thing we must do is define the API name, which is SHELLEXECUTEA in this example. Next, add a line to tell VARPG the name of the DLL file where that API can be found. In this case, the API is found in SHELL32.DLL. Finally, add a line to tell VARPG how to link to the DLL file. You'll almost always use the value *StdCall in the Linkage parameter.

OK. Using our conversion table, we discover that long data types are defined as "10 0" in VARPG. In addition, we see that the hWND, which is a Hungarian notation (see, there's no end to the education process when you program in Windows!) for a Windows "handle," which is defined as an unsigned integer. In VARPG, that means that you define the parameter using the U data type. The Windows handle is a special data type in Windows that allows your application to know what window or form the current operation is for. Actually, it's a bit more complex than that, but that definition will suffice for now.

The rest of the parameters are defined as STRING data types. And you can pass strings (VARPG alpha-numeric characters) to the API. However, notice that the Hungarian notation for each parameter in the API declaration is lp followed by the parameter name. This indicates to the programmer that this parameter can also be passed as a pointer data type. In general, if you can pass a pointer to a Win32 API, then do so. It will prevent problems that are hard to debug. Since the rest of the API parameters are defined as pointers, we can simply define the parameter in the APIs using an asterisk (*) in the VARPG data type field.

That's it. If you've entered your code like that in the code example, you've completed defining the API prototype. The next step is to define variables for each of the prototype parameters. That's the next section of the code, which begins with the variable named hWnd. Again, you'll need to ensure that the data type for the variables matches the data type in the prototype. Define one variable for each prototype parameter. In addition, to define a pointer variable, you'll need to define a single String variable of any length, and then a pointer variable with the address pointing to the String variable. See the code for an example of how this works.

Notice that the sample code initializes the lpOperation parameter to "open." This tells the SHELLEXECUTEA API to launch the default application associated with the file extension. For example, if the file extension is .exe, the Windows RUNDLL32.exe application will be automatically called to run the chosen application. If the extension of the file you want to open is .htm, the default Web browser defined for your system will open the file.

Our final variable is the command that we'll execute--in this case, the notepad.exe application. On my Windows 2000 PC, that executable is found in the C:\WINNT\ directory. It may be in a different directory on your PC.

Running the Application

When you compile and run the application, you'll see a screen similar to the one shown in Figure 1. When you click the Notepad.exe button, the press event for that button will be fired, which will then call the ShellCmd subroutine. In this subroutine, the window handle (variable hWnd) will be set to the current VARPG window with canvas named WIN1. The CommandString work variable will have a NULL terminator attached to it, and, finally, the ShellExecute API will be called, which will open the file/program named in the CommandString variable. If the call is successful, the variable ulRc will contain a zero. If it's not successful, ulRc will contain something else and you can take appropriate action.

Figure 1: Run the application

As you can see, when it comes time to use the Win32 API, things get pretty simple. But all the prep work that goes into finding, understanding, and defining the API can get very involved. Stick with it, and don't give up. By using the Win32 APIs, you can greatly extend the functionality of the VARPG tool and build professional and commercial-level applications.


Sponsored By
ASNA

Why Roto-Rooter Uses ASNA Visual RPG for Development:

Roto-Rooter knew that the time had come to replace their green-screen technician dispatch system. When they selected ASNA Visual RPG (AVR) as their development environment, they realized they would be able to use their existing RPG programming skills. They also found that they were able to program even faster than with traditional RPG. Their new AVR application includes capabilities not possible in the green-screen app, such as graphical representations of technician schedules, easy to access menus, and tabs that allow easy movement from screen to screen. These capabilities make their new application much easier for their users to learn and use than the old green-screen version. Since the application now features more information on the screen at one time, in a format that is easier to read, users are able to see and correct scheduling conflicts more quickly than so they can provide a higher level of customer service.

"AVR has saved us so much time while working on our first visual application. I would say that we are able to cut our programming time, just for subfiles, in half and we use subfiles in over 90% of the programs that we have created for this project. It's really nice to be able to move our employees from dumb terminals to PCs and get them using more useful and user friendly applications."
  —Tom Duebber, Roto-Rooter

ASNA Visual RPG (AVR) for Web, Windows and .NET Development

ASNA Visual RPG is a true Windows-hosted RPG compiler. When you select AVR as your programming environment, you are preserving your development team's development skills as well as your shop's long-time investment in RPG. Because AVR is RPG-based, learning curves are amazingly low, even for green-screen veterans who have never written Web or Windows applications before. Couple AVR's easy learning curve with AVR's great documentation and ASNA's superb training classes (offered at ASNA's San Antonio, Texas headquarters and at ASNA's European headquarters in the UK) and your team will be creating problem-solving applications faster than you ever thought possible—and orders of magnitude faster than any competing development tool.

Download your FREE copy of AVR today!

http://www.asna.com/downloads.asp


THIS ISSUE
SPONSORED BY:

ASNA
Magic Software
Aldon Computer Group
ASC
Profound Logic Software
WorksRight Software


BACK ISSUES

TABLE OF CONTENTS
Introduction to Win32 API Programming with VARPG

Accessing External Data Using DB2 UDB DataLinks

Qshell Functions

Sed, the Stream Editor

Back to Basics: Multiple Subfiles on One Screen

Create an Animated Chicken with VARPG


Editors
Shannon O'Donnell
Kevin Vandever

Managing Editor
Shannon Pastore

Contributing Editors:
Howard Arner
Joe Hertvik
Ted Holt
David Morris
Richard Shaler

Publisher and
Advertising Director:

Jenny Thomas

Contact the Editors
Do you have a gripe, inside dope or an opinion?
Email the editors:
editors@itjungle.com



Last Updated: 9/26/02
Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.