The un*x to OS/2-EMX Porting FAQ (pibtst.c)
Appearance
This is the pibtst.c sampled from The un*x to OS/2-EMX Porting FAQ article. You can also get the file from this link:
/**********************************************************************
* pibtst.c
*
* Shows how to modify the PIB so that an OS/2 VIO program can
* dynamically "morph" into an OS/2 PM program. An interesting
* side-effect of the morphing process is that stdout/stdin are still
* tied to the VIO window. In other words, printf() and gets() will
* will write to and read from the OS/2 Window from where the program
* was started. Of course, reading from stdin inside a window
* procedure is not a good idea.
*
* The modification of the PIB can be moved after the call to
* WinInitialize(), but must occur before the call to
* WinCreateMsgQueue(). You can also reset the pib->pib_ultype field to 2
* (the value for an OS/2 VIO session) after the call to
* WinCreateMsgQueue() without losing the ability to create windows.
* You will probably not be able to create a message queue in another
* thread if you reset this field, though.
*
* Note that the PIB being in a read/write area is in fact documented
* behavior. See DosGetInfoBlocks in the Control Program Guide and
* Reference.
*
* To compile the program:
* gcc -o pibtst.exe -DMORPH pibtst.c (EMX)
* icc /Fepibtst.exe /DMORPH pibtst.c (VACPP or C/Set++)
*
* Remove the -DMORPH or /DMORPH in the above lines to see how the
* program behaves without setting pib->pib_ultype.
*
* Darren Abbott
* abbott@hiwaay.net
*
* The included binary was created by:
* gcc -DMORPH -O3 -s -o pibtst.exe pibtst.c -Zmt -Zsys -Zomf -Zsmall-conv
*
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#define INCL_DOSPROCESS
#define INCL_WINWINDOWMGR
#define INCL_WIMMESSAGEMGR
#define INCL_WINDIALOGS
#include <os2.h>
static MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg,
MPARAM mp1, MPARAM mp2);
int main(void) {
HAB hab;
HMQ hmq;
PPIB pib;
PTIB tib;
BOOL rc;
HWND hwndFrame;
HWND hwndClient;
ULONG fcf;
QMSG qmsg;
char input[80];
char className[] = "TestClass.Win";
DosGetInfoBlocks(&tib, &pib);
printf("pib->pib_ultype = %d\n", pib->pib_ultype);
#ifdef MORPH
/* Try morphing into a PM application. */
pib->pib_ultype = 3;
printf("pib->pib_ultype = %d\n", pib->pib_ultype);
#endif
hab = WinInitialize(0);
printf("hab = %d\n", hab);
hmq = WinCreateMsgQueue(hab, 0);
printf("hmq = %d\n", hmq);
printf("Type enter to continue\n");
gets(input);
/* Create a simple window. */
rc = WinRegisterClass(hab, className, ClientWndProc, CS_SIZEREDRAW, 0L);
if (!rc) {
printf("WinRegisterClass failed\n");
}
fcf = FCF_TASKLIST | FCF_SYSMENU | FCF_SIZEBORDER |
FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_MINBUTTON;
hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE,
&fcf, className, "Test",
0L, 0, 1, &hwndClient);
if (!hwndFrame) {
printf("WinCreateStdWindow error\n");
}
printf("%s: %d\n", __FILE__, __LINE__);
while (WinGetMsg(hab, &qmsg, 0L, 0, 0))
WinDispatchMsg(hab, &qmsg);
WinDestroyWindow(hwndFrame);
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
printf("%s: %d\n", __FILE__, __LINE__);
return 0;
}
static MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg,
MPARAM mp1, MPARAM mp2) {
HPS hps;
RECTL rcl;
static char codeName[80] = { "Test Window" };
switch (msg) {
case WM_CREATE:
printf("WM_CREATE\n");
break;
case WM_CLOSE:
printf("WM_CLOSE\n");
WinPostMsg(hwnd, WM_QUIT, 0, 0);
break;
case WM_PAINT:
printf("WM_PAINT\n");
hps = WinBeginPaint(hwnd, NULLHANDLE, NULL);
WinQueryWindowRect(hwnd, &rcl);
GpiSetColor(hps, CLR_DARKCYAN);
WinDrawText(hps, -1, codeName, &rcl, 0, 0,
DT_TEXTATTRS | DT_CENTER | DT_VCENTER | DT_ERASERECT);
WinEndPaint(hps);
break;
default:
return WinDefWindowProc(hwnd, msg, mp1, mp2);
}
return 0;
}