Image of Navigational Map linked to Home / Contents / Search Alert: Building Win16 apps under Win32

by Ross Mack - GUI Computing
Image of Line Break

Warning, Will Robinson ! Warning ! My arms are flailing wildly !

Here are a few quick notes about building 16bit Applications under 32bit versions of Windows and some of the issues to be aware of. Also, some things to just avoid doing. Hopefully reading this will save some of you some time that unfortunately I spent trying to resolve impossible bugs or problems.

Building on NT, running under Win95.

It seems there is a bug somewhere, probably in NT4, that surfaces in the following scenario. You construct a VB3 application using DAO to retrieve data from a JET 2.0 database. Use the Microsoft Compatibility layer ( and a million other places) to allow VB3 to talk JET 2.0. I have also installed the Access 2.0 Service pack to upgrade JET to 2.5. All the code is quite plain, very standard data manipulation and retrieval. And initially everything seems to work fine. Now, compile the application and run it on a Win95 box. Much of the application will work fine. However, I have found that in this scenario the running application fails to retrieve some data. In fact in some cases there are large holes in the data retrieved. This appears to arise mostly where new recordsets are opened and closed while there are existing recordsets held open.

We discovered this error just prior to going live with this issue so have not discovered what exactly the problem is, but we’re working on it.

16bit APIs under Win95.

We have also discovered a minor problem compiling VB3 applications under Windows 95. In some rare cases when using 16bit APIs from VB3 you can encounter errors when that application is subsequently run under Win16. Essentially, this is what appears to happen. During the compilation process the compiler resolves any Declare statements for external functions and resolves them into a numeric reference using the export table of the library in question. This works fine in most cases as 16bit DLLs run under Win95 will return the same export tables as they are the same DLLs.

However, when calling Windows API calls, you are no longer making calls into the same DLLs as you would under Win16. Instead you are making calls that are resolved by Win95’s 16bit subsystem into 32bit APIs. Various thunking things happen and it all seems to work.

This also means that the reference information returned by the Win95 16bit subsystem can vary just slightly from what would be returned by Win16 itself. The result is that sometimes your 16bit APIs will fail when your app is run under Win16, but they will work fine under Win95. Fortunately, if you compile under Win16 your app will work fine under both Win16 and Win32.

Distributing VB4-16bit apps.

One of the major components of VB4 is OLE. It’s really a cornerstone of how VB4 works. It provides the mechanism to communicate with custom controls (OCXs) as well as with components like DAO and RDO (for VB4-32). However, when you run a VB4-16bit application under Win32 it will happily use the 32bit OLE architecture provided by Win95 or NT. Cool.

Under Win16, the same application will happily use the 16bit OLE2 DLLs and typelibs. The problem is when it comes time to distribute your 16bit application. If you have been constructing it under Win95 on NT you will probably be inclined to add your system’s OLE DLLs to the installation script so that it will have the OLE support it needs. Remembering that Win16 did not originally ship with OLE2, so you must ship it with your VB4 apps. Do not do this ! This will ship 32bit OLE which is fine if you install onto a Win32 box, but will kill OLE entirely if installed on a Win16 box. Messages to the tune of ‘This application requires a more recent version of windows’ will plague you. Of course this will also apply to VB3 apps that use OLE for whatever purpose.

What you need to do instead is keep a set of 16bit OLE DLLs aside that you can distribute with your application. As I use WISE ( to create all my installations I have a directory of such DLLs and a simple wise script that will install and register them. WISE allows me to include this script in other installation scripts, so I don’t have to rewrite it all the time.

You should also check the version of windows you are installing onto before your install script starts writing such files into system directories.

MAPI, thunk you very much.

Here is an interesting one, but along the same lines as my OLE discussion above. Under Win95 using Microsoft’s Messaging API (MAPI) works fine from 16bit applications. VB’s MAPI controls, VBX for VB3 or OCX for VB4 work seamlessly. Unfortunately, when it comes time to distribute your app you may be inclined to distribute the MAPI.DLL in your system directory. After all it is a 16bit DLL and should work fine uder Win16, right? Wrong. The MAPI.DLL that you will find in your Win95 system directory is actually simply a thunking DLL that takes 16bit MAPI calls and thunks them up to 32bit and them passes them on to MAPI32.DLL.

So, if you need to distribute a MAPI DLL, make sure that you grab the real 16bit DLL and install that on Win16 target machines. On Win32 target machines you should ensure that you do not install this DLL over any existing MAPI.DLL that does the 16 to 32bit thunking.


There are a number of issues involving 16bit ODBC under Win32 platforms and what you need to distribute and what you don’t. However, this has all been covered in Lisa Hooper's article ‘ODBC for Windows 95’. So I feel no need to go into it any further here.

Written by: Ross Mack
July '97

Image of Arrow linked to Previous Article Image of Arrow linked to Next Article
Image of Line Break