VOID main()
{

  if ( (hab = WinInitialize( 0L )) == (HAB) NULL ){
     printf( "ToolBar Error:  WinInitialize failed \n" );
     return;
  }
  else {
     if ( (hmq = WinCreateMsgQueue( hab, 0 )) == (HMQ) NULL ){
        printf( "ToolBar Error:  WinCreateMsgQueue failed \n" );
        return;
     }
     else {

       ULONG fulCreate= FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER |
                        FCF_MINMAX | FCF_SHELLPOSITION | FCF_ICON  ;
               /*
                *  Note: no menu was specificed in create flags
                */

        WinSetPointer( HWND_DESKTOP,
                       WinQuerySysPointer(HWND_DESKTOP,SPTR_WAIT,TRUE));

        WinRegisterClass(hab, szClassName, (PFNWP)MainWindowProc, CS_SIZEREDRAW, 0);

        hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
                                       0L,
                                       (PULONG)&fulCreate,
                                       szClassName ,
                                       szMainTitle,
                                       0L,
                                       (HMODULE)NULL,
                                       ID_MAIN_WIN,
                                       &hwndClient);
        if ( hwndFrame == NULLHANDLE ) {
           ShowErrorWindow( "Error creating Main window !", TRUE );
        }
        else {
           PFNWP     pfnwpOldFrameProc ;

             /* ---------  subclass frame proc  ------------------ */
           pfnwpOldFrameProc = WinSubclassWindow( hwndFrame,
                                                  (PFNWP) NewFrameProc );
           if ( pfnwpOldFrameProc == (PFNWP)0L ){
               ShowErrorWindow( "Error subclassing frame window !", TRUE );
           }
           else {
              PID       pid ;
              SWCNTRL   swCntrl;
              HSWITCH   hSwitch ;
              LONG      lRGB;

                /* -------  store old frame proc with handle  ------- */
              WinSetWindowULong( hwndFrame,
                                 QWL_USER,
                                 (ULONG) pfnwpOldFrameProc );

                /* ------------------ load menus  ------------------- */
              hwndMenuBar = WinLoadMenu( hwndFrame,
                                         (HMODULE)NULL,
                                         MID_MENUBAR );

              hwndToolBar = WinLoadMenu( hwndFrame,
                                         (HMODULE)NULL,
                                         MID_TOOLBAR );
                /*
                 *  Note that the last menu loaded, the toolbar, is the
                 *  one that is associated with the frame as "the" menu.
                 *  this means that hwndMenuBar is the only link to the
                 *  regular action bar, so hang onto it tightly
                 */

                /* ---------- set toolbar background color ---------- */
              lRGB =  WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONDARK, 0L );
              WinSetPresParam( hwndToolBar,
                               PP_BACKGROUNDCOLOR,
                               4L,
                               (PVOID)lRGB );

                /* ---------  set window size and pos  -------------- */
              WinSetWindowPos( hwndFrame,
                               HWND_TOP,
                               0, 0, 370, 300, 
                               SWP_SIZE | SWP_SHOW | SWP_ACTIVATE );

               /* ----------- add program to tasklist  --------------- */
              WinQueryWindowProcess( hwndFrame, &pid, NULL );
              swCntrl.hwnd = hwndFrame ;
              swCntrl.hwndIcon = (HWND) NULL ;
              swCntrl.hprog = (HPROGRAM) NULL ;
              swCntrl.idProcess = pid ;
              swCntrl.idSession = (LONG) NULL ;
              swCntrl.uchVisibility = SWL_VISIBLE ;
              swCntrl.fbJump = SWL_JUMPABLE ;
              sprintf( swCntrl.szSwtitle, szMainTitle );
              hSwitch = WinAddSwitchEntry((PSWCNTRL)&swCntrl);


              WinSetPointer(HWND_DESKTOP,
                            WinQuerySysPointer(HWND_DESKTOP,SPTR_ARROW,TRUE));

                 /* ---------- start the main processing loop ----------- */
              while (WinGetMsg(hab, &qmsg,NULLHANDLE,0,0)){
                  WinDispatchMsg(hab, &qmsg);
              }

              WinRemoveSwitchEntry( hSwitch );
           } /* end of else ( pfnwpOldFrameProc ) */

           WinSetPointer(HWND_DESKTOP,
                         WinQuerySysPointer(HWND_DESKTOP,SPTR_ARROW,TRUE));
           WinDestroyWindow(hwndFrame);
        }  /* end of else (hwndFrame == NULLHANDLE) */

        WinSetPointer(HWND_DESKTOP,
                      WinQuerySysPointer(HWND_DESKTOP,SPTR_ARROW,TRUE));
        WinDestroyMsgQueue(hmq);
     }  /* end of else ( ...WinCreateMsgQueue() */

   WinTerminate(hab);
   }  /* end of else (...WinInitialize(NULL) */
}  /*  end of main() */
nsresult nsLookAndFeel::NativeGetColor(const nsColorID aID, nscolor &aColor)
{
  nsresult res = NS_OK;

  int idx;
  switch (aID) {
    case eColor_WindowBackground:
        idx = SYSCLR_WINDOW;
        break;
    case eColor_WindowForeground:
        idx = SYSCLR_WINDOWTEXT;
        break;
    case eColor_WidgetBackground:
        idx = SYSCLR_BUTTONMIDDLE;
        break;
    case eColor_WidgetForeground:
        idx = SYSCLR_WINDOWTEXT; 
        break;
    case eColor_WidgetSelectBackground:
        idx = SYSCLR_HILITEBACKGROUND;
        break;
    case eColor_WidgetSelectForeground:
        idx = SYSCLR_HILITEFOREGROUND;
        break;
    case eColor_Widget3DHighlight:
        idx = SYSCLR_BUTTONLIGHT;
        break;
    case eColor_Widget3DShadow:
        idx = SYSCLR_BUTTONDARK;
        break;
    case eColor_TextBackground:
        idx = SYSCLR_WINDOW;
        break;
    case eColor_TextForeground:
        idx = SYSCLR_WINDOWTEXT;
        break;
    case eColor_TextSelectBackground:
    case eColor_IMESelectedRawTextBackground:
    case eColor_IMESelectedConvertedTextBackground:
        idx = SYSCLR_HILITEBACKGROUND;
        break;
    case eColor_TextSelectForeground:
    case eColor_IMESelectedRawTextForeground:
    case eColor_IMESelectedConvertedTextForeground:
        idx = SYSCLR_HILITEFOREGROUND;
        break;
    case eColor_IMERawInputBackground:
    case eColor_IMEConvertedTextBackground:
        aColor = NS_TRANSPARENT;
        return NS_OK;
    case eColor_IMERawInputForeground:
    case eColor_IMEConvertedTextForeground:
        aColor = NS_SAME_AS_FOREGROUND_COLOR;
        return NS_OK;
    case eColor_IMERawInputUnderline:
    case eColor_IMEConvertedTextUnderline:
        aColor = NS_SAME_AS_FOREGROUND_COLOR;
        return NS_OK;
    case eColor_IMESelectedRawTextUnderline:
    case eColor_IMESelectedConvertedTextUnderline:
        aColor = NS_TRANSPARENT;
        return NS_OK;
    case eColor_SpellCheckerUnderline:
        aColor = NS_RGB(0xff, 0, 0);
        return NS_OK;

    // New CSS 2 Color definitions
    case eColor_activeborder:
      idx = SYSCLR_ACTIVEBORDER;
      break;
    case eColor_activecaption:
      idx = SYSCLR_ACTIVETITLETEXT;
      break;
    case eColor_appworkspace:
      idx = SYSCLR_APPWORKSPACE;
      break;
    case eColor_background:
      idx = SYSCLR_BACKGROUND;
      break;
    case eColor_buttonface:
    case eColor__moz_buttonhoverface:
      idx = SYSCLR_BUTTONMIDDLE;
      break;
    case eColor_buttonhighlight:
      idx = SYSCLR_BUTTONLIGHT;
      break;
    case eColor_buttonshadow:
      idx = SYSCLR_BUTTONDARK;
      break;
    case eColor_buttontext:
    case eColor__moz_buttonhovertext:
      idx = SYSCLR_MENUTEXT;
      break;
    case eColor_captiontext:
      idx = SYSCLR_WINDOWTEXT;
      break;
    case eColor_graytext:
      idx = SYSCLR_MENUDISABLEDTEXT;
      break;
    case eColor_highlight:
    case eColor__moz_html_cellhighlight:
      idx = SYSCLR_HILITEBACKGROUND;
      break;
    case eColor_highlighttext:
    case eColor__moz_html_cellhighlighttext:
      idx = SYSCLR_HILITEFOREGROUND;
      break;
    case eColor_inactiveborder:
      idx = SYSCLR_INACTIVEBORDER;
      break;
    case eColor_inactivecaption:
      idx = SYSCLR_INACTIVETITLE;
      break;
    case eColor_inactivecaptiontext:
      idx = SYSCLR_INACTIVETITLETEXT;
      break;
    case eColor_infobackground:
      aColor = NS_RGB( 255, 255, 228);
      return res;
    case eColor_infotext:
      idx = SYSCLR_WINDOWTEXT;
      break;
    case eColor_menu:
      idx = SYSCLR_MENU;
      break;
    case eColor_menutext:
    case eColor__moz_menubartext:
      idx = SYSCLR_MENUTEXT;
      break;
    case eColor_scrollbar:
      idx = SYSCLR_SCROLLBAR;
      break;
    case eColor_threeddarkshadow:
      idx = SYSCLR_BUTTONDARK;
      break;
    case eColor_threedface:
      idx = SYSCLR_BUTTONMIDDLE;
      break;
    case eColor_threedhighlight:
      idx = SYSCLR_BUTTONLIGHT;
      break;
    case eColor_threedlightshadow:
      idx = SYSCLR_BUTTONMIDDLE;
      break;
    case eColor_threedshadow:
      idx = SYSCLR_BUTTONDARK;
      break;
    case eColor_window:
      idx = SYSCLR_WINDOW;
      break;
    case eColor_windowframe:
      idx = SYSCLR_WINDOWFRAME;
      break;
    case eColor_windowtext:
      idx = SYSCLR_WINDOWTEXT;
      break;
    case eColor__moz_eventreerow:
    case eColor__moz_oddtreerow:
    case eColor__moz_field:
    case eColor__moz_combobox:
      idx = SYSCLR_ENTRYFIELD;
      break;
    case eColor__moz_fieldtext:
    case eColor__moz_comboboxtext:
      idx = SYSCLR_WINDOWTEXT;
      break;
    case eColor__moz_dialog:
    case eColor__moz_cellhighlight:
      idx = SYSCLR_DIALOGBACKGROUND;
      break;
    case eColor__moz_dialogtext:
    case eColor__moz_cellhighlighttext:
      idx = SYSCLR_WINDOWTEXT;
      break;
    case eColor__moz_buttondefault:
      idx = SYSCLR_BUTTONDEFAULT;
      break;
    case eColor__moz_menuhover:
      if (WinQuerySysColor(HWND_DESKTOP, SYSCLR_MENUHILITEBGND, 0) ==
          WinQuerySysColor(HWND_DESKTOP, SYSCLR_MENU, 0)) {
        // if this happens, we would paint menu selections unreadable
        // (we are most likely on Warp3), so let's fake a dark grey
        // background for the selected menu item
        aColor = NS_RGB( 132, 130, 132);
        return res;
      } else {
        idx = SYSCLR_MENUHILITEBGND;
      }
      break;
    case eColor__moz_menuhovertext:
    case eColor__moz_menubarhovertext:
      if (WinQuerySysColor(HWND_DESKTOP, SYSCLR_MENUHILITEBGND, 0) ==
          WinQuerySysColor(HWND_DESKTOP, SYSCLR_MENU, 0)) {
        // white text to be readable on dark grey
        aColor = NS_RGB( 255, 255, 255);
        return res;
      } else {
        idx = SYSCLR_MENUHILITE;
      }
      break;
    case eColor__moz_nativehyperlinktext:
      aColor = NS_RGB( 0, 0, 255);
      return res;
    default:
      idx = SYSCLR_WINDOW;
      break;
  }

  long lColor = WinQuerySysColor( HWND_DESKTOP, idx, 0);

  int iRed = (lColor & RGB_RED) >> 16;
  int iGreen = (lColor & RGB_GREEN) >> 8;
  int iBlue = (lColor & RGB_BLUE);

  aColor = NS_RGB( iRed, iGreen, iBlue);

  return res;
}
/* This Proc handles the on-the-fly data CD writing */
MRESULT EXPENTRY waveinfoStatusDialogProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
  char text[CCHMAXPATH*2 +10];
  char title[CCHMAXPATH];
  SWCNTRL swctl;
  PID pid;
  int a;


  switch (msg)
    {
    case WM_PAINT:
      {
        HPS hps;
        RECTL rcl, rclSource;
        POINTL ptl;
        LONG lTemp;
        BOOL bUseCustomPainting=TRUE;
        LONG lWidthX;
        LONG lWidthY;
        LONG  lColor;
        ULONG attrFound;


        if(bUseCustomPainting) {
          //          if(allBMPs[CTRLIDX_BG].hbm) {
          if(1) {
            hps=WinBeginPaint(hwnd, NULLHANDLE, &rcl);
            rclSource.xLeft=0;
            rclSource.yBottom=0;
#if 0
            rclSource.yTop=allBMPs[CTRLIDX_BG].bmpInfoHdr.cy;
            rclSource.xRight=allBMPs[CTRLIDX_BG].bmpInfoHdr.cx;
            lTemp=rcl.xLeft/rclSource.xRight;
            ptl.x=lTemp*rclSource.xRight;
            lTemp=rcl.yBottom/rclSource.yTop;
            lTemp*=rclSource.yTop;
#endif

            //    rcl.yBottom+=4;
            rclSource=rcl;
            rcl.yTop+=4;
            WinFillRect(hps, &rclSource, CLR_RED);

            /* Border */
            lWidthX=WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
            lWidthY=WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);

            GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL);
#if 0
        if ( (WinQueryPresParam(hwnd, PP_BACKGROUNDCOLOR, 0, &attrFound, sizeof(attrFound),
                                                &lColor, QPF_PURERGBCOLOR)) == 0 )
           lColor = WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0);
#endif

            WinQueryWindowRect(hwnd, &rcl);
            ptl.x=1;
            ptl.y=0;
            GpiMove(hps, &ptl);
            GpiSetColor(hps, CLR_BLACK);
            ptl.x=rcl.xRight-1;
            GpiLine(hps,&ptl);
            ptl.y=rcl.yTop-1;
            GpiLine(hps,&ptl);
            GpiSetColor(hps, SYSCLR_SHADOW);
            ptl.x=rcl.xLeft;
            GpiLine(hps,&ptl);
            ptl.y=0;
            GpiLine(hps,&ptl);

            rcl.yTop-=1;
            rcl.yBottom+=1;
            rcl.xLeft+=1;
            rcl.xRight-=1;

            WinDrawBorder( hps,&rcl, 1, 1, 0, 0, 0x400);
            rcl.yTop-=1;
            rcl.yBottom+=1;
            rcl.xLeft+=1;
            rcl.xRight-=1;

            /* Get active border color */
            if(WinQueryActiveWindow(HWND_DESKTOP)==hwnd) {
              if ( (WinQueryPresParam(hwnd, PP_BORDERCOLOR, 0, &attrFound, sizeof(attrFound),
                                      &lColor, QPF_PURERGBCOLOR)) == 0 )
                lColor = WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0);
            }
            else {
              /* Inactive border color */
              if ( (WinQueryPresParam(hwnd, PP_INACTIVECOLOR, 0, &attrFound, sizeof(attrFound),
                                      &lColor, QPF_PURERGBCOLOR)) == 0 )
                lColor = WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0);
            }
            /*            Get Border size */
            WinSendMsg(hwnd, WM_QUERYBORDERSIZE, MPFROMP(&ptl),0);

            WinDrawBorder(hps,&rcl, ptl.x-2, ptl.y-2, lColor, 0, 0);

#if 0
            while(ptl.x<rcl.xRight) {
              ptl.y=lTemp;
              while(ptl.y<rcl.yTop) {/* y direction */
                //DosBeep(5000,100);
                WinDrawBitmap(hps, allBMPs[CTRLIDX_BG].hbm,
                              &rclSource, 
                              (PPOINTL)&ptl,
                              0, 0,
                              DBM_IMAGEATTRS);
                ptl.y+=allBMPs[CTRLIDX_BG].bmpInfoHdr.cy;
                //DosSleep(200);
              };
              ptl.x+=allBMPs[CTRLIDX_BG].bmpInfoHdr.cx; 
            };
#endif
            WinEndPaint(hps);
            return (MRESULT)0;
          }
        }
        break;
      }

    case WM_DRAWITEM:
      switch(SHORT1FROMMP(mp1))
        {
        case SLIDERID:
          return drawSlider(hwnd, msg, mp1, mp2, SHORT1FROMMP(mp1));
        default:
          break;
        }              
      break;
    case WM_INITDLG:
      /* Add switch entry */
      memset(&swctl,0,sizeof(swctl));
      WinQueryWindowProcess(hwnd,&pid,NULL);
      swctl.hwnd=hwnd;
      swctl.uchVisibility=SWL_VISIBLE;
      swctl.idProcess=pid;
      swctl.bProgType=PROG_DEFAULT;
      swctl.fbJump=SWL_JUMPABLE;
      WinAddSwitchEntry(&swctl);

#if 0      
      WinMessageBox( HWND_DESKTOP, HWND_DESKTOP, "",
                     "",
                     0UL, MB_OK | MB_ICONEXCLAMATION|MB_MOVEABLE );
#endif
      //      oldProc=WinSubclassWindow(WinWindowFromID(hwnd, IDST_TEXT), newProc);
      hwndNew=WinCreateWindow(hwnd, CLASS_NAME, "Title", WS_VISIBLE |WS_TABSTOP, 10,50, SLIDERID, 40, 
                              hwnd, HWND_TOP, SLIDERID, NULLHANDLE, NULLHANDLE);
      WinShowWindow(hwnd, TRUE);
      //      WinQueryWindowPos(hwndNew,&swpSl);
      return (MRESULT) TRUE;
      /* WM_APPTERMINATENOTIFY messages are sent from the helper programs e.g. format checker. */
    case WM_CLOSE:
      WinDismissDlg(hwnd,0);
      return FALSE;
    case WM_CONTROL:
      {
        switch(SHORT2FROMMP(mp1))
          {
          case SLN_SLIDERTRACK:
            {
              switch(SHORT1FROMMP(mp1))
                {
                case SLIDERID:
                  DosBeep(5000, 10);
                  break;
                default:
                  break;
                }/* switch */
              return (MRESULT) 0;
              break;
            }
          case SLN_CHANGE:
            {
              switch(SHORT1FROMMP(mp1))
                {
                case SLIDERID:
                  DosBeep(500, 100);
                  break;
                default:
                  break;
                }/* switch */
              return (MRESULT)TRUE;
            }
          default:
            break;
          }/* switch */
        break;
      }/* WM_CONTROL */
      
    case WM_COMMAND:
      switch(SHORT1FROMMP(mp1))
        {
        case DID_OK:
          /* User pressed the OK button */
          WinPostMsg(hwnd,WM_CLOSE,0,0);
          break;
        case IDPB_RIGHT:
          WinPostMsg( WinWindowFromID(hwnd, SLIDERID),
                      SLM_SETSLIDERINFO,
                      MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_RANGEVALUE),
                      MPFROMLONG( (LONG) 70 ));
          
          break;
        case IDPB_LEFT:
          WinPostMsg( WinWindowFromID(hwnd, SLIDERID),
                      SLM_SETSLIDERINFO,
                      MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_RANGEVALUE),
                      MPFROMLONG( (LONG) 20 ));
          
          break;
        case IDPB_SIZE:
          {
            SWP swp;
              RXSTRING arg[2];                       /* argument string for REXX  */
              RXSTRING rexxretval;                /* return value from REXX    */
              APIRET   rc;                        /* return code from REXX     */
              SHORT    rexxrc = 0;                /* return code from function */
              char chrThis[20];
              char chrHwnd[20];

              char    *str = "These words will be swapped"; /* text to swap   */

#if 0
              RexxRegisterFunctionExe("CWRXFunc1", (PFN)rexxFunc1);
              

              sprintf(chrThis, "%d",123);
              sprintf(chrHwnd, "%d", WinQueryWindow(hwnd,QW_PARENT));

              /* By setting the strlength of the output RXSTRING to zero, we   */
              /* force the interpreter to allocate memory and return it to us. */
              /* We could provide a buffer for the interpreter to use instead. */
              rexxretval.strlength = 0L;          /* initialize return to empty*/
              
              MAKERXSTRING(arg[0], chrHwnd, strlen(chrHwnd));/* create input argument     */
              MAKERXSTRING(arg[1], chrThis, strlen(chrThis));/* create input argument     */

              /* Here we call the interpreter.  We don't really need to use    */
              /* all the casts in this call; they just help illustrate         */
              /* the data types used.                                          */
              rc=RexxStart((LONG)      2,             /* number of arguments   */
                           (PRXSTRING)  &arg,          /* array of arguments    */
                           (PSZ)        "G:\\Projects_working\\mmclasses-0.3.0\\testfunc.cwr",/* name of REXX file     */
                           (PRXSTRING)  0,             /* No INSTORE used       */
                           (PSZ)        "CWRXX",         /* Command env. name     */
                           (LONG)       RXSUBROUTINE,  /* Code for how invoked  */
                           (PRXSYSEXIT) 0,             /* No EXITs on this call */
                           (PSHORT)     &rexxrc,       /* Rexx program output   */
                           (PRXSTRING)  &rexxretval ); /* Rexx program output   */

              sprintf(text,"rc: %d, function return code: %d, %s ", 
                      rc, (int) rexxrc, rexxretval.strptr);

              WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, text, "", 1234, MB_OK|MB_MOVEABLE);
              
              DosFreeMem(rexxretval.strptr);          /* Release storage       
                                                         given to us by REXX.  */
              
#endif

              //            WinQueryWindowPos(hwndNew,&swp);
              //    WinSetWindowPos(hwndNew, NULLHANDLE, 0, 0, swp.cx-30, swp.cy+10,SWP_SIZE);
          break;
          }
        default:
          break;
        }
      return (MRESULT) FALSE;
    default:
      break;
    }/* switch */
  
  return WinDefDlgProc( hwnd, msg, mp1, mp2);
}
BOOL CandyBarZFrameBorderPaintProc(HWND hwnd, RECTL * rect, HPS hpsFrame, short sState)
{
    CBZDATA     *pCBZData;
    CBZSHARE    *pCBZShare;
    PSPAINT     *pPaint;
    TEMPPAINT   *pFramePaint;
    BOOL        rc;
    int         i;
    ULONG       ulDataOffset;

    if (DosGetNamedSharedMem((PPVOID) & pCBZShare, CBZ_SHARE,  PAG_READ) != NO_ERROR)
    {
        return (FALSE);
    }
    ulDataOffset = pCBZShare->ulDataOffset;
    DosFreeMem(pCBZShare);

    // get window data
    if ((pCBZData = WinQueryWindowPtr(CandyBarZGetTopLevelFrameHWND(hwnd), ulDataOffset)) == NULL
            || !pCBZData->bFrameBorderEnabled  )
    {
        return (FALSE);
    }

    if (pCBZData->sFrameBorderIndex >= pCBZData->sPushButtonIndex)
    {
        return (FALSE);
    }

    // alloc paint struct
    if (DosAllocMem((PPVOID) & pFramePaint,
                    sizeof(TEMPPAINT),
                    PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR)
    {
        return (FALSE);
    }
    memset(pFramePaint, 0, sizeof(TEMPPAINT));

    pFramePaint->hab = WinQueryAnchorBlock(hwnd);

    // alloc paint struct
    if (DosAllocMem((PPVOID) & pPaint,
                    sizeof(PSPAINT),
                    PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR)
    {
        DosFreeMem(pFramePaint);
        return (FALSE);
    }
    memset(pPaint, 0, sizeof(PSPAINT));

    //Text plugin needs this for quering presentation parameters.
    pPaint->hwnd = hwnd;

    // entire window
    pPaint->rectlWindow = pPaint->rectlUpdate = *rect;

    // get PS
    pPaint->hpsWin = hpsFrame;

    // we will blt and draw gradient text into the hps associated with this dc
    if ((pFramePaint->hdc = DevOpenDC(pFramePaint->hab, OD_MEMORY, "*", 0L, (PDEVOPENDATA) NULL, NULLHANDLE))
            == NULLHANDLE)
    {
        DosFreeMem(pPaint);
        DosFreeMem(pFramePaint);
        return (FALSE);
    }
    // create hps2 for hdc2.  hps for hdc depends on size of bitmap, so it's not created until
    // we know if it's active or not.  create for size of window, then we blt only portion
    // needed
    pFramePaint->slHPS.cx = pPaint->rectlWindow.xRight;
    pFramePaint->slHPS.cy = pPaint->rectlWindow.yTop;

    if ((pPaint->hps = GpiCreatePS(pFramePaint->hab,
                                   pFramePaint->hdc,
                                   &(pFramePaint->slHPS),
                          PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC))
            == NULLHANDLE)
    {
        DevCloseDC(pFramePaint->hdc);
        DosFreeMem(pPaint);
        DosFreeMem(pFramePaint);
        return (FALSE);
    }

    pFramePaint->bif2.cbFix = sizeof(BITMAPINFOHEADER2);
    pFramePaint->bif2.cx = pPaint->rectlWindow.xRight;
    pFramePaint->bif2.cy = pPaint->rectlWindow.yTop;
    pFramePaint->bif2.cBitCount = 24;
    pFramePaint->bif2.cPlanes = 1;
    if ((pFramePaint->hbmTemp = GpiCreateBitmap(pPaint->hps,  // create bitmap
                                 (PBITMAPINFOHEADER2) & (pFramePaint->bif2),
                                                (ULONG) 0,
                                                (PSZ) NULL,
                       (PBITMAPINFO2) & (pFramePaint->bif2))) == NULLHANDLE)
    {
        GpiDestroyPS(pPaint->hps);
        DevCloseDC(pFramePaint->hdc);
        DosFreeMem(pPaint);
        DosFreeMem(pFramePaint);
        return (FALSE);
    }
    if (GpiSetBitmap(pPaint->hps, pFramePaint->hbmTemp) == HBM_ERROR)
    {
        GpiDeleteBitmap(pFramePaint->hbmTemp);
        GpiDestroyPS(pPaint->hps);
        DevCloseDC(pFramePaint->hdc);
        DosFreeMem(pPaint);
        DosFreeMem(pFramePaint);
        return (FALSE);
    }

    // set color table into rgb mode.  otherwise colors between 0 and
    // 15 are interpreted as indexes
    GpiCreateLogColorTable(pPaint->hps, 0, LCOLF_RGB, 0, 0, NULL);

    {
        //fill ps with default bg color...
        ULONG attrFound;
        long lColor;
        if ( (WinQueryPresParam(hwnd, PP_BACKGROUNDCOLOR, 0, &attrFound, sizeof(attrFound),
                                                &lColor, QPF_PURERGBCOLOR)) == 0 )
           lColor = WinQuerySysColor(HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0);
        // fill with default color
        WinFillRect(pPaint->hps, &(pPaint->rectlUpdate), lColor);
    }

    // call Plugins Paint Procedures here
    for (i = pCBZData->sFrameBorderIndex; i < pCBZData->sPushButtonIndex; i++)
    {
        if ( !(pCBZData->Plugins[i].pfnPluginRender(pPaint, pCBZData->Plugins[i].pData, sState)) )
        {
            GpiSetBitmap(pPaint->hps, NULLHANDLE);
            GpiDeleteBitmap(pFramePaint->hbmTemp);
            GpiDestroyPS(pPaint->hps);
            DevCloseDC(pFramePaint->hdc);
            DosFreeMem(pPaint);
            DosFreeMem(pFramePaint);
            return (FALSE);
        }
    }


    if ((rc = BltToWindow(pPaint)) == TRUE)
    {
        //paint sucessful, validate the window
//        WinQueryWindowRect(hwnd, &(pPaint->rectlUpdate));
        WinValidateRect(hwnd, &(pPaint->rectlUpdate), FALSE);
    }
    GpiSetBitmap(pPaint->hps, NULLHANDLE);
    GpiDeleteBitmap(pFramePaint->hbmTemp);
    GpiDestroyPS(pPaint->hps);
    DevCloseDC(pFramePaint->hdc);
    DosFreeMem(pPaint);
    DosFreeMem(pFramePaint);

    return (rc);
}
extern int main ( int argc, char *argv[] ) {

  /**************************************************************************
   * Register self.                                                         *
   **************************************************************************/

   Sys_RegisterThread ( ) ;

  /**************************************************************************
   * Set a default exception filter.                                        *
   **************************************************************************/

   REGISTER_EXCEPTION_HANDLER(0);

  /**************************************************************************
   * Start the main block (for constructors/destructors).                   *
   **************************************************************************/

   {

  /**************************************************************************
   * Get the initial file path for loading files from command-line.         *
   **************************************************************************/

   char InitialPath [CCHMAXPATH] ;
   _fullpath ( InitialPath, ".", sizeof(InitialPath) ) ;
   strcat ( InitialPath, "\\" ) ;

  /**************************************************************************
   * Determine the home directory.                                          *
   **************************************************************************/

   char Drive [_MAX_DRIVE+1], Dir[_MAX_DIR+1], Fname[_MAX_FNAME+1], Ext[_MAX_EXT+1] ;
   strupr ( argv[0] ) ;
   _fullpath ( HomePath, argv[0], sizeof(HomePath) ) ;
   _splitpath ( HomePath, Drive, Dir, Fname, Ext ) ;
   if ( Dir[strlen(Dir)-1] == '\\' )
      Dir[strlen(Dir)-1] = 0 ;
   strcpy ( HomePath, Drive ) ;
   strcat ( HomePath, Dir ) ;

   _chdrive ( Drive[0] - 'A' + 1 ) ;
   _chdir ( "\\" ) ;
   _chdir ( Dir ) ;

  /**************************************************************************
   * Set the C RunTime Library error message file handle.                   *
   **************************************************************************/

   #ifdef __DEBUG_ALLOC__
      Log ( "Escriba::main: Program started." ) ;
      _set_crt_msg_handle ( fileno(Logfile) ) ;
   #else
      #ifdef DEBUG
         Log ( "Escriba::main: Program started." ) ;
      #endif // DEBUG
   #endif // __DEBUG_ALLOC__

  /**************************************************************************
   * Determine if another instance of this program is present.              *
   *   If so, pass the command-line information to it.                      *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Checking for another instance already loaded." ) ;
   #endif // DEBUG

   PublicMemory Memory ( MEMORY_NAME, sizeof(SHARED_MEMORY), TRUE ) ;
   if ( NOT Memory.QueryCreated() ) {

      // Get the main instance's window handle.  Wait up to 20 seconds if necessary.
      HWND MainWindow = ((SHARED_MEMORY*)Memory.QueryMemory())->MainWindow ;
      clock_t LastClock = clock ( ) ;
      while ( MainWindow == 0 ) {
         if ( ( ( clock() - LastClock ) / CLOCKS_PER_SEC ) > 20 ) {
            Log ( "ERROR: Unable to get previous instance window handle." ) ;
            return ( 1 ) ;
         } /* endif */
         DosSleep ( 100 ) ;
         MainWindow = ((SHARED_MEMORY*)Memory.QueryMemory())->MainWindow ;
      } /* endwhile */

      // If any command-line parameters were given . . .
      if ( argc > 1 ) {

         // Build a command-line string.
         char Parms [512] = { 0 } ;
         int ParmLength = 0 ;
         while ( --argc ) {
            strcpy ( Parms+ParmLength, *(++argv) ) ;
            ParmLength += strlen(*argv) + 1 ;
         } /* endwhile */
         Parms[++ParmLength] = 0 ;

         // Get the original process's ID.
         PID Process ;
         TID Thread ;
         if ( !WinQueryWindowProcess ( MainWindow, &Process, &Thread ) ) {
            char Message [512] ;
            Log ( "ERROR: Unable to query window process.  %s", InterpretWinError(0,Message) ) ;
            return ( 1 ) ;
         } /* endif */

         // Allocate shared memory to hold the current path.
         PVOID Memory1 ;
         APIRET Status = DosAllocSharedMem ( &Memory1, 0, strlen(InitialPath)+1, fALLOC | OBJ_GIVEABLE | OBJ_GETTABLE) ;
         if ( Status ) {
            Log ( "ERROR: Unable to allocate shared memory.  Status %d.", Status ) ;
            return ( 1 ) ;
         } /* endif */
         strcpy ( PCHAR(Memory1), InitialPath ) ;

         // Allocate shared memory to hold the command-line.
         PVOID Memory2 ;
         Status = DosAllocSharedMem ( &Memory2, 0, ParmLength, fALLOC | OBJ_GIVEABLE | OBJ_GETTABLE) ;
         if ( Status ) {
            Log ( "ERROR: Unable to allocate shared memory.  Status %d.", Status ) ;
            return ( 1 ) ;
         } /* endif */
         memcpy ( Memory2, Parms, ParmLength ) ;

         // Make both shared memory blocks available to the original process.
         Status = DosGiveSharedMem ( Memory1, Process, PAG_READ | PAG_WRITE ) ;
         DosFreeMem ( Memory1 ) ;
         if ( Status ) {
            Log ( "ERROR: Unable to give shared memory.  Status %d.", Status ) ;
            return ( 1 ) ;
         } /* endif */
         Status = DosGiveSharedMem ( Memory2, Process, PAG_READ | PAG_WRITE ) ;
         DosFreeMem ( Memory2 ) ;
         if ( Status ) {
            Log ( "ERROR: Unable to give shared memory.  Status %d.", Status ) ;
            return ( 1 ) ;
         } /* endif */

         // Pass the information to the original process.
         Sys_PostMessage ( MainWindow, WM_LOAD_FILE, MPFROMP(Memory1), MPFROMP(Memory2) ) ;

      } /* endif */

      // Bring the previous instance to the fore.
      Sys_SetActiveWindow ( MainWindow ) ;

      // We're outta here . . .
      return ( 0 ) ;

   } /* endif */

  /**************************************************************************
   * If the ISPELL environment variable isn't set, set it to the current    *
   *   directory, before we change it.  This assumes that the current       *
   *   directory is also the directory to which Escriba (and ISPELL) was    *
   *   installed.  This is true with the basic installation.                *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Setting ISPELL environment variable." ) ;
   #endif // DEBUG

   {
      char *p = getenv ( "ISPELL" ) ;
      if ( p == 0 ) {
         static char SetString [_MAX_PATH+10] ;
         sprintf ( SetString, "ISPELL=%s", HomePath ) ;
         _putenv ( SetString ) ;
      } /* endif */
   }

  /**************************************************************************
   * Get application language module.                                       *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Loading default language." ) ;
   #endif // DEBUG

   char DefaultLanguage [80] = { 0 } ;

   { /* startblock */
      Profile IniFile ( PSZ(PROGRAM_NAME), 0, HomePath ) ;
      if ( IniFile.QueryHandle() ) 
         IniFile.GetString ( "Language", DefaultLanguage, sizeof(DefaultLanguage) ) ;
      else
         strcpy ( DefaultLanguage, "English" ) ;
   } /* endblock */

   Library = Language_Create ( PROGRAM_NAME, REVISION, IDS_TITLE1, DefaultLanguage ) ;
   if ( Library == 0 ) {
      Process Proc ( PROGRAM_NAME, HWND_DESKTOP, 0 ) ;
      Debug ( HWND_DESKTOP, "ERROR: Unable to find language module for %s, %s, %s.", PROGRAM_NAME, REVISION, DefaultLanguage ) ;
      return ( 1 ) ;
   } /* endif */

   LibraryHandle = Library->QueryHandle() ;

  /**************************************************************************
   * Get the program title.                                                 *
   **************************************************************************/

   ResourceString Title ( Library->QueryHandle(), IDS_TITLE ) ;

  /**************************************************************************
   * Determine the default codepage.                                        *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Determining codepage to use." ) ;
   #endif // DEBUG

   PUSHORT pCodePage = Library->QueryCodepages() ;
   while ( *pCodePage ) {
      if ( !DosSetProcessCp ( *pCodePage ) )
         break ;
      pCodePage ++ ;
   } /* endwhile */

   if ( *pCodePage == 0 ) {
      ResourceString Format ( Library->QueryHandle(), IDS_WARNING_BADCODEPAGE ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), *Library->QueryCodepages() ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
         PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      return ( 1 ) ;
   } /* endif */
 
  /**************************************************************************
   * Initialize the process with an extra-large message queue.              *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Connecting to PM." ) ;
   #endif // DEBUG

   Process Proc ( PCHAR(Title), HWND_DESKTOP, Library->QueryHandle(), 100, *pCodePage ) ;
   if ( Proc.QueryAnchor() == 0 ) 
      return ( 1 ) ;

  /**************************************************************************
   * Register the custom control classes.                                   *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Registering custom control classes." ) ;
   #endif // DEBUG

   RegisterControls ( Proc.QueryAnchor() ) ;

  /**************************************************************************
   * Open up debug timer.                                                   *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Opening debug timer." ) ;
   #endif // DEBUG

   OpenTimer ( ) ;

  /**************************************************************************
   * Open the registration library, if it is present.                       *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to open registration file." ) ;
   #endif // DEBUG

   char *RegistrationName = PROGRAM_NAME"R" ;
   Module *pRegistration = new Module ( RegistrationName, FALSE ) ;
   if ( pRegistration->QueryHandle() == 0 )
      RegistrationName = "PLUMAR" ;
   delete pRegistration, pRegistration = 0 ;

   Module Registration = Module ( RegistrationName, FALSE ) ;

  /**************************************************************************
   * Load any extenders (except spell-check).                               *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to load extenders." ) ;
   #endif // DEBUG

   AddonList.Build ( DefaultLanguage ) ;

  /**************************************************************************
   * Get the country information.                                           *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to get country information." ) ;
   #endif // DEBUG

   GetCountryInfo ( 0, 0 ) ;

  /**************************************************************************
   * Set any language-specific globals.                                     *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to set language-specific globals." ) ;
   #endif // DEBUG

   ResourceString AllGraphicFiles ( LibraryHandle, IDS_ALL_GRAPHICS ) ;
   GraphicTypeList[0] = PSZ ( AllGraphicFiles ) ;

  /**************************************************************************
   * Check for command-line options and remove them from the argument list. *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to parse the command line." ) ;
   #endif // DEBUG

   ResourceString ResetCommand ( Library->QueryHandle(), IDS_PARMS_RESET ) ;
   BOOL Reset = FALSE ;

// ResourceString PrintCommand ( Library->QueryHandle(), IDS_PARMS_PRINT ) ;
// BOOL Print = FALSE ;

   ResourceString TrapCommand ( Library->QueryHandle(), IDS_PARMS_TRAP ) ;
   BOOL Trap = FALSE ;

   int i = 1 ;
   char **p = argv + 1 ;
   while ( i < argc ) {
      if ( **p == '-' ) {
         if ( !stricmp ( (*p)+1, PCHAR(ResetCommand) ) ) {
            Reset = TRUE ;
//       } else if ( !stricmp ( (*p)+1, PCHAR(PrintCommand) ) ) {
//          Print = TRUE ;
         } else if ( !stricmp ( (*p)+1, PCHAR(TrapCommand) ) ) {
            Trap = TRUE ;
         } else {
            Debug ( HWND_DESKTOP, "ERROR: Invalid command-line parameter '%s'.", (*p)+1 ) ;
            return ( 1 ) ;
         } /* endif */
         for ( int j=i+1; j<argc; j++ ) {
            argv[j-1] = argv[j] ;
         } /* endfor */
         argv[j] = 0 ;
         argc -- ;
         continue ;
      } /* endif */
      i ++ ;
      p ++ ;
   } /* endwhile */

  /**************************************************************************
   * Create the help instance.                                              *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to create the help instance." ) ;
   #endif // DEBUG

   _splitpath ( Library->QueryName(), Drive, Dir, Fname, Ext ) ;
   char HelpFileName [CCHMAXPATH] ;
   sprintf ( HelpFileName, "%s.hlp", Fname ) ;

   ResourceString HelpTitle ( Library->QueryHandle(), IDS_HELPTITLE ) ;

   Help = new HelpWindow ( Proc.QueryAnchor(), 0, ID_MAIN, PSZ(HelpFileName), PSZ(HelpTitle) ) ;

   if ( Help->QueryHandle() == 0 ) {
      ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ;
      ResourceString Format ( Library->QueryHandle(), IDS_ERROR_CREATEHELP ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), Error ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
   } /* endif */

  /**************************************************************************
   * Open/create the profile file.  Reset if requested.                     *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to open profile file." ) ;
   #endif // DEBUG

   Profile2 IniFile ( PSZ(PROGRAM_NAME), Proc.QueryAnchor(), Library->QueryHandle(),
      IDD_PROFILE_PATH, Help, Reset ) ;

   if ( IniFile.QueryHandle() == 0 ) {
      ResourceString Message ( Library->QueryHandle(), IDS_ERROR_PRFOPENPROFILE ) ;
      Log ( "%s", PSZ(Message) ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      CloseTimer() ;
      return ( 2 ) ;
   } /* endif */

  /**************************************************************************
   * Get profile data. Try the OS2.INI first, then try for private INI.     *
   *   If obtained from OS2.INI, erase it afterwards and resave it.         *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to get profile data." ) ;
   #endif // DEBUG

   INIDATA IniData ( Registration.QueryHandle() ) ;
   IniFile.GetIniData ( IniData ) ;

   if ( IniData.Language [0] == 0 ) 
      strcpy ( IniData.Language, DefaultLanguage ) ;

  /**************************************************************************
   * Activate the spell checker, if it is present.                          *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to open the default dictionary." ) ;
   #endif // DEBUG

   char SpellerPath [ CCHMAXPATH ] = { 0 } ;
   if ( getenv ( "ISPELL" ) ) {
      strcpy ( SpellerPath, getenv ( "ISPELL" ) ) ;
      strcat ( SpellerPath, "\\" ) ;
   } /* endif */
   strcat ( SpellerPath, "ISPELLER.DLL" ) ;
   Dictionary *Speller = new Dictionary ( SpellerPath, DefaultLanguage ) ;
   if ( Speller->QueryLibrary() == 0 ) {
      #ifdef DEBUG
         Log ( "Escriba::main: Could not find spellchecker.  Will try again through LIBPATH." ) ;
      #endif // DEBUG
      delete Speller, Speller = 0 ;
      Speller = new Dictionary ( "ISPELLER", DefaultLanguage ) ;
   } /* endif */
   if ( Speller->Available() ) {
      #ifdef DEBUG
         Log ( "Escriba::main: Adding dictionary object to extension list." ) ;
      #endif // DEBUG
      AddonList.Add ( Speller ) ;
   } else {
      #ifdef DEBUG
         Log ( "Escriba::main: Dictionary object could not be fully created." ) ;
      #endif // DEBUG
      delete Speller, Speller = 0 ;
   } /* endif */

  /**************************************************************************
   * Create the frame window.                                               *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to create the frame window." ) ;
   #endif // DEBUG

   FRAMECDATA FrameControlData ;
   FrameControlData.cb = sizeof(FrameControlData) ;
   FrameControlData.flCreateFlags =
      FCF_TITLEBAR | FCF_MENU | FCF_ICON | FCF_NOBYTEALIGN | FCF_ACCELTABLE | FCF_SYSMENU |
      ( Trap ? 0 : FCF_SIZEBORDER | FCF_MINMAX ) ;
   FrameControlData.hmodResources = USHORT ( Library->QueryHandle() ) ;
   FrameControlData.idResources = ID_MAIN ;

   Window Frame ( HWND_DESKTOP, WC_FRAME, PSZ(Title),
      IniData.Animate ? WS_ANIMATE : 0,
      0, 0, 0, 0, HWND_DESKTOP, HWND_TOP, ID_MAIN,
      &FrameControlData, NULL ) ;

   if ( Frame.QueryHandle() == 0 ) {
      ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ;
      ResourceString Format ( Library->QueryHandle(), IDS_ERROR_CREATEFRAME ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), Error ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      CloseTimer() ;
      return ( 3 ) ;
   } /* endif */

  /**************************************************************************
   * Associate the help instance with the frame window.                     *
   **************************************************************************/

   Help->Associate ( Frame.QueryHandle() ) ;

  /**************************************************************************
   * Register the client window class.                                      *
   **************************************************************************/

   if ( !WinRegisterClass ( Proc.QueryAnchor(), PSZ(CLASS_NAME),
      MessageProcessor, CS_MOVENOTIFY, sizeof(PVOID) ) ) {
      ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ;
      ResourceString Format ( Library->QueryHandle(), IDS_ERROR_WINREGISTERCLASS ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), CLASS_NAME, Error ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
         PSZ(Title), IDD_ERROR_WINREGISTERCLASS, MB_ENTER | MB_ICONEXCLAMATION | MB_HELP, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      CloseTimer() ;
      return ( 4 ) ;
   } /* endif */

  /**************************************************************************
   * Build the presentation parameters for the main window.                 *
   **************************************************************************/

   COLOR BackColor = IniData.fMainColors[0] ? IniData.MainColors[0] :
      WinQuerySysColor ( HWND_DESKTOP, SYSCLR_APPWORKSPACE, 0 ) ;
   ULONG Ids[] = { PP_BACKGROUNDCOLOR } ;
   ULONG ByteCounts[] = { sizeof(BackColor) } ;
   PUCHAR Params[] = { PUCHAR(&BackColor) } ;

   PPRESPARAMS PresParams = BuildPresParams ( sizeof(Ids)/sizeof(Ids[0]),
     Ids, ByteCounts, Params ) ;

  /**************************************************************************
   * Create client window.  If this fails, destroy frame and return.        *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to create the client window." ) ;
   #endif // DEBUG

   PARMS Parms ;
   Parms.Filler = 0 ;
   Parms.Library = Library ;
   Parms.Registration = & Registration ;
   Parms.IniFile = & IniFile ;
   Parms.IniData = & IniData ;
   Parms.Speller = Speller ;
   Parms.InitialPath = InitialPath ;
   Parms.argc = argc ;
   Parms.argv = argv ;
   Parms.Trap = Trap ;

   Window Client ( Frame.QueryHandle(), PSZ(CLASS_NAME), PSZ(""), WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
      0, 0, 0, 0, Frame.QueryHandle(), HWND_BOTTOM, FID_CLIENT, &Parms, PresParams ) ;

   free ( PresParams ) ;

   if ( Client.QueryHandle() == 0 ) {
      ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ;
      ResourceString Format ( Library->QueryHandle(), IDS_ERROR_CREATECLIENT ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), Error ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
         PSZ(Title), IDD_ERROR_CREATECLIENT, MB_ENTER | MB_ICONEXCLAMATION | MB_HELP, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      CloseTimer ( ) ;
      return ( 5 ) ;
   } /* endif */

   ((SHARED_MEMORY*)Memory.QueryMemory())->MainWindow = Client.QueryHandle() ;

  /**************************************************************************
   * Wait for and process messages to the window's queue.  Terminate        *
   *   when the WM_QUIT message is received.                                *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to enter the main message loop." ) ;
   #endif // DEBUG

   Sys_ProcessMessages ( Proc.QueryAnchor() ) ;

  /**************************************************************************
   * Discard all that had been requested of the system.                     *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to close the HR Timer." ) ;
   #endif // DEBUG

   CloseTimer ( ) ;

  /**************************************************************************
   * Invoke nearly all the destructors.                                     *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Invoking most destructors." ) ;
   #endif // DEBUG

   } /* Invoke all destructors except the global ones. */

  /**************************************************************************
   * Invoke the remaining destructors.                                      *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Clearing the addon list." ) ;
   #endif // DEBUG

   AddonList.Clear ( ) ;

   #ifdef DEBUG
      Log ( "Escriba::main: Clearing the file type list." ) ;
   #endif // DEBUG

   ClearFileTypeList ( ) ;

   #ifdef DEBUG
      Log ( "Escriba::main: Clearing the graphic type list." ) ;
   #endif // DEBUG

   ClearGraphicTypeList ( ) ;

   #ifdef DEBUG
      Log ( "Escriba::main: Destroying the help instance." ) ;
   #endif // DEBUG

   if ( Help ) delete Help ;

   #ifdef DEBUG
      Log ( "Escriba::main: Destroying the language library instance." ) ;
   #endif // DEBUG

   if ( Library ) delete Library ;

  /**************************************************************************
   * Check to see if any memory remains allocated.                          *
   **************************************************************************/

   #ifdef __DEBUG_ALLOC__
      Log ( "Escriba::main: Checking the heap." ) ;
      _dump_allocated ( 64 ) ;
      Log ( "Escriba::main: Program ended." ) ;
      fclose ( Logfile ) ;
   #else
      #ifdef DEBUG
         Log ( "Escriba::main: Program ended." ) ;
      #endif // DEBUG
   #endif // __DEBUG_ALLOC__

  /**************************************************************************
   * Discard the exception filter.                                          *
   **************************************************************************/

   UNREGISTER_EXCEPTION_HANDLER(0);

  /**************************************************************************
   * Terminate the process.                                                 *
   **************************************************************************/

   return ( 0 ) ;
}
/*      QWL_USER+8 - reserved for text                        */
MRESULT EXPENTRY TestWndProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
  PMYCDATA pCData = (PMYCDATA)WinQueryWindowULong(hwnd, QWL_USER+4);
  PSZ pszText = (PSZ)WinQueryWindowULong(hwnd, QWL_USER+8);
  PMYCDATA pCreate;
  PCREATESTRUCT pCreateStruct;

  switch (msg) {
  /* we are creating our control */
  case WM_CREATE:
     /* if data was passed in */
     if (pCreate=(PMYCDATA)PVOIDFROMMP(mp1)) {
        /* allocate memory for the control data */
        DosAllocMem((PPVOID) &pCData,
                           (ULONG) pCreate->cb,
                           PAG_COMMIT|PAG_READ | PAG_WRITE);

        /* copy the data that is passed in */
        memcpy((PBYTE)pCData, (PBYTE) pCreate, pCreate->cb);

        /* save the control data pointer */
        WinSetWindowULong(hwnd, QWL_USER+4, (ULONG)pCData);
     } /* endif */
     /* allocate memory for the text */
     DosAllocMem((PPVOID) &pszText,
                        (ULONG) MAXTEXTLENGTH+1,
                        PAG_COMMIT|PAG_READ | PAG_WRITE);
     /* save the text pointer */
     WinSetWindowULong(hwnd, QWL_USER+8, (ULONG)pszText);
     /* initialize to a NULL string */
     strcpy(pszText,"");
     pCreateStruct=(PCREATESTRUCT)mp2;
     if (pCreateStruct) {
        /* copy the text into the buffer provided */
        strncpy(pszText, pCreateStruct->pszText,  MAXTEXTLENGTH);

        /* NULL terminate the string */
        pszText[MAXTEXTLENGTH]=0;
     }
     break;
  case WM_QUERYWINDOWPARAMS:
     {
        PWNDPARAMS pWndParams = (PWNDPARAMS)PVOIDFROMMP(mp1);
        MRESULT mr;

        /* call the default window proc first so that presentation
        /* parameters are handled */

        mr = WinDefWindowProc( hwnd, msg, mp1, mp2 );
        if (pWndParams) {
           if (pCData) {
              if (pWndParams->fsStatus & WPM_CBCTLDATA) {
                 pWndParams->cbCtlData = pCData->cb;
                 mr=(MRESULT)TRUE;
              } /* endif */
              if (pWndParams->fsStatus & WPM_CTLDATA) {
                 pWndParams->cbCtlData = pCData->cb;
                 memcpy((PBYTE)pWndParams->pCtlData, (PBYTE)pCData,  pCData->cb);
                 mr=(MRESULT)TRUE;
              } /* endif */
           } /* endif */

           /* responding to WinQueryWindowTextLength */
           if (pWndParams->fsStatus & WPM_CCHTEXT) {
              pWndParams->cchText = strlen(pszText);
              mr=(MRESULT)TRUE;
           } /* endif */

           /* responding to WinQueryWindowText */
           if (pWndParams->fsStatus & WPM_TEXT) {

              /* copy the text into the buffer provided */
              strncpy(pWndParams->pszText, pszText,  pWndParams->cchText);

              /* NULL terminate the string */
              pWndParams->pszText[pWndParams->cchText]=0;
              mr=(MRESULT)TRUE;
           } /* endif */
        } /* endif */
        return mr;
     }
     break;
  case WM_SETWINDOWPARAMS:
     {
        PWNDPARAMS pWndParams = (PWNDPARAMS)PVOIDFROMMP(mp1);
        MRESULT mr;

        mr = WinDefWindowProc( hwnd, msg, mp1, mp2 );
        if (pWndParams) {
           if (pWndParams->fsStatus & WPM_CTLDATA) {
              if (pCData) {
                 DosFreeMem(pCData);
              } /* endif */
              DosAllocMem((PPVOID) &(pCData),
                                 (ULONG) pWndParams->cbCtlData,
                                 PAG_COMMIT|PAG_READ | PAG_WRITE);
              WinSetWindowULong(hwnd, QWL_USER+4, (ULONG)pCData);
              memcpy((PBYTE)pCData, (PBYTE)pWndParams->pCtlData,  pWndParams->cbCtlData);
              WinInvalidateRect(hwnd, 0, 0);
              mr=(MRESULT)TRUE;
           } /* endif */

           /* responding to WinQueryWindowText */
           if (pWndParams->fsStatus & WPM_TEXT) {

              /* copy the text into the buffer provided */
              strncpy(pszText, pWndParams->pszText,  MAXTEXTLENGTH);

              /* NULL terminate the string */
              pszText[MAXTEXTLENGTH]=0;
              WinInvalidateRect(hwnd, 0, 0);
              mr=(MRESULT)TRUE;
           } /* endif */
        } /* endif */
        return mr;
     }
     break;
  case WM_PAINT:
     {
        HPS hps;
        RECTL rectlPaint;
        ULONG lTextColor, lBackColor;
        ULONG ulPPIndex;
        SWP swp;
        POINTL ptlPoint;

        WinQueryWindowPos(hwnd,&swp);
        hps=WinBeginPaint(hwnd, 0, &rectlPaint);

        /* put PS into RGB color mode */
        GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, 0 );

        if (!WinQueryPresParam(hwnd,PP_BACKGROUNDCOLOR,0,&ulPPIndex,
              sizeof(LONG),&lBackColor,QPF_NOINHERIT)) {
           lBackColor=WinQuerySysColor(HWND_DESKTOP,SYSCLR_WINDOW, 0);
        } /* endif */

        if (!WinQueryPresParam(hwnd,PP_FOREGROUNDCOLOR,0,&ulPPIndex,
              sizeof(LONG),&lTextColor,QPF_NOINHERIT)) {
           lTextColor=WinQuerySysColor(HWND_DESKTOP,SYSCLR_ICONTEXT, 0);
        } /* endif */

        WinFillRect(hps, &rectlPaint, lBackColor);
        ptlPoint.x=0;
        ptlPoint.y=0;
        GpiMove(hps,&ptlPoint);
        ptlPoint.x=swp.cx-1;
        ptlPoint.y=swp.cy-1;
        GpiBox(hps,DRO_OUTLINE,&ptlPoint,0,0);


        /* draw your control and its text here */
        ptlPoint.x=0;
        ptlPoint.y=0;
        GpiSetCharAngle(hps,&pCData->gradient);
        GpiSetCharMode(hps,CM_MODE3);
        GpiSetColor(hps,lTextColor);
        GpiSetDrawControl(hps,DCTL_DISPLAY,DCTL_OFF);
        GpiSetDrawControl(hps,DCTL_BOUNDARY,DCTL_ON);
        GpiCharStringAt(hps, &ptlPoint,strlen(pszText),pszText);
        GpiQueryBoundaryData(hps,&rectlPaint);
        GpiSetDrawControl(hps,DCTL_DISPLAY,DCTL_ON);
        GpiSetDrawControl(hps,DCTL_BOUNDARY,DCTL_OFF);
        ptlPoint.x=-rectlPaint.xLeft;
        ptlPoint.y=-rectlPaint.yBottom;
        GpiCharStringAt(hps, &ptlPoint,strlen(pszText),pszText);

        WinEndPaint(hps);
     }
     break;
  case WM_DESTROY:
     if (pCData)
        DosFreeMem(pCData);
     if (pszText)
        DosFreeMem(pszText);
     break;
  case WM_PRESPARAMCHANGED:
     WinInvalidateRect(hwnd,0,FALSE);
     break;
  default:
     return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  } /* endswitch */
  return (MRESULT) FALSE;
}