An IPF communication object can be structured in many ways. Its content depends on the function being implemented. Application-controlled windows typically simulate activity that might or might not require user interaction.
An example of a communication object is provided in the IPF sample program (available in the Toolkit), and is shown in the previous IPF-controlled window example. The program contains two procedures:
IPFMain registers a window class for the application-controlled window, creates an instance of the class, and registers it with IPF as a communication object.
IPFWinProc provides the animation in the application-controlled window. IPFWinProc is called by IPFMain procedure.
#define INCL_WIN
#define INCL_GPI
#define INCL_DOS
#define INCL_DOSMODULEMGR
#define LINT_ARGS
#define DINCL_32
#include <OS2.H>
#include "IPF.H"
#define COM_HWND 4 /* Used in WinSetWindowULong */
#define FRAMES 5 /* Number of frames in animation sequence */
#define BEEP_WARN_FREQ 60 /* Frequency of warning beep */
#define BEEP_WARN_DUR 100 /* Duration of warning beep */
USHORT IPFClassRegistered = 0; /* IPF class registered flag */
HWND hwndClient; /* Handle to the client window */
HWND hwndPrevious; /* Handle to the previous active */
/* object communication window */
HWND hwndLatest; /* Handle to the latest active */
/* object communication window */
MRESULT EXPENTRY IPFMain (PACVP pACVP, PCH Parameter);
MRESULT EXPENTRY IPFWinProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
VOID Error (PCH str);
MRESULT EXPENTRY IPFMain (PACVP pACVP, PCH Parameter)
{
HWND hwndParent; /* Handle of parent window in IPF */
HWND hwndFrame; /* Handle to the frame */
ULONG WinStyle; /* window style for creating frame */
ULONG CtrlData; /* control data for creating frame */
Parameter; /* Warning Level 3 Avoidance */
/** 1) Initialize **/
if (!IPFClassRegistered)
{
if (!WinRegisterClass (pACVP->hAB,
"CLASS_IPF",
(PFNWP) IPFWinProc,
CS_SYNCPAINT | CS_SIZEREDRAW | CS_MOVENOTIFY,
8))
{
DosBeep (BEEP_WARN_FREQ, BEEP_WARN_DUR);
exit (TRUE);
}
IPFClassRegistered = 1;
}
WinStyle = 0L;
CtrlData = 0L;
if (!(hwndFrame = WinCreateStdWindow (pACVP->hWndParent,
WinStyle,
&CtrlData,
"CLASS_IPF",
"IPF",
0L,
0L,
0L,
&hwndClient
)))
{
Error ("Cannot create window");
return (MRESULT) TRUE;
}
/** 2) Process **/
pACVP->hWndACVP = hwndFrame;
hwndParent = pACVP->hWndParent;
hwndPrevious = WinSendMsg (pACVP->hWndParent,
HM_SET_OBJCOM_WINDOW,
(MPARAM) hwndFrame,
NULL);
hwndLatest = WinSendMsg (pACVP->hWndParent,
HM_QUERY,
MPFROM2SHORT (NULL, HMQW_OBJCOM_WINDOW),
NULL);
if (hwndFrame != hwndLatest)
{
Error ("Cannot set object communication window");
return (MRESULT) TRUE;
}
/** 3) Finish **/
if (!WinSetWindowULong (hwndClient, COM_HWND, (ULONG) hwndPrevious))
{
Error ("Cannot save handle into reserved memory");
return (MRESULT) TRUE;
}
return (MRESULT) FALSE;
}
MRESULT EXPENTRY IPFWinProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
static HAB Hhab; /* anchor block handle */
static HBITMAP hbm [5]; /* array of bitmap handles */
static HPS hps; /* presentation space */
static POINTL ptl; /* pointl */
static HMODULE hModule; /* to get bitmaps from DLL resource */
static SHORT index; /* index to current bitmap to display */
static LONG cxClient,
cyClient; /* window size */
BOOL rValue=TRUE; /* FALSE if the message was acted */
/* upon successfully */
/** 1) Initialize **/
switch (msg)
{
case HM_UPDATE_OBJCOM_WINDOW_CHAIN:
hwndPrevious = (HWND) WinQueryWindowULong (hwnd, COM_HWND);
if (hwndPrevious == mp2)
{
hwndPrevious = mp1;
if (!WinSetWindowULong (hwndClient,
COM_HWND,
(ULONG) hwndPrevious))
{
Error ("Cannot save handle into reserved memory");
break;
}
}
else
{
if (hwndPrevious != NULL)
{
WinSendMsg (hwndPrevious,
HM_UPDATE_OBJCOM_WINDOW_CHAIN,
(MPARAM) mp1,
(MPARAM) mp2);
}
}
rValue = FALSE;
break;
case WM_CREATE:
if (DosLoadModule (NULL, 0L, "IPF", &hModule))
{
Error ("Cannot load module");
break;
}
if (!(hps = WinGetPS(hwnd)))
{
Error ("Cannot get presentation space");
break;
}
for (index = 0; index < FRAMES; index++)
{
if (!(hbm [index] = GpiLoadBitmap (hps,
hModule,
(USHORT)(IDB_FRAME1+index),
cxClient,
cyClient)))
{
Error ("Cannot load bitmap");
return (MRESULT) rValue;
}
}
WinReleasePS (hps);
index = 0;
if (!(Hhab = WinQueryAnchorBlock (hwnd)))
{
Error ("Cannot retrieve anchor block handle");
break;
}
if (!WinStartTimer (Hhab, hwnd, ID_TIMER, 150))
{
Error ("Cannot start timer");
break;
}
rValue = FALSE;
break;
case WM_TIMER:
if (index++ == FRAMES-1)
{
index = 0;
}
WinInvalidateRect (hwnd, NULL, FALSE);
rValue = FALSE;
break;
/** 2) Process **/
case WM_PAINT:
if (!(hps = WinBeginPaint (hwnd, NULL, NULL)))
{
Error ("Cannot set presentation space for drawing");
break;
}
if (!WinDrawBitmap (hps,
hbm [index],
NULL,
&ptl,
CLR_NEUTRAL,
CLR_BACKGROUND,
DBM_NORMAL))
{
Error ("Cannot draw bitmap");
break;
}
WinEndPaint (hps);
rValue = FALSE;
break;
case WM_SIZE:
cxClient = SHORT1FROMMP (mp2);
cyClient = SHORT2FROMMP (mp2);
rValue = FALSE;
break;
/** 3) Finish **/
case WM_CLOSE:
WinDestroyWindow (WinQueryWindow (hwnd, QW_PARENT));
rValue = FALSE;
break;
case WM_DESTROY:
WinStopTimer (Hhab, hwnd, ID_TIMER);
for (index = 0; index < 8; index++)
{
GpiDeleteBitmap (hbm [index]);
}
hwndPrevious = (HWND) WinQueryWindowULong (hwnd, COM_HWND);
hwndLatest = WinSendMsg (hwnd,
HM_QUERY,
MPFROM2SHORT (NULL, HMQW_OBJCOM_WINDOW),
NULL);
WinSendMsg (hwndLatest,
HM_UPDATE_OBJCOM_WINDOW_CHAIN,
(MPARAM) hwndPrevious,
(MPARAM) WinQueryWindow (hwnd, QW_PARENT));
DosFreeModule (hModule);
rValue = FALSE;
break;
default:
rValue = TRUE;
break;
}
return (rValue ? WinDefWindowProc (hwnd, msg, mp1, mp2) : 0L);
}