home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / samples / som / somem / c / emdemo / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-21  |  20.3 KB  |  668 lines

  1. /*
  2.  *   COMPONENT_NAME: somx
  3.  *
  4.  *   ORIGINS: 27
  5.  *
  6.  *
  7.  *   10H9767, 10H9769  (C) COPYRIGHT International Business Machines Corp. 1992,1994
  8.  *   All Rights Reserved
  9.  *   Licensed Materials - Property of IBM
  10.  *   US Government Users Restricted Rights - Use, duplication or
  11.  *   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  12.  */
  13. /*   %Z% %I% %W% %G% %U% [%H% %T%] */
  14.  
  15. /*
  16.  *
  17.  * DISCLAIMER OF WARRANTIES.
  18.  * The following [enclosed] code is sample code created by IBM
  19.  * Corporation. This sample code is not part of any standard or IBM
  20.  * product and is provided to you solely for the purpose of assisting
  21.  * you in the development of your applications.  The code is provided
  22.  * "AS IS". IBM MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
  23.  * NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24.  * FOR A PARTICULAR PURPOSE, REGARDING THE FUNCTION OR PERFORMANCE OF
  25.  * THIS CODE.  IBM shall not be liable for any damages arising out of
  26.  * your use of the sample code, even if they have been advised of the
  27.  * possibility of such damages.
  28.  *
  29.  * DISTRIBUTION.
  30.  * This sample code can be freely distributed, copied, altered, and
  31.  * incorporated into other software, provided that it bears the above
  32.  * Copyright notice and DISCLAIMER intact.
  33.  */
  34.  
  35. /*
  36.    ==========================================================================
  37.    main.c
  38.  
  39.    This test program exercises several facilities of Event Manager (EMan).
  40.    It shows how to register interest in timer, client and workproc
  41.    events. It also shows how the callback routines are to be written.
  42.    This program exercises all most all of EMan methods.
  43.    ==========================================================================
  44. */
  45.  
  46. /* Definitions and includes.
  47.  --------------------------- */
  48. /* #define ILLUSTRATE_LOOP */
  49.  
  50. #include <windows.h>
  51. #include <stdio.h>
  52. #include <stdlib.h>
  53. #include <string.h>
  54. #include <malloc.h>
  55. #include <sys\types.h>
  56. #include <time.h>
  57. #include <errno.h>
  58. #include <io.h>
  59. #include <fcntl.h>
  60. #include <share.h>
  61.  
  62. #include <som.h>     
  63.  
  64. /* EMan includes.
  65.  ---------------- */
  66. #include <eman.h>
  67. #include <eventmsk.h>
  68. #include "emobj.h"
  69.  
  70. #include "main.h"
  71. #include "nlsutil.h"
  72. /* Messages for NLS Support */
  73. static char *nlsmsgs[ENDNLSID-STARTNLSID+1];
  74. #define GetNlsMessage(id) nlsmsgs[id-STARTNLSID]
  75. #define SetNlsMessage(id, str) nlsmsgs[id-STARTNLSID] = (str);
  76.  
  77. /**********************************************************
  78. 18953: NLS support
  79. This procedure must be called first to initialize all the messages
  80. to be used by irdump. These messages are obtained from the resource file.
  81. ****************************************************************/
  82. static void InitNlsMsgs(){
  83.     SetNlsMessage(EMANSAMPLEERRORID, NlsMsgAlloc(EMANSAMPLEERRORID));
  84.     SetNlsMessage(UnknownCommandId, NlsMsgAlloc(UnknownCommandId));
  85.     SetNlsMessage(CallbackId, NlsMsgAlloc(CallbackId));
  86.     SetNlsMessage(ClientEventDataId, NlsMsgAlloc(ClientEventDataId));
  87.     SetNlsMessage(UnknownEventTypeId, NlsMsgAlloc(UnknownEventTypeId));
  88.     SetNlsMessage(DestroyId, NlsMsgAlloc(DestroyId));
  89.     SetNlsMessage(EventType1Id, NlsMsgAlloc(EventType1Id));
  90.     SetNlsMessage(HelloMomId, NlsMsgAlloc(HelloMomId));
  91.     SetNlsMessage(EventType2Id, NlsMsgAlloc(EventType2Id));
  92.     SetNlsMessage(HelloDadId, NlsMsgAlloc(HelloDadId));
  93.     SetNlsMessage(SOMEventMgrId, NlsMsgAlloc(SOMEventMgrId));
  94.     SetNlsMessage(StartEMANLoopId, NlsMsgAlloc(StartEMANLoopId));
  95.     SetNlsMessage(LeftEMANLoopId, NlsMsgAlloc(LeftEMANLoopId));
  96.     SetNlsMessage(QuittingId, NlsMsgAlloc(QuittingId));
  97. }
  98.  
  99.  
  100. BOOL InitAppl(HINSTANCE);
  101.  
  102. /* Globals.
  103.  ---------- */
  104. static  SOMEEMan           *gEManPtr;
  105. static  Environment        *testEnv;
  106. static  EMObject           *target;
  107. static  long               regId0, regId1, regId2, regId4, fd;
  108. static  SOMEClientEvent    *clientEvent1, *clientEvent2;
  109. static  SOMEEMRegisterData *data;
  110. static  long               sock, msgsockregId, sockregId, PortNumber;
  111.  
  112. static  char               portnumbstr[10];
  113.  
  114. Environment *mainev;
  115.  
  116. HINSTANCE hinst;
  117. HWND      hwndMain, hwndChild, hwndTimer, hwndWorkProc;
  118. HACCEL    haccel;
  119. short     sHighSock = 0;
  120. int       nCmd;
  121.  
  122. int       nPops = 0; /* Number of Timer Pops since registration */
  123. int       nWorkProcs = 0; /* Number of calls on WorkProc since registration */
  124.  
  125. struct msg_struct
  126. {
  127.    HWND hwnd;
  128.    char szMsg[100];
  129. };
  130.  
  131. #define WM_PROCESS_ARGS WM_USER + 100
  132.  
  133. void SOMLINK callBack( SOMEEvent  *event, void  *targetData );
  134. void ReadMsgAndPrint( SOMEEvent event, void *inputdata);
  135. LRESULT APIENTRY MainWndProc(HWND hwnd, UINT message, UINT wParam,
  136.                                LONG lParam);
  137. #ifdef THREAD_EMAN
  138. void startEman(void);
  139. #endif
  140.  
  141. /*=========================================================================*/
  142. /*                          Client Functions                               */
  143. /*=========================================================================*/
  144.  
  145. void ErrorMessage(char *lpszFmt, ...)
  146. {
  147.    char szBuf[256];
  148.    va_list args;
  149.  
  150.    va_start(args, lpszFmt);
  151.    wvsprintf(szBuf, lpszFmt, args);
  152.    MessageBox(hwndMain,szBuf,GetNlsMessage(EMANSAMPLEERRORID),MB_ICONEXCLAMATION | MB_OK);
  153. }
  154.  
  155. void InfoMessage(char *title, char *lpszFmt, ...)
  156. {
  157.    char szBuf[256];
  158.    va_list args;
  159.  
  160.    va_start(args, lpszFmt);
  161.    wvsprintf(szBuf, lpszFmt, args);
  162.    if (title)
  163.       MessageBox(hwndMain,szBuf,title,MB_ICONINFORMATION);
  164. }
  165.  
  166. void CheckEnv(Environment *ev) {
  167.     if (ev->_major != NO_EXCEPTION) {
  168.         ErrorMessage(somExceptionId(ev));
  169.     }
  170. }
  171. /**************************** ACCEPT CONNECTION ****************************/
  172.  
  173.  
  174. /*------------------------------  unRegister  -----------------------------*/
  175.  
  176. void  unRegister( long  id )
  177. {
  178.     Environment *env = somGetGlobalEnvironment();
  179.  
  180.     _someUnRegister( gEManPtr, env, id );
  181. }
  182.  
  183.  
  184. /*--------------------------  ChangeRegistrations  ------------------------*/
  185.  
  186. void ChangeRegistrations(HWND hwnd, char x)
  187. {
  188.     Environment        *env = somGetGlobalEnvironment();
  189.     EMRegProc          *proc;
  190.     HMENU               hMenu;
  191.  
  192.     hMenu = GetMenu(hwnd);
  193.  
  194.     switch (x) {
  195.     case 'c' : /* make a client event of type 1 occur */
  196.                _someQueueEvent(gEManPtr, env, clientEvent1);
  197.                break;
  198.  
  199.     case 'C' : /* make a client event of type 2 occur */
  200.                _someQueueEvent(gEManPtr, env, clientEvent2);
  201.                break;
  202.  
  203.     case 'W' : /* register a work proc with eman */
  204.                _someClearRegData( data, env );
  205.                _someSetRegDataEventMask( data, env, EMWorkProcEvent, NULL );
  206.                ShowWindow (hwndWorkProc,SW_SHOW);
  207.                proc = MakeProcInstance(callBack, hinst);
  208.                regId2 = _someRegisterProc( gEManPtr, env, data, proc, "Work Proc" );
  209.                EnableMenuItem(hMenu, IDM_REGPROC, MF_GRAYED);
  210.                EnableMenuItem(hMenu, IDM_UNREGPROC, MF_ENABLED);
  211.                nWorkProcs = 0;
  212.                break;
  213.  
  214.     case 'w' : /* Unregister a workproc from eman */
  215.                unRegister(regId2);
  216.                ShowWindow (hwndWorkProc,SW_HIDE);
  217.                EnableMenuItem(hMenu, IDM_REGPROC, MF_ENABLED);
  218.                EnableMenuItem(hMenu, IDM_UNREGPROC, MF_GRAYED);
  219.                break;
  220.  
  221.     case 't' : /* unregister timer events */
  222.                unRegister(regId1);
  223.                ShowWindow (hwndTimer,SW_HIDE);
  224.                EnableMenuItem(hMenu, IDM_REGTIMER, MF_ENABLED);
  225.                EnableMenuItem(hMenu, IDM_UNREGTIMER, MF_GRAYED);
  226.                EnableMenuItem(hMenu, IDM_UPDTIMER, MF_GRAYED);
  227.                break;
  228.  
  229.     case 'T' : /* reRegister timer events */
  230.                _someClearRegData( data, env );
  231.                _someSetRegDataEventMask( data, env, EMTimerEvent, NULL );
  232.                _someSetRegDataTimerInterval( data, env, 1000 );
  233.                ShowWindow (hwndTimer,SW_SHOW);
  234.                proc = MakeProcInstance(callBack, hinst);
  235.                regId1 = _someRegisterProc( gEManPtr,
  236.                                            env,
  237.                                            data,
  238.                                            proc,
  239.                                            "Timer Pop" );
  240.                EnableMenuItem(hMenu, IDM_REGTIMER, MF_GRAYED);
  241.                EnableMenuItem(hMenu, IDM_UNREGTIMER, MF_ENABLED);
  242.                EnableMenuItem(hMenu, IDM_UPDTIMER, MF_ENABLED);
  243.                nPops = 0;
  244.                break;
  245.  
  246.     case 'U' : /* update the timer registration data to change the timer interval value*/
  247.                _someClearRegData( data, env );
  248.                _someSetRegDataEventMask( data, env, EMTimerEvent, NULL );
  249.                _someSetRegDataTimerInterval( data, env, 800 );
  250.                _someChangeRegData(gEManPtr, env, regId1, data);
  251.                EnableMenuItem(hMenu, IDM_UPDTIMER, MF_GRAYED);
  252.                break;
  253.  
  254.     case 'q' : /* Quit program */
  255.     case 'Q' :
  256.                SendMessage(hwnd,WM_CLOSE,0,0L);
  257.                break;
  258.  
  259.     default:
  260.                break;
  261.     }
  262. }
  263.  
  264. /*-------------------------------  callBack  ------------------------------*/
  265.  
  266. void SOMLINK callBack( SOMEEvent  *event, void  *targetData )
  267. {
  268.      Environment *env = somGetGlobalEnvironment();
  269.      HBRUSH      hBrush ;
  270.      HDC         hdc ;
  271.      PAINTSTRUCT ps ;
  272.      RECT        rc ;
  273.      COLORREF    bkColor , fgColor;
  274.      char        szTimer[15];
  275.  
  276.     switch( _somevGetEventType( event, env )) {
  277.  
  278.     case  EMTimerEvent:
  279.         InvalidateRect (hwndTimer, NULL, FALSE) ;
  280.         hdc = BeginPaint (hwndTimer, &ps) ;
  281.         GetClientRect (hwndTimer, &rc) ;
  282.         bkColor = RGB(((nPops) * 32) % 255,63,255);
  283.         fgColor = RGB(255,255,255);
  284.  
  285.         /* fill the window */
  286.         hBrush = CreateSolidBrush (bkColor) ;
  287.         FillRect (hdc, &rc, hBrush) ;
  288.  
  289.         /* draw the text */
  290.         wsprintf(szTimer, "%s %d", (LPSTR) targetData, ++nPops);
  291.         SetBkColor(hdc, bkColor) ;
  292.         SetTextColor(hdc, fgColor) ;
  293.         DrawText (hdc, szTimer, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  294.  
  295.         EndPaint (hwndTimer, &ps) ;
  296.         DeleteObject (hBrush) ;
  297.  
  298.         break;
  299.  
  300.     case  EMSinkEvent:
  301.         InfoMessage(NULL, GetNlsMessage(CallbackId), targetData);
  302.         break;
  303.  
  304.     case  EMClientEvent:
  305.         InfoMessage("Client Type 2", GetNlsMessage(ClientEventDataId), (LPSTR) targetData);
  306.         break;
  307.  
  308.     case  EMWorkProcEvent:
  309.         InvalidateRect (hwndWorkProc, NULL, FALSE) ;
  310.         hdc = BeginPaint (hwndWorkProc, &ps) ;
  311.         GetClientRect (hwndWorkProc, &rc) ;
  312.         bkColor = RGB(((nWorkProcs + 128) * 16) % 255,0,127);
  313.         fgColor = RGB(255,255,255);
  314.         hBrush = CreateSolidBrush (bkColor) ;
  315.         FillRect (hdc, &rc, hBrush) ;
  316.         /* draw the text */
  317.         wsprintf(szTimer, "%s %d", (LPSTR) targetData,++nWorkProcs);
  318.         SetBkColor(hdc, bkColor) ;
  319.         SetTextColor(hdc, fgColor) ;
  320.         DrawText (hdc, szTimer, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  321.         EndPaint (hwndWorkProc, &ps) ;
  322.         DeleteObject (hBrush) ;
  323.         break;
  324.  
  325.     default: ErrorMessage(GetNlsMessage(UnknownEventTypeId));
  326.     }
  327. }
  328.  
  329.  
  330. /*---------------------------  MsgToCmd  ----------------------------------*/
  331.  
  332. char MsgToCmd(WORD msg, LPARAM lParam)
  333. {
  334.    char chCmd;
  335.  
  336.    switch (msg)
  337.    {
  338.       case IDM_REGPROC:
  339.          chCmd = 'W';
  340.          break;
  341.  
  342.       case IDM_UNREGPROC:
  343.          chCmd = 'w';
  344.          break;
  345.  
  346.       case IDM_REGTIMER:
  347.          chCmd = 'T';
  348.          break;
  349.  
  350.       case IDM_UNREGTIMER:
  351.          chCmd = 't';
  352.          break;
  353.  
  354.       case IDM_UPDTIMER:
  355.          chCmd = 'U';
  356.          break;
  357.  
  358.       case IDM_CLIENT1:
  359.          chCmd = 'c';
  360.          break;
  361.  
  362.       case IDM_CLIENT2:
  363.          chCmd = 'C';
  364.          break;
  365.  
  366.       case IDM_QUIT:
  367.          chCmd = 'Q';
  368.          break;
  369.  
  370.       case ID_CMD:
  371.          chCmd = LOBYTE(LOWORD(lParam));
  372.          break;
  373.  
  374.       default:
  375.          chCmd = -1;
  376.          break;
  377.    }
  378.  
  379.    return chCmd;
  380. }
  381.  
  382. /*---------------------------  MainWndProc  -------------------------------*/
  383.  
  384.  
  385. LRESULT APIENTRY MainWndProc(HWND hwnd, UINT message, UINT wParam,
  386.                                LONG lParam)
  387. {
  388.    char chCmd;
  389.    char *pTemp, *pBuf;
  390.    short cxClient, cyClient, i;
  391.  
  392.    switch (message)
  393.    {
  394.       case WM_CREATE:
  395.          haccel = LoadAccelerators(hinst, "MainAccel");
  396.          EnableMenuItem(GetMenu(hwnd), IDM_REGSOCK, MF_GRAYED);
  397.          break;
  398.  
  399.       case WM_SIZE:
  400.          cxClient = LOWORD (lParam) ;
  401.          cyClient = HIWORD (lParam) ;
  402.  
  403.          MoveWindow (hwndTimer, 5, 5, cxClient / 5, cyClient / 5, TRUE) ;
  404.          MoveWindow (hwndWorkProc, 10 + (cxClient / 5),
  405.                                    5,
  406.                                    cxClient / 5,
  407.                                    cyClient / 5,
  408.                                    TRUE) ;
  409.  
  410.       case WM_COMMAND:
  411.          if ((chCmd = MsgToCmd((WORD)wParam, lParam)) == -1)
  412.          {
  413.             return(DefWindowProc(hwnd, message, wParam, lParam));
  414.          }
  415.          else
  416.          {
  417.             ChangeRegistrations(hwnd, chCmd);
  418.          }
  419.          break;
  420.  
  421.       case WM_DESTROY:
  422.          InfoMessage(NULL, GetNlsMessage(DestroyId),(long) hwnd, sHighSock);
  423.          PostQuitMessage(0);
  424.          break;
  425.  
  426.       default:
  427.          return (DefWindowProc(hwnd, message, wParam, lParam));
  428.    }
  429.  
  430.    return 0;
  431. }
  432.  
  433. /*---------------------------  InitAppl  ----------------------------------*/
  434.  
  435. BOOL InitAppl(HINSTANCE hinstCur)
  436. {
  437.    WNDCLASS wc;
  438.  
  439.    wc.style = 0;
  440.    wc.lpfnWndProc = MainWndProc;
  441.    wc.cbClsExtra = 0;
  442.    wc.cbWndExtra = 0;
  443.    wc.hInstance = hinstCur;
  444.    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  445.    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  446.    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  447.    wc.lpszMenuName = "MainMenu";
  448.    wc.lpszClassName = "MainWClass";
  449.  
  450.    return(RegisterClass(&wc));
  451.  
  452. }
  453.  
  454. /*---------------------------  InitEMAN  ----------------------------------*/
  455.  
  456. BOOL InitEMAN(void)
  457. {
  458.     char        *comm_envvar;
  459.     Environment *testEnv = somGetGlobalEnvironment();
  460.  
  461.     gEManPtr = SOMEEManNew();         /* create an EMan object */
  462.     data = SOMEEMRegisterDataNew( );    /* create a registration data object */
  463.     target = EMObjectNew();    /* create a target object whose method is called back by EMan */
  464.  
  465.     /* Create a client event of type "ClientType1".
  466.      ---------------------------------------------- */
  467.     clientEvent1 = SOMEClientEventNew();
  468.     _somevSetEventClientType( clientEvent1, testEnv, "ClientType1" );
  469.     _somevSetEventClientData( clientEvent1,
  470.                               testEnv,
  471.                               GetNlsMessage(EventType1Id));
  472.  
  473.     /* Register the event with EMan.
  474.      ------------------------------- */
  475.     _someClearRegData( data, testEnv );
  476.     _someSetRegDataEventMask( data, testEnv, EMClientEvent, NULL );
  477.     _someSetRegDataClientType(data, testEnv, "ClientType1");
  478.     regId0 = _someRegisterEv( gEManPtr,
  479.                             testEnv,
  480.                             data,
  481.                             target,
  482.                             mainev,
  483.                             "eventMethod",
  484.                             GetNlsMessage(HelloMomId) );
  485.  
  486.     /* Create and register a different type of client event.
  487.      ------------------------------------------------------- */
  488.     clientEvent2 = SOMEClientEventNew();
  489.     _somevSetEventClientType( clientEvent2, testEnv, "ClientType2" );
  490.     _somevSetEventClientData( clientEvent2, testEnv, GetNlsMessage(EventType2Id) );
  491.     _someClearRegData( data, testEnv ); /* Notice that the registration data object can be reused */
  492.     _someSetRegDataEventMask( data, testEnv, EMClientEvent, NULL );
  493.     _someSetRegDataClientType( data, testEnv, "ClientType2" );
  494.     regId4 = _someRegisterProc( gEManPtr, testEnv, data, callBack, GetNlsMessage(HelloDadId));
  495.  
  496.     return(TRUE);
  497. }
  498.  
  499. /*---------------------------  InitInst  ----------------------------------*/
  500.  
  501. BOOL InitInst(HINSTANCE hinstCur, int nCmdShow)
  502. {
  503.    HWND hwnd;
  504.  
  505.    hinst = hinstCur;
  506.  
  507.    hwnd = CreateWindow("MainWClass", GetNlsMessage(SOMEventMgrId), WS_OVERLAPPEDWINDOW,
  508.                        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  509.                        CW_USEDEFAULT, NULL, NULL, hinstCur, NULL);
  510.  
  511.    hwndTimer = CreateWindow ("static", NULL, WS_CHILD | WS_DLGFRAME | SS_GRAYRECT,
  512.                              0, 0, 0, 0,
  513.                              hwnd, 0, hinstCur, NULL) ;
  514.  
  515.    hwndWorkProc = CreateWindow ("static", NULL, WS_CHILD | WS_DLGFRAME | SS_GRAYRECT,
  516.                                 0, 0, 0, 0,
  517.                                 hwnd, 0, hinstCur, NULL) ;
  518.  
  519.    if (hwnd == NULL)
  520.    {
  521.       return FALSE;
  522.    }
  523.  
  524.    hwndMain = hwnd;
  525.    nCmd = nCmdShow;
  526.  
  527.    return TRUE;
  528. }
  529.  
  530.  
  531. /*---------------------------  InitAppl  ----------------------------------*/
  532.  
  533. BOOL ProcessInput(LPSTR pszArgs)
  534. {
  535.    if (pszArgs != NULL && *pszArgs != '\0' && *pszArgs != ' ')
  536.    {
  537.       MessageBox(hwndMain,"This program ignores all command-line arguments...","Usage Information",MB_ICONEXCLAMATION | MB_OK);
  538.    }
  539.  
  540.    ShowWindow(hwndMain, nCmd);
  541.    UpdateWindow(hwndMain);
  542.  
  543.    return TRUE;
  544. }
  545.  
  546. /*=========================================================================*/
  547. /*                              Main Program                               */
  548. /*=========================================================================*/
  549.  
  550. int WINAPI WinMain(HINSTANCE hinstCur, HINSTANCE hinstPrev, LPSTR lpszCmdLine,
  551.                    int nCmdShow)
  552. {
  553.    short sQSize = 120;
  554.    int iRc = TRUE;
  555.  
  556. #if defined(ILLUSTRATE_LOOP) || defined(THREAD_EMAN)
  557.    MSG msg;
  558. #if defined(THREAD_EMAN)
  559.    DWORD threadId;
  560. #endif
  561.  
  562. #endif
  563.  
  564.     /* Init NLS Messages */
  565.     InitNlsMsgs();
  566.     
  567.   
  568.    testEnv = somGetGlobalEnvironment();
  569.  
  570.    if (!hinstPrev)
  571.    {
  572.       if (!InitAppl(hinstCur))
  573.       {
  574.          return FALSE;
  575.       }
  576.    }
  577.  
  578.    mainev = somGetGlobalEnvironment();
  579.  
  580.    if (!InitInst(hinstCur, nCmdShow))
  581.    {
  582.       return FALSE;
  583.    }
  584.  
  585.      Sleep(10);
  586.  
  587.    if (!InitEMAN())
  588.    {
  589.       return FALSE;
  590.    }
  591.  
  592.    if (ProcessInput(lpszCmdLine))
  593.    {
  594.  
  595.     /*------------------------------------------------------------------------
  596.  
  597.        Two alternative schemes are possible for a program using Eman.
  598.        The client program can provide its own main loop, polling Eman
  599.        periodically to process events registered with EMan.
  600.  
  601.        Alternatively, the client can turn control over to EMan's main
  602.        loop, with all client processing handled through the callback
  603.        mechanism and a standard Windows message loop implemented.
  604.  
  605.        The latter scheme is employed when the program can be designed
  606.        to be completely event-driven.  Both methods are illustrated below.
  607.  
  608.        Please note that the first scheme will not provide reliable timer
  609.        events as GetMessage only returns when there is a window message to
  610.        be processed.
  611.  
  612.      -------------------------------------------------------------------------*/
  613.  
  614. #ifdef ILLUSTRATE_LOOP
  615.  
  616.       while (GetMessage(&msg, NULL, NULL, NULL))
  617.       {
  618.          if (!TranslateAccelerator(hwndMain, haccel, &msg))
  619.          {
  620.             TranslateMessage(&msg);
  621.             DispatchMessage(&msg);
  622.          }
  623.  
  624.          _someProcessEvent(gEManPtr, testEnv,
  625.                            EMProcessTimerEvent
  626.                          | EMProcessSinkEvent
  627.                          | EMProcessClientEvent
  628.                          | EMProcessWorkProcEvent );
  629.       }
  630.  
  631. #elif !defined(THREAD_EMAN)
  632.  
  633.     /* Let EMan take over loop and process EMAN events between
  634.        processing Windows events.
  635.      --------------------------------------------------------- */
  636.     InfoMessage(NULL,GetNlsMessage(StartEMANLoopId));
  637.       _someProcessEvents(gEManPtr, testEnv);
  638.     InfoMessage(NULL,GetNlsMessage(LeftEMANLoopId));
  639.  
  640. #else
  641.       CreateThread(NULL, 0,
  642.                    (LPTHREAD_START_ROUTINE)startEman,
  643.                    NULL, 0, &threadId);
  644.       while (GetMessage(&msg, NULL, (UINT)NULL, (UINT)NULL))
  645.       {
  646.          if (!TranslateAccelerator(hwndMain, haccel, &msg))
  647.          {
  648.             TranslateMessage(&msg);
  649.             DispatchMessage(&msg);
  650.          }
  651.       }
  652.  
  653. #endif
  654.    }
  655.  
  656.    _somFree(gEManPtr);
  657.  
  658.    InfoMessage(NULL,GetNlsMessage(QuittingId));
  659.    return(iRc);
  660. }
  661.  
  662. #ifdef THREAD_EMAN
  663. void startEman(void)
  664. {
  665.         _someProcessEvents(gEManPtr, testEnv);
  666. }
  667. #endif
  668.