Once you have obtained the address of the target DLL function, you can call it from APP16
using the CallProcEx32W or CallProc32W function. You cannot create a prototype for CallProc32W unless you do one of the following:
CallProc32W
_1
for functions that use one parameter, CallProc32W_2
for functions that use two parameters, and so forth. When linking your application or DLL, use forwarders to map calls to these functions to CallProc32W. This is a limitation of the Pascal calling convention. For this reason, you may choose to use the CallProcEx32W function, which uses the C calling convention to support a variable number of arguments.
These examples call MyPrint
, passing two arguments, a string and a window handle. All parameters must be 32-bit values. Therefore, the string is declared using a FAR pointer, as shown here:
char FAR *TestString = "Hello there";
You must convert the 16-bit window handle to a 32-bit window handle using the WOWHandle32 function, as shown here:
// Convert the window handle.
DWORD hWnd32;
hWnd32 = WOWHandle32(hWnd, WOW_TYPE_HWND);
This first example uses CallProcEx32W.
// Call the MyPrint routine in the Win32-based DLL
CallProcEx32W( 2 | CPEX_DEST_STDCALL,
2,
hProc,
(DWORD) TestString,
hWnd32);
This next example uses CallProc32W:
// Call the MyPrint routine in the Win32-based DLL
CallProc32W( (DWORD) TestString,
hWnd32,
hProc,
2,
2 | CPEX_DEST_STDCALL);
A mask of 2 (0x10) is given because we want to pass TestString
by reference and hProc
by value. The system translates the pointer for us.
If you are isolating your thunking code into DLL16
, put the call to CallProc32W or CallProcEx32W in the MyPrint
function of the DLL16
code.