/**************************************************************************
 *
 *  Name       : Quatro(*HPS phps,int i, int j)
 *
 *  Description: рисует квадратик
 *
 *  Concepts:  Получает указатель на пространство отображения
 *	       и рисует квадрат размером BmpSize с координатами
 *        i и j
 *
 *
 *  API's      :
 *
 *  Parameters :  phps - указатель на hps
 *                i,j - номера элемента матрицы Field
 *************************************************************************/
VOID Quatro(PHPS phps,int i, int j)
{  RECTL rec;//где рисовать
   POINTL ptl;//куда и откуда рисовать
   //рисуем квадрат
   if(Field == NULL) return;//если инициализации не было
   rec.xLeft   = j*BmpSize+1;
   rec.xRight  = j*BmpSize+BmpSize;
   rec.yBottom = i*BmpSize;
   rec.yTop    = i*BmpSize+BmpSize-1;
   WinFillRect(*phps, &rec, Field[i][j]);
   if(bStyle){//рисуем линии 3D
      if(Field[i][j]>6)
         GpiSetColor(*phps,CLR_DARKGRAY);
      else
         GpiSetColor(*phps,Field[i][j]+8);
      ptl.x=j*BmpSize;
      ptl.y=i*BmpSize;
      GpiMove(*phps,&ptl);
      ptl.x=j*BmpSize+BmpSize-1;
      GpiLine(*phps,&ptl);
      GpiMove(*phps,&ptl);
      ptl.y=i*BmpSize+BmpSize;
      GpiLine(*phps,&ptl);
      ptl.x=j*BmpSize+BmpSize-2;
      ptl.y=i*BmpSize+BmpSize-1;
      GpiMove(*phps,&ptl);
      ptl.y=i*BmpSize+1;
      GpiLine(*phps,&ptl);
      GpiMove(*phps,&ptl);
      ptl.x=j*BmpSize+1;
      GpiLine(*phps,&ptl);}
}   /* End of Quatro */
void drawAxis(HPS hps,long yAxis12Dx,long yAxis12Dy,long yAxis22Dx,long yAxis22Dy,long xAxis12Dx,long xAxis12Dy,long xAxis22Dx,long xAxis22Dy,long zAxis12Dx,long zAxis12Dy,long zAxis22Dx,long zAxis22Dy,int drawIt )
{
    POINTL p;

    if (drawIt )
        GpiSetColor (hps,CLR_GREEN );
    else
        GpiSetColor (hps,CLR_BLACK );

    p.x=yAxis12Dx;
    p.y=yAxis12Dy;
    GpiMove(hps,&p);

    p.x=yAxis22Dx;
    p.y=yAxis22Dy;
    GpiLine(hps,&p);

    p.x=xAxis12Dx;
    p.y=xAxis12Dy;
    GpiMove(hps,&p);

    p.x=xAxis22Dx;
    p.y=xAxis22Dy;
    GpiLine(hps,&p);

    p.x=zAxis12Dx;
    p.y=zAxis12Dy;
    GpiMove(hps,&p);

    p.x=zAxis22Dx;
    p.y=zAxis22Dy;
    GpiLine(hps,&p);

}
/**************************************************************************
 *
 *  Name       : DlgQuatro(*HPS phps,int i, int j, LONG lColor)
 *
 *  Description: рисует квадратик в любом месте любого цвета
 *
 *  Concepts:  Родной брат обычного квадратика. Необходимость
 *	       в нем возникла при разработке диалога. Старый не
 *        подходил, и переделывать его значило бы
 *        перелопачивать всю программу. Елки-палки.
 *
 *  Parameters :  phps - указатель на hps
 *                i,j - координаты
 *                lColor - цвет
 *************************************************************************/
VOID DlgQuatro(PHPS phps,int i, int j, LONG lColor)
{  RECTL rec;//где рисовать
   POINTL ptl;//куда и откуда рисовать
   //рисуем квадрат
   rec.xLeft   = j+1;
   rec.xRight  = j+bs;
   rec.yBottom = i;
   rec.yTop    = i+bs-1;
   WinFillRect(*phps, &rec, lColor);
   if(st){//рисуем линии 3D
      if(lColor>6)
         GpiSetColor(*phps,CLR_DARKGRAY);
      else
         GpiSetColor(*phps,lColor+8);
      ptl.x=j;
      ptl.y=i;
      GpiMove(*phps,&ptl);
      ptl.x=j+bs-1;
      GpiLine(*phps,&ptl);
      GpiMove(*phps,&ptl);
      ptl.y=i+bs;
      GpiLine(*phps,&ptl);
      ptl.x=j+bs-2;
      ptl.y=i+bs-1;
      GpiMove(*phps,&ptl);
      ptl.y=i+1;
      GpiLine(*phps,&ptl);
      GpiMove(*phps,&ptl);
      ptl.x=j+1;
      GpiLine(*phps,&ptl);}
}   /* End of DlgQuatro */
static void drawLine(pLines pLin, HPS hps,WINDOWINFO *pwi,POINTL ptl1, POINTL ptl2)
{

      GpiSetLineType(hps,pLin->bt.line.LineType);
      GpiMove(hps, &ptl1);
      if (pLin->bt.line.LineWidth > 1 && pwi->uXfactor >= (float)1)
      {
         LONG lLineWidth = pLin->bt.line.LineWidth;

         if (pwi->ulUnits == PU_PELS)
         {
            lLineWidth = (lLineWidth * pwi->xPixels)/10000;
         }
         GpiSetPattern(hps, PATSYM_SOLID);
         GpiSetLineJoin(hps,pLin->bt.line.LineJoin);
         GpiSetLineEnd(hps,pLin->bt.line.LineEnd);
         GpiSetLineWidthGeom (hps,lLineWidth);
         GpiBeginPath( hps, 1L);  /* define a clip path    */
      }
      GpiLine(hps,&ptl2);

      if (pwi->uXfactor >= (float)1)
      {
         GpiSetLineType(hps,LINETYPE_SOLID);
         drwEndPoints(pwi,pLin->bt.arrow,ptl1,ptl2);
      }

      if (pLin->bt.line.LineWidth > 1 && pwi->uXfactor >= (float)1)
      {
         GpiEndPath(hps);
         GpiStrokePath (hps, 1, 0);
      }
}
/*------------------------------------------------------------------------*/
VOID DrawGrid(WINDOWINFO *pwi, RECTL *rcl)
{
   POINTL ptl;
   LONG   lForeColor;
   LONG   lBackColor;
   ULONG  ulcx = pwi->ulgridcx;
   ULONG  ulcy = pwi->ulgridcy;


   lForeColor = GpiQueryColor(pwi->hps);
   lBackColor = GpiQueryBackColor(pwi->hps);

   if (view.iZoom == 2)
   {
      ulcx /=2;
      ulcy /=2;
   }
   else if (view.iZoom && view.iZoom != 2)
   {
      ulcx *= view.iZoom;
      ulcy *= view.iZoom;
      ulcx /= 100;
      ulcy /= 100;
   }
   GpiSetColor(pwi->hps,lBackColor);
   GpiSetMix(pwi->hps,FM_INVERT);

   for (ptl.x= rcl->xLeft; ptl.x <  rcl->xRight; ptl.x += (ulcx * pwi->ulgriddisp))
      for (ptl.y=rcl->yBottom; ptl.y <  rcl->yTop; ptl.y += (ulcy * pwi->ulgriddisp))
      {
         GpiMove(pwi->hps,&ptl);
         GpiLine(pwi->hps,&ptl);
      }
   GpiSetColor(pwi->hps,lForeColor);
}
void DrawFigure (HPS hps, INT i, INT cxClient, INT cyClient)
     {
     POINTL ptl ;

     ptl.x = (1 + 10 * i) * cxClient / 30 ;
     ptl.y = 3 * cyClient / 4 ;
     GpiMove (hps, &ptl) ;

     ptl.x = (5 + 10 * i) * cxClient / 30 ;
     ptl.y = cyClient / 4 ;
     GpiLine (hps, &ptl) ;

     ptl.x = (9 + 10 * i) * cxClient / 30 ;
     ptl.y = 3 * cyClient / 4 ;
     GpiLine (hps, &ptl) ;
     }
Exemple #7
0
VOID ShowStatusLine( const HPS hps, const char Moves,
							const char Ships, const LONG Width,
							const LONG Height )
{
    RECTL Rect = { 0, Height, Width, Height + 30 };
    POINTL Point = { Width, Height };
    CHAR text[256];
 
    WinFillRect( hps, &Rect, CLR_WHITE ); //SYSCLR_WINDOW );	// clear background
    GpiSetColor( hps, CLR_BLACK );
    GpiSetLineType( hps, LINETYPE_SHORTDASH );
    GpiSetLineWidth( hps, LINEWIDTH_NORMAL );
    GpiSetMix( hps, FM_OVERPAINT );
    GpiMove( hps, &Point );
    Point.x = 0;
    GpiLine( hps, &Point );
    Point.x += 10;
    Point.y += 10;
    GpiMove( hps, &Point );
    if( Ships )
	sprintf( text, "%d %s made     %d %s still lost", Moves,
		 Moves == 1 ? "move" : "moves", Ships, Ships == 1 ? "ship" : "ships" );
    else
	sprintf( text, "%d %s made     All ships found", Moves,
		 Moves == 1 ? "move" : "moves" );

    GpiCharString( hps, strlen(text), text );
    DosSleep( 1 );	// free time slice 
} 
MRESULT
DrawMenuItem( POWNERITEM poi )
{
  TASKDATA* data = (TASKDATA*)poi->hItem;
  BOOL   select  = (poi->fsAttribute & MIA_HILITED) ? TRUE : FALSE;
  ULONG  cx_icon = WinQuerySysValue( HWND_DESKTOP, SV_CXICON );
  ULONG  cy_icon = WinQuerySysValue( HWND_DESKTOP, SV_CYICON );
  POINTL pos;
  RECTL  rect = poi->rclItem;

  WinFillRect( poi->hps, &rect, select ? SYSCLR_MENUHILITEBGND : SYSCLR_MENU );

  rect.xLeft += 2;
  rect.yBottom += ( rect.yTop - rect.yBottom - cy_icon/2 ) / 2;
  if( data->hIcon != NULLHANDLE ) {
    WinDrawPointer( poi->hps, rect.xLeft + 1, rect.yBottom + 1, data->hIcon, DP_MINI );
  }

  rect.xLeft += cx_icon/2 + 5;
  rect.yBottom = poi->rclItem.yBottom;
  WinDrawText( poi->hps, -1, data->szTitle, &rect,
                    select ? SYSCLR_MENUHILITE : SYSCLR_MENUTEXT, 0,
                    DT_LEFT | DT_VCENTER );

  // Well well well... And now ;) we are going to fix A great-Warp4-Menu-Bug
  // Make to redraw erased parts of menu's window border
  // Define something like #ifdef WARP_3 if you are running OS/2 Warp 3.x

  // vertical "light" line
  pos.x = poi->rclItem.xLeft;
  pos.y = 1;
  GpiSetColor( poi->hps, SYSCLR_BUTTONLIGHT );
  GpiMove( poi->hps, &pos );
  pos.y = poi->rclItem.yTop;
  GpiLine( poi->hps, &pos );

  // horizontal "dark" line
  pos.x = 1;
  pos.y = 1;
  GpiSetColor( poi->hps, SYSCLR_BUTTONDARK );
  GpiMove( poi->hps, &pos );
  pos.x = poi->rclItem.xRight;
  GpiLine( poi->hps, &pos );

  poi->fsAttributeOld = (poi->fsAttribute &= ~MIA_HILITED);
  return MRFROMLONG( TRUE );
}
VOID DrawCrossHairsInner (HWND hwnd)
     {
     POINTL ptl1;

     GpiSetMix (cp.hpsScreen, FM_INVERT) ;

     ptl1.x = 0; ptl1.y = ptlCrossHairs.y;
     GpiMove (cp.hpsScreen, &ptl1);
     ptl1.x = cxClient-1;
     GpiLine (cp.hpsScreen, &ptl1);
     ptl1.x = ptlCrossHairs.x; ptl1.y = 0;
     GpiMove (cp.hpsScreen, &ptl1);
     ptl1.y = cyClient-1;
     GpiLine (cp.hpsScreen, &ptl1);

     GpiSetMix (cp.hpsScreen, FM_DEFAULT);
     }
/*--------------------------------------------------
 * Draws the 3D border
 *-------------------------------------------------*/
void PMWindow::draw_3dborder( HPS ps, const SHAPE& rect, long thickness )
{
  LONG palette_format;

  if( !GpiQueryColorData( ps, 1, &palette_format ))
    PM_THROW_GUIERROR();

  LONG white    = palette_format == LCOLF_RGB ? RGB_WHITE    : CLR_WHITE;
  LONG darkgray = palette_format == LCOLF_RGB ? RGB_DARKGRAY : CLR_DARKGRAY;
  LONG palegray = palette_format == LCOLF_RGB ? RGB_PALEGRAY : CLR_PALEGRAY;
  LONG black    = palette_format == LCOLF_RGB ? RGB_BLACK    : CLR_BLACK;

  POINTL pos;
  GpiSetLineWidth( ps, LINEWIDTH_NORMAL );

  pos.y = rect.y;
  pos.x = rect.x;
  GpiMove( ps, &pos );

  GpiSetColor( ps, white );
  pos.x = rect.x+rect.cx-1;
  GpiLine( ps, &pos );
  pos.y = rect.y+rect.cy-1;
  GpiLine( ps, &pos );

  GpiSetColor( ps, darkgray );
  pos.x = rect.x;
  GpiLine( ps, &pos );
  pos.y = rect.y;
  GpiLine( ps, &pos );

  if( thickness > 1 )
  {
    pos.y = rect.y+1;
    pos.x = rect.x+1;
    GpiMove( ps, &pos );

    GpiSetColor( ps, palegray );
    pos.x = rect.x+rect.cx-2;
    GpiLine( ps, &pos );
    pos.y = rect.y+rect.cy-2;
    GpiLine( ps, &pos );

    GpiSetColor( ps, black );
    pos.x = rect.x+1;
    GpiLine( ps, &pos );
    pos.y = rect.y+1;
    GpiLine( ps, &pos );
  }
}
Exemple #11
0
MRESULT hchlb_wmPaint( HWND hwnd, MPARAM mp1, MPARAM mp2 )
{
    HPS     hps;
    RECTL   rcl;
    POINTL  ptl;

    hps = WinBeginPaint( hwnd, NULLHANDLE, &rcl );
    WinQueryWindowRect( hwnd, &rcl );

    GpiSetColor( hps, SYSCLR_BUTTONDARK);

    ptl.x = rcl.xRight - 1;
    ptl.y = rcl.yTop - 1;
    GpiMove( hps, &ptl );

    ptl.x = rcl.xLeft;
    GpiLine( hps, &ptl );

    ptl.y = rcl.yBottom;
    GpiLine( hps, &ptl );

    GpiSetColor( hps, SYSCLR_BUTTONLIGHT );

    ptl.x = rcl.xLeft + 1;
    GpiMove( hps, &ptl );

    ptl.x = rcl.xRight - 1;
    GpiLine( hps, &ptl );

    ptl.y = rcl.yTop - 1;
    GpiLine( hps, &ptl );

    WinEndPaint( hps );

    return 0;
}
void drawGrid(HPS hps,long gridX,long gridY,int drawIt,char *str,BOOL tracename)
{
    POINTL p;

    if (!tracename)
        return;

    if (drawIt )
        GpiSetColor (hps,CLR_CYAN );
    else
        GpiSetColor (hps,CLR_BLACK );

    p.x=gridX-10;
    p.y=gridY-10;
    GpiMove(hps,&p);

    p.x=gridX-13;
    p.y=gridY-9;
    GpiLine(hps,&p);

    p.x=gridX-13;
    p.y=gridY+9;
    GpiLine(hps,&p);

    p.x=gridX-10;
    p.y=gridY+10;
    GpiLine(hps,&p);

    p.x=gridX+10;
    p.y=gridY-10;
    GpiMove(hps,&p);

    p.x=gridX+13;
    p.y=gridY-9;
    GpiLine(hps,&p);

    p.x=gridX+13;
    p.y=gridY+9;
    GpiLine(hps,&p);

    p.x=gridX+10;
    p.y=gridY+10;
    GpiLine(hps,&p);

    p.x=gridX;
    p.y=gridY-15;

    if (drawIt )
        GpiSetColor (hps,CLR_WHITE );
    
    GpiCharStringAt(hps,&p,strlen(str),str);

}
void XArc::Draw( XGraphicDevice * dev)
{
   if (!(settings & GO_HIDE))
   {
      SetupDevice(dev);

      POINTL po;
      po.x = p.x;
      po.y = p.y;
      GpiMove(dev->hps, &po);
      ARCPARAMS a;

      a.lQ = w;
      a.lP = h;
      a.lR = x;
      a.lS = y;

      GpiSetArcParams(dev->hps, &a);

      if (vis)
      {
         GpiBeginPath(dev->hps, 1);
         GpiPartialArc(dev->hps, &po, MAKEFIXED(1, 0), MAKEFIXED(st, 0), MAKEFIXED(en, 0));
         GpiLine(dev->hps, &po);
         GpiEndPath(dev->hps);
         if (filled)
            GpiFillPath(dev->hps, 1, FPATH_WINDING);
         else
            GpiOutlinePath(dev->hps, 1, 0);
      }
      else
      {
         POINTL pt[3];

//berechnen!
         pt[0].x = pt[0].y = 0;
         GpiMove(dev->hps, &pt[0]);
         pt[1].x = pt[1].y = 100;
         pt[2].x = 200;
         pt[2].y = 0;
         GpiPointArc(dev->hps, &pt[1]);
      }
   }
}
void XLine::Draw( XGraphicDevice * dev)
{
   if (!(settings & GO_HIDE))
   {
      POINTL po;
      po.x = p.x;
      po.y = p.y;
      SetupDevice(dev);
      GpiBeginPath(dev->hps, 1);
      GpiMove(dev->hps, &po);
      //POINTL ptl;// = po;

      po.x = p.x + width;
      po.y = p.y + height;
      GpiLine(dev->hps, &po);
      GpiEndPath(dev->hps);
      GpiOutlinePath(dev->hps, 1, 0);
   }
}
/*----------------------------------------------------------------------*/
VOID DrawLine(WINDOWINFO *pwi,POINTL ptlSt,POINTL ptlE, short mode,POBJECT pObj)
{
   pLines pLin;

   if (pObj && pObj->usClass == CLS_LIN)
      pLin = (pLines)pObj;
   else
      pLin = (pLines)0;

   if ( mode == CREATEMODE)
      GpiSetMix(pwi->hps,FM_INVERT);
   else
   {
      GpiSetMix(pwi->hps,FM_DEFAULT);
      GpiSetColor(pwi->hps,pwi->ulOutLineColor);
      GpiSetLineType(pwi->hps,pwi->lLntype);
   }

  if ( mode != CREATEMODE && pwi->lLnWidth > 1)
  {
     GpiSetPattern(pwi->hps,PATSYM_SOLID);
     GpiSetLineJoin(pwi->hps,pwi->lLnJoin);
     GpiSetLineEnd(pwi->hps,pwi->lLnEnd);
     GpiSetLineWidthGeom (pwi->hps,pwi->lLnWidth);
     GpiBeginPath( pwi->hps, 1L);
  }

  GpiMove(pwi->hps,&ptlSt);
  GpiLine(pwi->hps,&ptlE);

  if ( mode != CREATEMODE && pwi->lLnWidth > 1)
  {
     GpiEndPath(pwi->hps);
     GpiStrokePath (pwi->hps, 1, 0);
  }
  
  if (pLin)
     drwEndPoints(pwi,pLin->bt.arrow,ptlSt,ptlE);
  else
     drwEndPoints(pwi,pwi->arrow,ptlSt,ptlE);
}
/*------------------------------------------------------------------------*/
VOID LineMoving(POBJECT pObj,WINDOWINFO *pwi,SHORT dx, SHORT dy)
{
   POINTL ptl1;
   POINTL ptl2;
   pLines pLin = (pLines)pObj;

   ptl1.x = (LONG)(pLin->ptl1.x * pwi->usFormWidth ) + (LONG)dx;
   ptl1.y = (LONG)(pLin->ptl1.y * pwi->usFormHeight) + (LONG)dy;
   ptl1.x += (LONG)pwi->fOffx;
   ptl1.y += (LONG)pwi->fOffy;
   GpiMove(pwi->hps, &ptl1);

   ptl2.x = (LONG)(pLin->ptl2.x * pwi->usFormWidth ) + (LONG)dx;
   ptl2.y = (LONG)(pLin->ptl2.y * pwi->usFormHeight) + (LONG)dy;
   ptl2.x += (LONG)pwi->fOffx;
   ptl2.y += (LONG)pwi->fOffy;
   GpiLine(pwi->hps,&ptl2);

   drwEndPoints(pwi,pLin->bt.arrow,ptl1,ptl2);
   return;   
}
static void draw ( IPresSpaceHandle hps,
                   IListBox *lb, 
                   const TgtLocation &target )
  {
  if ( target.index != nil )
    {
    // First, get offset from top of listbox:
    unsigned
      offset = target.index - lb->top() + 1,
      height = ListBoxItem::itemHeight( lb );
    // Next, adjust if before this item:
    if ( target.type == ListBoxItem::before )
      offset--;
    // Calculate that item's rectangle's bottom:
    unsigned
      bottom = lb->rect().height() - height * offset;
    // Lower 2 pels 'cause it looks better!
    bottom -= 2;
    // Draw line or box:
    IPoint
      origin( 0, bottom );
    if ( target.type == ListBoxItem::on )
      {
      IPoint
        topRight( lb->rect().width(), bottom + height );
      origin += 1;
      topRight -= IPoint( WinQuerySysValue( HWND_DESKTOP,
                                            SV_CXVSCROLL ) + 1, 1 );
      GpiMove( hps, PPOINTL( &origin ) );
      GpiBox( hps, DRO_OUTLINE, PPOINTL( &topRight ), 0, 0 );
      }
    else
      {
      IPoint
        end( lb->rect().width(), bottom );
      GpiMove( hps, PPOINTL( &origin ) );
      GpiLine( hps, PPOINTL( &end ) );
      }
    }
  }
/*------------------------------------------------------------------------*/
VOID * LineSelect(POINTL ptlMouse,WINDOWINFO *pwi, POBJECT pObj)
{
   pLines pLin = (pLines)pObj;
   POINTL ptl;

   if (pLin->bt.usLayer == pwi->uslayer || pwi->bSelAll)
   {
      ptl.x = (LONG)(pLin->ptl1.x * pwi->usFormWidth );
      ptl.y = (LONG)(pLin->ptl1.y * pwi->usFormHeight);
      ptl.x += (LONG)pwi->fOffx;
      ptl.y += (LONG)pwi->fOffy;

      GpiMove(pwi->hps, &ptl);
      ptl.x = (LONG)(pLin->ptl2.x * pwi->usFormWidth );
      ptl.y = (LONG)(pLin->ptl2.y * pwi->usFormHeight);
      ptl.x += (LONG)pwi->fOffx;
      ptl.y += (LONG)pwi->fOffy;

      if (GpiLine(pwi->hps,&ptl) == GPI_HITS)
            return (void *)pLin;
   }
   return (void *)0;
}
Exemple #19
0
MRESULT EXPENTRY ToolBarProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) {
    if (msg == WM_CREATE) {
        WinSetWindowPtr(hwnd, QWL_USER, PVOIDFROMMP(mp1));
    } else {
        ToolBarData *td = (ToolBarData *)WinQueryWindowPtr(hwnd, QWL_USER);
        ToolBarItem *items = td->pItems;

        switch (msg) {
        case WM_DESTROY:
            free(td);
            free(items);
            break;

        case WM_PAINT:
        {
            HPS hps;
            RECTL rcl;
            POINTL ptl;
            SWP swp;
            int xpos, ypos, item;

            WinQueryWindowPos(hwnd, &swp);

            hps = WinBeginPaint(hwnd, 0, &rcl);

            /* top outside 3D border */
            if (rcl.yBottom < 1) {
                GpiSetColor(hps, CLR_DARKGRAY);
                ptl.x = rcl.xLeft;
                ptl.y = 0;
                GpiMove(hps, &ptl);
                ptl.x = Min(rcl.xRight, swp.cx - 2);
                GpiLine(hps, &ptl);
            }

            /* bottom outside 3D border */
            if (rcl.yTop >= swp.cy - 1 - 1) {
                GpiSetColor(hps, CLR_WHITE);
                ptl.x = Max(rcl.xLeft, 1);
                ptl.y = swp.cy - 1;
                GpiMove(hps, &ptl);
                ptl.x = rcl.xRight;
                GpiLine(hps, &ptl);
            }

            /* 3D corners */
            GpiSetColor(hps, CLR_PALEGRAY);
            ptl.x = 0;
            ptl.y = 0;
            GpiSetPel(hps, &ptl);
            ptl.x = swp.cx - 1;
            ptl.y = swp.cy - 1;
            GpiSetPel(hps, &ptl);

            /* bottom space */
            if (rcl.yBottom < TYBORDER - 1) {
                for (ptl.y = 1; ptl.y < TYBORDER - 2; ptl.y++) {
                    ptl.x = Max(rcl.xLeft, 1);
                    GpiMove(hps, &ptl);
                    ptl.x = Min(rcl.xRight, swp.cx - 1);
                    GpiLine(hps, &ptl);
                }
            }

            /* top space */
            if (rcl.yTop >= swp.cy - TYBORDER + 2) {
                for (ptl.y = swp.cy - TYBORDER + 2; ptl.y < swp.cy - 1; ptl.y++) {
                    ptl.x = Max(rcl.xLeft, 1);
                    GpiMove(hps, &ptl);
                    ptl.x = Min(rcl.xRight, swp.cx - 1);
                    GpiLine(hps, &ptl);
                }
            }

            /* left outside 3D border */
            if (rcl.xLeft < 1) {
                GpiSetColor(hps, CLR_WHITE);
                ptl.y = Max(1, rcl.yBottom);
                ptl.x = 0;
                GpiMove(hps, &ptl);
                ptl.y = rcl.yTop;
                GpiLine(hps, &ptl);
            }

            /* right outside 3D border */
            if (rcl.xRight >= swp.cx - 1) {
                GpiSetColor(hps, CLR_DARKGRAY);
                ptl.y = rcl.yBottom;
                ptl.x = swp.cx - 1;
                GpiMove(hps, &ptl);
                ptl.y = Min(swp.cy - 2, rcl.yTop);
                GpiLine(hps, &ptl);
            }

            /* left border */
            if (rcl.xLeft < TXBORDER - 2) {
                GpiSetColor(hps, CLR_PALEGRAY);
                for (ptl.x = 1; ptl.x < TXBORDER - 2; ptl.x++) {
                    ptl.y = Max(1, rcl.yBottom);
                    GpiMove(hps, &ptl);
                    ptl.y = Min(swp.cy - 2, rcl.yTop);
                    GpiLine(hps, &ptl);
                }
            }

            /* draw toolbar items */
            xpos = TXBORDER;
            ypos = TYBORDER;

            for (item = 0; item < td->ulCount; item++) {
                if (items[item].ulType == tiBITMAP) {
                    if (rcl.xRight >= xpos - 2 && rcl.xLeft <= xpos + TXICON + 1) {
                        GpiSetColor(hps, CLR_BLACK);
                        ptl.x = xpos - 2;
                        ptl.y = ypos - 2;
                        GpiMove(hps, &ptl);
                        ptl.x = xpos + TXICON + 1;
                        ptl.y = ypos + TYICON + 1;
                        GpiBox(hps, DRO_OUTLINE, &ptl, 0, 0);
                        if (item == td->ulDepressed && (items[item].ulFlags & tfDEPRESSED)) {
                            ptl.x = xpos + 1;
                            ptl.y = ypos - 1;
                            WinDrawBitmap(hps,
                                          items[item].hBitmap,
                                          0,
                                          &ptl,
                                          0, 0,
                                          (items[item].ulFlags & tfDISABLED) ? DBM_INVERT: DBM_NORMAL);

                            GpiSetColor(hps, CLR_DARKGRAY);
                            ptl.x = xpos - 1;
                            ptl.y = ypos - 1;
                            GpiMove(hps, &ptl);
                            ptl.y = ypos + TYICON;
                            GpiLine(hps, &ptl);
                            ptl.x = xpos + TXICON;
                            GpiLine(hps, &ptl);
                            ptl.y--;
                            GpiMove(hps, &ptl);
                            ptl.x = xpos;
                            GpiLine(hps, &ptl);
                            ptl.y = ypos - 1;
                            GpiLine(hps, &ptl);
                        } else {
                            ptl.x = xpos;
                            ptl.y = ypos;
                            WinDrawBitmap(hps,
                                          items[item].hBitmap,
                                          0,
                                          &ptl,
                                          0, 0,
                                          (items[item].ulFlags & tfDISABLED) ? DBM_INVERT: DBM_NORMAL);

                            GpiSetColor(hps, CLR_PALEGRAY);
                            ptl.x = xpos - 1;
                            ptl.y = ypos - 1;
                            GpiSetPel(hps, &ptl);
                            GpiSetColor(hps, CLR_WHITE);
                            ptl.y++;
                            GpiMove(hps, &ptl);
                            ptl.y = ypos + TYICON;
                            GpiLine(hps, &ptl);
                            ptl.x = xpos + TXICON - 1;
                            GpiLine(hps, &ptl);
                            GpiSetColor(hps, CLR_PALEGRAY);
                            ptl.x++;
                            GpiSetPel(hps, &ptl);
                            ptl.y--;
                            GpiSetColor(hps, CLR_DARKGRAY);
                            GpiMove(hps, &ptl);
                            ptl.y = ypos - 1;
                            GpiLine(hps, &ptl);
                            ptl.x = xpos;
                            GpiLine(hps, &ptl);
                        }
                    }
                    xpos += TXICON + 3;
                } else if (items[item].ulType == tiSEPARATOR) {
                    if (rcl.xRight >= xpos - 1 && rcl.xLeft <= xpos + TXSEPARATOR + 1) {
                        GpiSetColor(hps, CLR_PALEGRAY);
                        ptl.x = xpos - 1;
                        ptl.y = ypos - 2;
                        GpiMove(hps, &ptl);
                        ptl.x = xpos + TXSEPARATOR + 1;
                        ptl.y = ypos + TYICON + 1;
                        GpiBox(hps, DRO_FILL, &ptl, 0, 0);
                    }
                    xpos += TXSEPARATOR + 3;
                }
            }
            GpiSetColor(hps, CLR_PALEGRAY);
            ptl.x = xpos - 1;
            ptl.y = ypos - 2;
            GpiMove(hps, &ptl);
            ptl.x = swp.cx - 2;
            ptl.y = swp.cy - TYBORDER + 1;
            GpiBox(hps, DRO_FILL, &ptl, 0, 0);

            WinEndPaint(hps);
        }
        break;

        case WM_ADJUSTWINDOWPOS:
        {
            PSWP pswp = (PSWP)PVOIDFROMMP(mp1);
            pswp->cy = TYBORDER + TYICON + TYBORDER;
        }
        break;

        case WM_BUTTON1DOWN:
        case WM_BUTTON1DBLCLK:
        {
            int item;
            POINTL ptl;
            RECTL rcl;

            ptl.x = (LONG) SHORT1FROMMP(mp1);
            ptl.y = (LONG) SHORT2FROMMP(mp1);

            rcl.yBottom = TYBORDER - 1;
            rcl.yTop = TYBORDER + TYICON + 1;
            rcl.xLeft = TXBORDER - 1;
            rcl.xRight = TXBORDER + TXICON + 1;

            for (item = 0; item < td->ulCount; item++) {
                if (rcl.xLeft <= ptl.x && rcl.yBottom <= ptl.y &&
                        rcl.xRight >= ptl.x && rcl.yTop >= ptl.y &&
                        td->pItems[item].ulType == tiBITMAP &&
                        (td->pItems[item].ulFlags & tfDISABLED) == 0)
                {
                    td->ulDepressed = item;
                    td->pItems[item].ulFlags |= tfDEPRESSED;
                    WinInvalidateRect(hwnd, &rcl, FALSE);
                    WinSetCapture(HWND_DESKTOP, hwnd);
                    break;
                }
                if (td->pItems[item].ulType == tiBITMAP) {
                    rcl.xLeft += TXICON + 3;
                    rcl.xRight += TXICON + 3;
                } else if (td->pItems[item].ulType == tiSEPARATOR) {
                    rcl.xLeft += TXSEPARATOR + 3;
                    rcl.xRight += TXSEPARATOR + 3;
                }
            }
        }
        break;

        case WM_MOUSEMOVE:
        {
            STARTFUNC("ToolBarProc[WM_MOUSEMOVE]");
            int item;
            POINTL ptl;
            RECTL rcl;

            if (td->ulDepressed == -1)
                break;

            ptl.x = (LONG) SHORT1FROMMP(mp1);
            ptl.y = (LONG) SHORT2FROMMP(mp1);

            rcl.yBottom = TYBORDER - 1;
            rcl.yTop = TYBORDER + TYICON + 1;
            rcl.xLeft = TXBORDER - 1;
            rcl.xRight = TXBORDER + TXICON + 1;

            LOG << "Depressed: " << td-> ulDepressed << ENDLINE;
            for (item = 0; item < td->ulCount; item++) {
                LOG << "Checking item " << item << ENDLINE;
                LOG << "  pItem -> " << (void*)(td->pItems + item) << ENDLINE;
                if (item == td->ulDepressed) {
                    if (rcl.xLeft <= ptl.x && rcl.yBottom <= ptl.y &&
                            rcl.xRight >= ptl.x && rcl.yTop >= ptl.y)
                    {
                        if ((td->pItems[item].ulFlags & tfDEPRESSED) == 0) {
                            td->pItems[item].ulFlags |= tfDEPRESSED;
                            WinInvalidateRect(hwnd, &rcl, FALSE);
                        }
                    } else {
                        if (td->pItems[item].ulFlags & tfDEPRESSED) {
                            td->pItems[item].ulFlags &= ~tfDEPRESSED;
                            WinInvalidateRect(hwnd, &rcl, FALSE);
                        }
                    }
                    break;
                }
                if (td->pItems[item].ulType == tiBITMAP) {
                    rcl.xLeft += TXICON + 3;
                    rcl.xRight += TXICON + 3;
                } else if (td->pItems[item].ulType == tiSEPARATOR) {
                    rcl.xLeft += TXSEPARATOR + 3;
                    rcl.xRight += TXSEPARATOR + 3;
                }
            }
        }
        break;

        case WM_BUTTON1UP:
        {
            int item;
            POINTL ptl;
            RECTL rcl;

            if (td->ulDepressed == -1)
                break;

            ptl.x = (LONG) SHORT1FROMMP(mp1);
            ptl.y = (LONG) SHORT2FROMMP(mp1);

            rcl.yBottom = TYBORDER - 1;
            rcl.yTop = TYBORDER + TYICON + 1;
            rcl.xLeft = TXBORDER - 1;
            rcl.xRight = TXBORDER + TXICON + 1;

            for (item = 0; item < td->ulCount; item++) {
                if (item == td->ulDepressed) {
                    WinSetCapture(HWND_DESKTOP, (HWND)0);
                    if (rcl.xLeft <= ptl.x && rcl.yBottom <= ptl.y &&
                            rcl.xRight >= ptl.x && rcl.yTop >= ptl.y &&
                            td->pItems[item].ulFlags & tfDEPRESSED)
                    {
                        td->pItems[item].ulFlags &= ~tfDEPRESSED;
                        WinInvalidateRect(hwnd, &rcl, FALSE);

                        // message
                        WinPostMsg(WinQueryWindow(hwnd, QW_OWNER), WM_COMMAND, MPFROM2SHORT(td->pItems[item].ulCommand, 0), MPFROM2SHORT(CMDSRC_OTHER, TRUE));

                        break;
                    }
                }
                if (td->pItems[item].ulType == tiBITMAP) {
                    rcl.xLeft += TXICON + 3;
                    rcl.xRight += TXICON + 3;
                } else if (td->pItems[item].ulType == tiSEPARATOR) {
                    rcl.xLeft += TXSEPARATOR + 3;
                    rcl.xRight += TXSEPARATOR + 3;
                }
            }
            td->ulDepressed = -1;
        }
        break;
        }
    }
    return WinDefWindowProc(hwnd, msg, mp1, mp2);
}
MRESULT EXPENTRY WndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
//	static POINTS DragStartPtrPos;
    POINTL ptl;
    static char Row, Col;
    static BOOL HasMoved = FALSE;
    static BOOL IntroSoundPlayed = FALSE;
    static BOOL RealPaint = TRUE;           // indicates whether the board
				// has to be repainted or just copied
    INT aktscan;
    CHAR msgtext[256];
    ULONG ulResponse;
//	ERRORID errId;

	
    switch( msg ){
    case WM_CREATE:
	if( !InfoData.LoadHigh() ){	// get previously saved highscores
	    InfoData.ResetHigh();
	    WinMessageBox( HWND_DESKTOP, hwndMain,
			   "The file scores.dat " \
			   "(which is in the current directory) was somehow corrupted." \
			   " All Highscores will be reset to Zero.",
			   "Error when loading Highscores",
			   0, MB_OK | MB_INFORMATION );
	}

	// allocate memory for global variables; see GLOBALS struct in tgraph.h
	pg = new GLOBALS;
	// initialize globals to zero
	memset( pg, 0, sizeof( GLOBALS ));
	// store globals pointer into client window words; see WinRegisterClass
//    WinSetWindowULong( hwnd, QWL_USER, (ULONG) pg );

    wcprintf("1: %x", WinGetLastError( hab ) );
	DosCreateEventSem( NULL, &hevWaitAfterScan, 0, FALSE );
				// Sem is created in reset state
	DosCreateEventSem( NULL, &hevHiScoreWin, 0, FALSE );
	DosCreateEventSem( NULL, &hevWaitAfterSound, 0, FALSE );
	DosCreateEventSem( NULL, &hevWaitSoundReady, 0, TRUE );
				// Sem is created in posted state
	// hevWaitAfterScan and hewWaitAfterSound are used to indicate
	// when the respective WM_CREATE routines are done.
	// after that they are in posted state, as desired
            
	// initialize globals with important data
	pg->hab          = hab;
	pg->hwndClient   = hwnd;
	pg->hwndFrame    = WinQueryWindow( hwnd, QW_PARENT );
	pg->hwndTitlebar = WinWindowFromID( pg->hwndFrame, FID_TITLEBAR );
	pg->hwndMenubar  = WinWindowFromID( pg->hwndFrame, FID_MENU );
	// create graphics and sound threads
	pg->tidTSound = _beginthread( &threadsound, NULL, LEN_STACK, NULL );
	pg->tidTGraph = _beginthread( &threadgraph, NULL, LEN_STACK, NULL );
	DosWaitEventSem( hevWaitAfterSound, SEM_INDEFINITE_WAIT );
	WinPostMsg( pg->hwndTSound, WM_SOUND_INTRO, MPFROMHWND(hwnd), 0 );
	// wait for the sound's WM_CREATE
	DosWaitEventSem( hevWaitAfterScan, SEM_INDEFINITE_WAIT );
	// wait for the graphics' WM_CREATE
	InfoData.ShipsNotFound = GBoard.GetShipNumber();
	wcprintf("create: %x", WinGetLastError( hab ) );
	return (MRESULT)0;
			
    case WM_CONTROL:
	break;
    case WM_QUIT:
	break;
			
    case WM_CLOSE:	// this message is sent before WM_QUIT
	InfoData.SaveHigh( WinGetCurrentTime(hab) );
				// save the highscores and provide a random seed
	// get pointer to globals from window words
//    pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
	// tell object windows to quit, then exit their threads
//			WinSendMsg( pg->hwndTGraph, WM_DESTROY, mp1, mp2 );
	WinPostMsg( pg->hwndTGraph, WM_QUIT, mp1, mp2 );
//			WinSendMsg( pg->hwndTSound, WM_DESTROY, mp1, mp2 );
	WinPostMsg( pg->hwndTSound, WM_QUIT, mp1, mp2 );
	DosCloseEventSem( hevWaitAfterScan );
	DosCloseEventSem( hevHiScoreWin );
	DosCloseEventSem( hevWaitAfterSound );
	DosCloseEventSem( hevWaitSoundReady );
	WriteProfile( hab );
	delete pg;
	return (MRESULT) 0;
	
    case WM_ERASEBACKGROUND:
	wcprintf("erasebackground");        
//	return (MRESULT) FALSE;
	return (MRESULT) TRUE;

    case WM_PAINT:
///////////////////////////////////
	    {
		RECTL rectl;
		WinQueryWindowRect( pg->hwndClient, &rectl );
wcprintf("Linienrechteck: Breite: %d H”he: %d", rectl.xRight, rectl.yTop );
		// test size:
		GpiSetColor( hpsGlob, CLR_RED );
		ptl.x = rectl.xLeft; ptl.y = rectl.yBottom;
		GpiMove( hpsGlob, &ptl );
		ptl.x = rectl.xRight; ptl.y = rectl.yTop;
		GpiLine( hpsGlob, &ptl );
	    }
///////////////////////////
	break;

    case WM_SIZE:
	wcprintf("main wnd function wm-size");
	RealPaint = TRUE;
	GBoard.SetPMBoardValues( SHORT1FROMMP( mp2 ), SHORT2FROMMP( mp2 ) );
	WndResize( hwnd );
	wcprintf("size: %x", WinGetLastError( hab ) );
	break;
			
    case WM_BEGINDRAG:
	WinSetCapture( HWND_DESKTOP, hwnd );	// capture the mouse pointer
	GBoard.SetfDrag( TRUE );	// indicate that mouse is being dragged
	GBoard.ResetFirstDraw();	// for initialization of drag op.
	fHideSquare = TRUE;
	WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
		    MPFROM2SHORT( 0, 0 ) );
//			GBoard.ShowPointerPos( hwnd, 0, 0 ); // removes the square
	ptl.x = SHORT1FROMMP(mp1);
	ptl.y = SHORT2FROMMP(mp1);
	Row = GBoard.GetBoardRow( ptl.y );	// starting point of drag
	Col = GBoard.GetBoardCol( ptl.x );	// operation; static!
	return (MRESULT)TRUE;
			
    case WM_MOUSEMOVE:
	if( GBoard.GetfDrag() ){	// if mouse is being dragged
	    WinSendMsg( pg->hwndTGraph, WM_DRAWDRAGLINE, mp1,
			MPFROM2SHORT( Row, Col ) );
	    HasMoved = TRUE;
	} else {		// mouse is moved normally
	    if( !fHideSquare )
		WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
			    mp1 );
//					GBoard.ShowPointerPos( hwnd, SHORT1FROMMP(mp1),
//														  SHORT2FROMMP(mp1));
	}
	break;	
    case WM_ENDDRAG:
	WinSetCapture( HWND_DESKTOP, NULLHANDLE ); // release the captured
				// mouse pointer
	if( HasMoved ){	// mousemove has actually been moved
	    WinSendMsg( pg->hwndTGraph, WM_MARKDRAGLINE,
			MPFROM2SHORT( Row, Col ), 0 );
	    HasMoved = FALSE;
	}
	GBoard.SetfDrag( FALSE );
	GBoard.ClearDrawPoint();	// because no square is drawn right now
	fHideSquare = FALSE;
	WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
		    mp1 );
//			GBoard.ShowPointerPos( hwnd, SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));
				// draws square at the current ptr pos
	break;
			
    case WM_CHAR:	// key was pressed
	if( SHORT2FROMMP( mp2 ) != VK_SPACE ) break;	// only space is interesting
	if( GBoard.GetfDrag() ) break;	// do nothing while dragging
	if( !GBoard.GetfShowLines() ){	// lines not visible yet
	    GBoard.SetfShowLines( TRUE );
	    WinSendMsg( pg->hwndTGraph, WM_DISPLAYLINES, 0, 0 );
	}
	break;
			
    case WM_BUTTON1CLICK:
	if( !InfoData.ShipsNotFound ) break;	// game is finished
	ptl.x = (LONG)SHORT1FROMMP( mp1 );
	ptl.y = (LONG)SHORT2FROMMP( mp1 );
	Row = GBoard.GetBoardRow( ptl.y );
	Col = GBoard.GetBoardCol( ptl.x );
	if( !Row || !Col ) break;
	fHideSquare = TRUE;
	WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
		    MPFROM2SHORT( 0, 0 ) );
//			GBoard.ShowPointerPos( hwnd, 0, 0 );	// hides pointer square
	if(( aktscan = GBoard.GetDiscovered( Row, Col )) != -1 ){
	    WinSendMsg( pg->hwndTGraph, WM_DRAWPMPLACE, MPFROMHWND(hwnd),
			MPFROMSH2CH( MAKESHORT(Row, Col),
				     (CHAR)aktscan,(CHAR)TRUE));
// umstricken auf WinPostMsg												 
				// toggle Place display
	} else {	// scan Place
	    DosResetEventSem( hevWaitAfterScan, &ulResponse );
// DosBeep(500, 150 );				
	    WinPostMsg( pg->hwndTGraph, WM_GRAPH_SCAN, MPFROMHWND(hwnd),
			MPFROM2SHORT( Row, Col ) );
// DosBeep( 800, 150 );								
	    WinWaitEventSem( hevWaitAfterScan, SEM_INDEFINITE_WAIT );
// DosBeep( 1000, 150 );				
				// first the scanning sounds must be played (and finished)
	    aktscan = GBoard.Scan( Row, Col );
	    if( aktscan == GBoard.GetShipNumber() + 10 ){
		InfoData.ShipsNotFound--;
		WinPostMsg( pg->hwndTSound, WM_SOUND_FOUNDSHIP, MPFROMHWND(hwnd), 0 );
	    } else {
		if( aktscan )
		    WinPostMsg( pg->hwndTSound, WM_SOUND_FOUND,
				MPFROMHWND(hwnd), MPFROMLONG( aktscan ) );
		else	
		    WinPostMsg( pg->hwndTSound, WM_SOUND_FOUND0, MPFROMHWND(hwnd), 0 );
	    }
	    WinWaitEventSem( hevWaitAfterScan, SEM_INDEFINITE_WAIT );
				// waits until scanning is done, and only then displays the
				// field icon
//				hps = WinGetPS( hwnd );
	    WinSendMsg( pg->hwndTGraph, WM_DRAWPMPLACE, MPFROMHWND(hwnd),
			MPFROMSH2CH( MAKESHORT(Row, Col),
				     (CHAR)aktscan,(CHAR)TRUE));
// umstricken auf WinPostMsg
	    WinPostMsg( pg->hwndTGraph, WM_SHOWSTATUSLINE, 0, 0 );
				
//				ShowStatusLine( hps, GBoard.MovesNeeded(), InfoData.ShipsNotFound,
//									 GBoard.GetWinWidth(), GBoard.GetWinHeight() );
//				WinReleasePS( hps );
	    if( !InfoData.ShipsNotFound ){	// game is finished, all ships found
		Score = GBoard.MovesNeeded();
		if	( !InfoData.ReturnLastHigh()	// still space in the hiscore table
		|| Score < InfoData.ReturnLastHigh() ){	// player kicks last one out
				// player enters highscore table
		    WinPostMsg( pg->hwndTSound, WM_SOUND_NEWHISCORE, MPFROMHWND(hwnd), 0 );
		    WinWaitEventSem( hevHiScoreWin, SEM_INDEFINITE_WAIT );
				// waits until the NEWHISCORE sound is actually played
		    WinDlgBox( HWND_DESKTOP, hwnd, HighScoreDlgProc, (HMODULE)0,
			       IDR_HIGHSCOREDLG, NULL );
		    WinPostMsg( hwnd, WM_COMMAND,
				MPFROMSHORT(IDM_GAMEHIGH), (MPARAM)0 );
				// show highscore-table
		    DosResetEventSem( hevHiScoreWin, &ulResponse ); // resets the sem again
		} else {
		    WinPostMsg( pg->hwndTSound, WM_SOUND_LOST, MPFROMHWND(hwnd), 0 );
		    WinWaitEventSem( hevHiScoreWin, SEM_INDEFINITE_WAIT );
				// waits until the NEWHISCORE sound is actually played
		    sprintf( msgtext,
			     "You needed %d moves to find the lost ships. " \
			     "To enter the highscore list you need %d moves." \
			     " So try again!", Score, InfoData.ReturnLastHigh() - 1 );
		    WinMessageBox( HWND_DESKTOP, hwnd, msgtext, "Oh, Shit!", 0,
				   MB_OK | MB_INFORMATION | MB_HELP );
		}
	    }
	}
	fHideSquare = FALSE;
	WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
		    MPFROM2SHORT( ptl.x, ptl.y ) );
//			GBoard.ShowPointerPos( hwnd, ptl.x, ptl.y ); // redisplay ptr square
	break;
			
    case WM_BUTTON2CLICK:
	fHideSquare = TRUE;
	WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
		    MPFROM2SHORT( 0, 0 ) );
	ptl.x = (LONG)SHORT1FROMMP( mp1 );
	ptl.y = (LONG)SHORT2FROMMP( mp1 );
	Row = GBoard.GetBoardRow( ptl.y );
	Col = GBoard.GetBoardCol( ptl.x );
	WinSendMsg( pg->hwndTGraph, WM_DRAWPMMARK, MPFROMHWND(hwnd),
		    MPFROM2SHORT( Row, Col ) );
	fHideSquare = FALSE;
	WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
		    MPFROM2SHORT( ptl.x, ptl.y ) );
	break;
			
    case WM_COMMAND:
	switch( SHORT1FROMMP( mp1 ) ){
	case IDM_GAMENEW:
	    GBoard.NewGame();
	    InfoData.ShipsNotFound = GBoard.GetShipNumber();
	    RealPaint = TRUE;
	    WinInvalidateRect( hwnd, NULL, TRUE );
	    break;
	case IDM_GAMESETTINGS:
	    if( WinDlgBox( HWND_DESKTOP, hwndFrame,
			   GameSettingsDlgProc, (HMODULE)0,
			   IDR_GAMESETTINGSDLG, NULL ) ){
				// screen must be repainted
		RealPaint = TRUE;
		WinInvalidateRect( hwnd, NULL, TRUE );
	    }
	    break;
	case IDM_GAMEHIGH:
	    if( !WinDlgBox( HWND_DESKTOP, hwndFrame,
			    ShowHighDlgProc, (HMODULE)0,
			    IDR_SHOWHIGHDLG, NULL ) ){	// user requested "Clear"
		if( WinMessageBox( HWND_DESKTOP, hwndMain,
				   "Do you really want to eradicate all those " \
				   "arduously achieved highscores?",
				   "Clear Highscores",
				   0, MB_OKCANCEL | MB_WARNING ) == MBID_OK )
		    InfoData.ResetHigh();
	    }
	    break;
					
	case IDM_HELPINDEX:	// help index
	    WinSendMsg( hwndHelp, HM_HELP_INDEX, 0, 0 );
	    break;
					
	case IDM_HELPGENERAL:	// general help
	    WinSendMsg( hwndHelp, HM_EXT_HELP, 0, 0 );
	    break;
					
	case IDM_HELPEXTENDED:	// help on help (system page)
	    WinSendMsg( hwndHelp, HM_DISPLAY_HELP, 0, 0 );
	    break;
					
	case IDM_HELPKEYS:	// keys help
	    WinSendMsg( hwndHelp, HM_KEYS_HELP, 0, 0 );
	    break;
					
	
	case IDM_HELPPRODUCTINFO:
	    ulResponse = WinDlgBox( HWND_DESKTOP, hwndFrame,
				    ProdInfoDlgProc, (HMODULE)0,
				    IDR_PRODINFODLG, NULL );
	    break;		
	}
	break;

    case HM_QUERY_KEYS_HELP:                // system asks which page to display
	return MRFROMSHORT( PANEL_HELPKEYS );
	      
    case HM_HELPSUBITEM_NOT_FOUND:
	return (MRESULT)FALSE;
			
    case WM_USER_ACK:	// graphics task finished its work
//         DosBeep( 1000, 150 );
	switch( (ULONG)mp1 ){
	case WM_USER_PAINT:
	    WinQueryPointerPos( HWND_DESKTOP, &ptl );
	    WinMapWindowPoints( HWND_DESKTOP, hwnd, &ptl, 1);
	    fHideSquare = FALSE;
	    WinSendMsg( pg->hwndTGraph, WM_SHOWPOINTERPOS, MPFROMHWND(hwnd),
			MPFROM2SHORT( ptl.x, ptl.y ) );
//					GBoard.ShowPointerPos( hwnd, ptl.x, ptl.y );
				// painting has finished, square can be displayed now
	    break;
	}
	break;	
    case WM_SOUND_ACK:
	switch( (ULONG)mp1 ){
	case WM_SOUND_INTRO:
	    break;
	}
	break;

			
    default:
	return (MRESULT)WinDefWindowProc( hwnd, msg, mp1, mp2 );
    }		// end switch( msg )
    return (MRESULT)WinDefWindowProc( hwnd, msg, mp1, mp2 );
}		// end MRESULT EXPENTRY WndProc()
/* 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);
}
MRESULT EXPENTRY newProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{

  switch (msg)
    {      
    case WM_CREATE:
      {
        PCREATESTRUCT pCreate=PVOIDFROMMP(mp2);

        /* Initialize the slider data */
        WinSetWindowUShort(hwnd, SLIDERARMWITH,20);
        WinSetWindowUShort(hwnd, SLIDERARMHEIGHT,10);
        /* Dimensions of slider. The slider active area is smaller than the window to
           allow drawing of active state. */
        WinSetWindowULong(hwnd, SLIDERCX,pCreate->cx-4);
        WinSetWindowULong(hwnd, SLIDERCY,pCreate->cy-4);
        WinSetWindowULong(hwnd, SLIDERX,2);
        WinSetWindowULong(hwnd, SLIDERY,2);
        WinSetWindowULong(hwnd, SLIDERARMPOS, 0);
        WinSetWindowULong(hwnd, SLDRAGGING,FALSE);
        return (MRESULT)0;
      }
    case WM_SIZE:
      WinSetWindowULong(hwnd, SLIDERCX, SHORT1FROMMP(mp2)-4);
      WinSetWindowULong(hwnd, SLIDERCY, SHORT2FROMMP(mp2)-4);
      WinInvalidateRect(hwnd, NULLHANDLE,TRUE);
      return (MRESULT)0;
    case WM_BUTTON1DOWN:
      {
        SHORT x=SHORT1FROMMP( mp1);
        SHORT y=SHORT2FROMMP( mp1);
        LONG  lPos=WinQueryWindowULong(hwnd, SLIDERARMPOS);
        USHORT usWidth=WinQueryWindowUShort(hwnd, SLIDERARMWITH);

        if(x<lPos+usWidth && y<WinQueryWindowUShort(hwnd, SLIDERY)+WinQueryWindowUShort(hwnd, SLIDERCY)
           && y>WinQueryWindowUShort(hwnd, SLIDERY)) {
          WinSetWindowUShort(hwnd, PTRPOSINSLARM, x-lPos);
        }
        WinSetFocus(HWND_DESKTOP, hwnd);
      break;
      }
    case WM_FOCUSCHANGE:
      {
        HPS hps;
        RECTL rcl;
        POINTL ptl;

        if(SHORT1FROMMP(mp2)) {
          hps=WinGetPS(hwnd);
          WinQueryWindowRect(hwnd, &rcl);        
          GpiSetLineType(hps, LINETYPE_DOT);
          ptl.x=rcl.xLeft;
          ptl.y=rcl.yBottom;
          GpiMove(hps,&ptl);
          ptl.x=rcl.xRight-1;
          GpiLine(hps,&ptl);
          ptl.y=rcl.yTop-1;
          GpiLine(hps,&ptl);
          ptl.x=rcl.xLeft;
          GpiLine(hps,&ptl);
          ptl.y=rcl.yBottom;
          GpiLine(hps,&ptl);
          WinReleasePS(hps);
        }
        else {
          WinInvalidateRect(hwnd, NULLHANDLE,TRUE);
        }

        break;
      }
    case WM_CHAR:
      if(WinQueryFocus(HWND_DESKTOP)==hwnd) {
        /* We have the focus */
        if((SHORT1FROMMP(mp1) & (KC_VIRTUALKEY))==(KC_VIRTUALKEY)) {
          LONG  lPos=WinQueryWindowULong(hwnd, SLIDERARMPOS);
          USHORT usWidth=WinQueryWindowUShort(hwnd, SLIDERARMWITH);
          ULONG ulCx=WinQueryWindowULong(hwnd, SLIDERCX);
#if 0
          FILE* file;
          file=fopen("d:\\md.log","a");
          fprintf(file,"0x%x 0x%x \n",SHORT1FROMMP(mp1),SHORT2FROMMP(mp1) );
          fclose(file);
#endif
          /*(KC_KEYUP|KC_PREVDOWN|KC_VIRTUALKEY)*/
          switch(SHORT2FROMMP(mp2))
            {
            case VK_RIGHT:

              if(SHORT1FROMMP(mp1) & (KC_KEYUP|KC_PREVDOWN)) {
                lPos+=2;
                if(lPos>ulCx-usWidth)
                  lPos=ulCx-usWidth;
                else {
                  WinPostMsg( hwnd,
                              SLM_SETSLIDERINFO,
                              MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_RANGEVALUE),
                              MPFROMLONG( (LONG) lPos ));
                  if(SHORT1FROMMP(mp1) & KC_LONEKEY)
                    /* Post SLN_CHANGE notification */
                    WinPostMsg( WinQueryWindow(hwnd, QW_PARENT),WM_CONTROL,
                                MPFROM2SHORT(WinQueryWindowUShort(hwnd, QWS_ID), SLN_CHANGE),
                                MPFROMLONG(lPos));
                  else
                    /* Post SLN_SLIDERTRACK notification */
                    WinPostMsg(WinQueryWindow(hwnd, QW_PARENT),WM_CONTROL,
                               MPFROM2SHORT(WinQueryWindowUShort(hwnd, QWS_ID), SLN_SLIDERTRACK),
                               MPFROMLONG(lPos));
                  
                }
                WinSetWindowULong(hwnd, SLIDERARMPOS, lPos);
              }
              return (MRESULT)TRUE;
            case VK_LEFT:
              if(SHORT1FROMMP(mp1) & (KC_KEYUP|KC_PREVDOWN)) {
                lPos-=2;
                if(lPos<0) {
                  lPos=0;
                }
                else {
                  WinPostMsg( hwnd,
                              SLM_SETSLIDERINFO,
                              MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_RANGEVALUE),
                              MPFROMLONG( (LONG) lPos ));
                  /* Post SLN_CHANGE notification */
                  WinPostMsg(WinQueryWindow(hwnd, QW_PARENT), WM_CONTROL,
                             MPFROM2SHORT(WinQueryWindowUShort(hwnd, QWS_ID), SLN_CHANGE),
                   MPFROMLONG(WinQueryWindowULong(hwnd, SLIDERARMPOS)));

                }
                WinSetWindowULong(hwnd, SLIDERARMPOS, lPos);
              }
              return (MRESULT)TRUE;
            default:
              break;
            }
        }
      }
      break;
    case WM_BUTTON1MOTIONSTART:
      {
        SHORT x=SHORT1FROMMP( mp1);
        SHORT y=SHORT2FROMMP( mp1);
        LONG  lPos=WinQueryWindowULong(hwnd, SLIDERARMPOS);
        USHORT usWidth=WinQueryWindowUShort(hwnd, SLIDERARMWITH);

        if(x<lPos+usWidth && y<WinQueryWindowUShort(hwnd, SLIDERY)+WinQueryWindowUShort(hwnd, SLIDERCY)
           && y>WinQueryWindowUShort(hwnd, SLIDERY)) {
          WinSetWindowULong(hwnd, SLDRAGGING, TRUE);
          WinSetCapture(HWND_DESKTOP, hwnd);
        }
        break;
      }
    case WM_BUTTON1MOTIONEND:
      if(WinQueryWindowULong(hwnd, SLDRAGGING)) {
        WinSetWindowULong(hwnd, SLDRAGGING,FALSE);
        WinSetCapture(HWND_DESKTOP, NULLHANDLE);
        /* Post SLN_CHANGE notification */
        WinPostMsg(WinQueryWindow(hwnd, QW_PARENT),WM_CONTROL, MPFROM2SHORT(WinQueryWindowUShort(hwnd, QWS_ID), SLN_CHANGE),
                   MPFROMLONG(WinQueryWindowULong(hwnd, SLIDERARMPOS)));
      }
      break;
    case SLM_SETSLIDERINFO:
      switch(SHORT1FROMMP(mp1))
        {
          case SMA_SLIDERARMPOSITION:
            /*  SMA_RANGEVALUE only for now !! */
            if(SHORT2FROMMP(mp1)==SMA_RANGEVALUE) {
              WinSetWindowULong(hwnd, SLIDERARMPOS, LONGFROMMP(mp2));
              WinInvalidateRect(hwnd, NULLHANDLE,TRUE);
              return (MRESULT)0;
            }
            break;
        default:
          break;
        }
      break;
    case WM_MOUSEMOVE:
      if(WinQueryWindowULong(hwnd, SLDRAGGING)) {
        HPS hps;
        RECTL rcl, rcl2, rcl3;
        LONG lTemp;
        SHORT x=SHORT1FROMMP(mp1);
        LONG  lPos=WinQueryWindowULong(hwnd, SLIDERARMPOS);
        USHORT usWidth=WinQueryWindowUShort(hwnd, SLIDERARMWITH);
       
        lTemp=lPos;
     
        rcl.xLeft=WinQueryWindowULong(hwnd, SLIDERX);
        rcl.yBottom=WinQueryWindowULong(hwnd, SLIDERY);
        rcl.xRight=rcl.xLeft+WinQueryWindowULong(hwnd, SLIDERCX);
        rcl.yTop=rcl.yBottom+WinQueryWindowULong(hwnd, SLIDERCY);

        rcl2=rcl3=rcl;
        rcl.xLeft=x-WinQueryWindowUShort(hwnd, PTRPOSINSLARM);
        if(rcl.xLeft<rcl2.xLeft)/* Make sure we stop at the left border */
          rcl.xLeft=rcl2.xLeft;

        rcl.xRight=rcl.xLeft+usWidth;
        if(rcl.xRight>rcl2.xRight)
          {/* Make sure we stop at the right border */
            rcl.xRight=rcl2.xRight;
            rcl.xLeft=rcl.xRight-usWidth;
          }
        lPos=rcl.xLeft-WinQueryWindowULong(hwnd, SLIDERX);/* Save position zero based */
        WinSetWindowULong(hwnd, SLIDERARMPOS, lPos);
        if(lPos!=lTemp) {
          BOOL rc;

          hps=WinGetPS(hwnd);
          /* Paint Background not necessary here */

          /* Shaft */
          /* Left part */
          rcl3.xRight=rcl.xLeft;
          rc=FALSE;
          if(USERSLIDER) {
            OWNERITEM oi={0};
            oi.hwnd=hwnd;
            oi.hps=hps;
            oi.fsState=SLS_OWNERDRAW;/* More to come */
            oi.rclItem=rcl3;
            oi.idItem=SDA_SLIDERSHAFT;
            rc=(BOOL)WinSendMsg(WinQueryWindow(hwnd, QW_PARENT), WM_DRAWITEM, MPFROMSHORT(WinQueryWindowUShort(hwnd, QWS_ID)),
                                MPFROMP(&oi) );
          }
          if(!rc)
            WinFillRect(hps, &rcl3, CLR_GREEN);

          /* Right part */
          rcl3.xRight=rcl2.xRight;
          rcl3.xLeft=rcl.xRight;
          rc=FALSE;
          if(USERSLIDER) {
            OWNERITEM oi={0};
            oi.hwnd=hwnd;
            oi.hps=hps;
            oi.fsState=SLS_OWNERDRAW;/* More to come */
            oi.rclItem=rcl3;
            oi.idItem=SDA_SLIDERSHAFT;
            rc=(BOOL)WinSendMsg(WinQueryWindow(hwnd, QW_PARENT), WM_DRAWITEM, MPFROMSHORT(WinQueryWindowUShort(hwnd, QWS_ID)),
                                MPFROMP(&oi) );
          }
          if(!rc)
            WinFillRect(hps, &rcl3, CLR_WHITE);

          /* Paint Slider */
          rc=FALSE;
          if(USERSLIDER) {
            OWNERITEM oi={0};
            oi.hwnd=hwnd;
            oi.hps=hps;
            oi.fsState=SLS_OWNERDRAW;/* More to come */
            oi.rclItem=rcl;
            oi.idItem=SDA_SLIDERARM;
            rc=(BOOL)WinSendMsg(WinQueryWindow(hwnd, QW_PARENT), WM_DRAWITEM, MPFROMSHORT(WinQueryWindowUShort(hwnd, QWS_ID)),
                                MPFROMP(&oi) );
          }
          if(!rc)
            {
              WinFillRect(hps,&rcl, CLR_BLUE);
              WinDrawBorder(hps, &rcl, 2, 2, 0, 0 ,0x0400);
            }

          WinReleasePS(hps);

          /* Post SLN_SLIDERTRACK notification */
          WinPostMsg(WinQueryWindow(hwnd, QW_PARENT),WM_CONTROL, MPFROM2SHORT(WinQueryWindowUShort(hwnd, QWS_ID), SLN_SLIDERTRACK),
                     MPFROMLONG(lPos));
        }
      }
      break;
    case WM_PAINT:
      {
        HPS hps, hps2;
        RECTL rcl, rcl2, rcl3;
        POINTL ptl;
        LONG  lPos=WinQueryWindowULong(hwnd, SLIDERARMPOS);
        USHORT usWidth=WinQueryWindowUShort(hwnd, SLIDERARMWITH);
        BOOL rc;

        WinQueryWindowRect(hwnd, &rcl);

        /* Shaft */
        rcl2.xLeft=WinQueryWindowULong(hwnd, SLIDERX);
        rcl2.yBottom=WinQueryWindowULong(hwnd, SLIDERY);
        rcl2.xRight=rcl2.xLeft+WinQueryWindowULong(hwnd, SLIDERCX)-1;
        rcl2.yTop=rcl2.yBottom+WinQueryWindowULong(hwnd, SLIDERCY)-1;

        /* Background */
        hps2=WinGetPS(hwnd);
        GpiExcludeClipRectangle(hps2,&rcl2);
        WinFillRect(hps2, &rcl, CLR_PALEGRAY);
        WinReleasePS(hps2);
        rcl2.yTop+=1;
        rcl2.xRight+=1;

        hps=WinBeginPaint(hwnd, NULLHANDLE, NULLHANDLE);
        /* Focus */
        if(WinQueryFocus(HWND_DESKTOP)==hwnd) {
          GpiSetLineType(hps, LINETYPE_DOT);
          ptl.x=rcl.xLeft;
          ptl.y=rcl.yBottom;
          GpiMove(hps,&ptl);
          ptl.x=rcl.xRight-1;
          GpiLine(hps,&ptl);
          ptl.y=rcl.yTop-1;
          GpiLine(hps,&ptl);
          ptl.x=rcl.xLeft;
          GpiLine(hps,&ptl);
          ptl.y=rcl.yBottom;
          GpiLine(hps,&ptl);
        }

        rcl3=rcl=rcl2;

        /* Arm pos */        
        rcl2.xLeft+=lPos;
        /* Arm size */        
        rcl2.xRight=rcl2.xLeft+usWidth;
        
        /* Shaft */
        /* Left part */
        rcl3.xRight=rcl2.xLeft;
        rc=FALSE;
        if(USERSLIDER) {
          OWNERITEM oi={0};
          oi.hwnd=hwnd;
          oi.hps=hps;
          oi.fsState=SLS_OWNERDRAW;/* More to come */
          oi.rclItem=rcl3;
          oi.idItem=SDA_SLIDERSHAFT;
          rc=(BOOL)WinSendMsg(WinQueryWindow(hwnd, QW_PARENT), WM_DRAWITEM, MPFROMSHORT(WinQueryWindowUShort(hwnd, QWS_ID)),
                    MPFROMP(&oi) );
        }
        if(!rc)
          WinFillRect(hps, &rcl3, CLR_GREEN);

        /* Right part */
        rcl3.xRight=rcl.xRight;
        rcl3.xLeft=rcl2.xRight;
        rc=FALSE;
        if(USERSLIDER) {
          OWNERITEM oi={0};
          oi.hwnd=hwnd;
          oi.hps=hps;
          oi.fsState=SLS_OWNERDRAW;/* More to come */
          oi.rclItem=rcl3;
          oi.idItem=SDA_SLIDERSHAFT;
          rc=(BOOL)WinSendMsg(WinQueryWindow(hwnd, QW_PARENT), WM_DRAWITEM, MPFROMSHORT(WinQueryWindowUShort(hwnd, QWS_ID)),
                              MPFROMP(&oi) );
        }
        if(!rc)
          WinFillRect(hps, &rcl3, CLR_WHITE);

        rc=FALSE;
        if(USERSLIDER) {
          OWNERITEM oi={0};
          oi.hwnd=hwnd;
          oi.hps=hps;
          oi.fsState=SLS_OWNERDRAW;/* More to come */
          oi.rclItem=rcl2;
          oi.idItem=SDA_SLIDERARM;
          rc=(BOOL)WinSendMsg(WinQueryWindow(hwnd, QW_PARENT), WM_DRAWITEM, MPFROMSHORT(WinQueryWindowUShort(hwnd, QWS_ID)),
                              MPFROMP(&oi) );
        }
        if(!rc)
          {
            WinFillRect(hps,&rcl2, CLR_BLUE);        
            WinDrawBorder(hps, &rcl2, 2, 2, 0, 0 ,0x0400);
          }

        WinEndPaint(hps);
        return (MRESULT)0;
      }
      break;
    default:
      break;
    }

  return WinDefWindowProc(hwnd, msg, mp1, mp2);
}
Exemple #23
0
MRESULT EXPENTRY tBarProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
  HENUM henum;
  RECTL rect;
  short height, i=0;
  HWND hwndHelp;
  char str[50];
  HPS hps;

  switch( msg )
  {
    case WM_CREATE:
    case WM_DESTROY:
    case WM_SIZE:
      break;

    case WM_COMMAND:
      WinSendMsg( WinQueryWindow( hwnd, QW_OWNER ), msg, mp1, mp2 );
      break;

    case TB_REDRAW:
      henum  = WinBeginEnumWindows( hwnd );

      while( (hwndHelp = WinGetNextWindow( henum )) != 0 )
      {
        WinSetWindowPos( hwndHelp, 0, i+2, 3, 0, 0, SWP_MOVE );
        WinQueryWindowRect( hwndHelp, &rect );
        i += rect.xRight;
      }

      break;

    case TB_ADDBUTTON:
      WinQueryWindowRect( hwnd, &rect );
      height = rect.yTop - rect.yBottom;

      sprintf( str, "#%ld", (ULONG)mp1 );

      hwndHelp = WinCreateWindow( hwnd, WC_BUTTON, str, WS_VISIBLE |
                                  BS_PUSHBUTTON | BS_BITMAP | BS_NOPOINTERFOCUS,
                                  0, 0, height-4, height-4,
                                  hwnd, HWND_BOTTOM, (ULONG)mp1, 0, NULL );

      oldButProc = WinSubclassWindow( hwndHelp, tButProc );

      WinPostMsg( hwnd, TB_REDRAW, 0, 0 );

      break;

    case TB_ADDSPACE:
      hwndHelp = WinCreateWindow( hwnd, WC_STATIC, NULL, !WS_VISIBLE,
                                  0, 0, (ULONG)mp1, 0,
                                  hwnd, HWND_BOTTOM, 0, 0, NULL );

      WinPostMsg( hwnd, TB_REDRAW, 0, 0 );

      break;

    case TB_SETBITMAP:
      sprintf( str, "#%ld", (ULONG)mp2 );
      hwndHelp = WinWindowFromID( hwnd, (USHORT)mp1 );
      WinSetWindowText( hwndHelp, (PSZ)str );
      WinPostMsg( hwnd, TB_REDRAW, 0, 0 );
      break;

    case TB_REMOVEBUTTONID:
      hwndHelp = WinWindowFromID( hwnd, (USHORT) mp1 );
      if( hwndHelp )
        WinDestroyWindow( hwndHelp );
      break;

    case TB_HWNDFROMID:
      return (MPARAM) WinWindowFromID( hwnd, (USHORT) mp1 );

    case WM_PAINT: {
      RECTL rcl;
      POINTL pt;

      HPS hps = WinBeginPaint( hwnd, 0, 0 );

      WinQueryWindowRect(hwnd,&rcl);
      WinFillRect( hps, &rcl, SYSCLR_BUTTONMIDDLE );

      pt.x = rcl.xLeft;
      pt.y = rcl.yBottom;
      GpiSetColor( hps, SYSCLR_BUTTONLIGHT );
      GpiMove( hps, &pt );
      pt.x = rcl.xRight - 1;
      GpiLine( hps, &pt );
      pt.x = rcl.xLeft;
      pt.y = rcl.yBottom + 1;
      GpiSetColor( hps, SYSCLR_BUTTONDARK );
      GpiMove( hps, &pt );
      pt.x = rcl.xRight - 1;
      GpiLine( hps, &pt );
      rcl.yBottom += 2;
      WinEndPaint( hps );
    }
    break;

    default:
      return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  }

  return FALSE;
}
Exemple #24
0
//Draw the Plugin effect into the given presentation space
BOOL CBZPluginRender(PSPAINT * pPaint, PVOID pData, short sActive)
{
    POINTL point;               //should allocate all this data dynamically, to keep it off

    int i, y;                   // the stack!!!

    FONTMETRICS font;
    PLUGINSHARE *pPluginData;

    pPluginData = (PLUGINSHARE *) pData;

    if (pPluginData == NULL)
        return (FALSE);

    if (((sActive == TRUE) && !(pPluginData->bActiveEnabled)) ||
            ((sActive == FALSE) && !(pPluginData->bInactiveEnabled)))
        return (TRUE);

    GpiQueryFontMetrics(pPaint->hpsWin, sizeof(font), &(font));

    GpiSetLineType(pPaint->hps, pPluginData->lLineStyle);

    // if no text
    if (pPaint->rectlText.xLeft == pPaint->rectlText.xRight)
    {
        for (y = 4; y < pPaint->rectlWindow.yTop - 4; y += 3)
        {
            if (sActive == TRUE)
                GpiSetColor(pPaint->hps, pPluginData->lActiveShadowColor);
            else
                GpiSetColor(pPaint->hps, pPluginData->lInactiveShadowColor);
            point.x = pPaint->rectlWindow.xLeft + 6;
            point.y = y;
            GpiMove(pPaint->hps, &point);
            point.x = pPaint->rectlWindow.xRight - 5;
            GpiLine(pPaint->hps, &point);

            if (sActive == TRUE)
                GpiSetColor(pPaint->hps, pPluginData->lActiveLineColor);
            else
                GpiSetColor(pPaint->hps, pPluginData->lInactiveLineColor);
            point.x = pPaint->rectlWindow.xLeft + 5;
            point.y++;
            GpiMove(pPaint->hps, &point);
            point.x = pPaint->rectlWindow.xRight - 6;
            GpiLine(pPaint->hps, &point);
        }
    }
    else                        //text exists... draw around it.
    {
        if (pPaint->rectlWindow.xRight > (pPaint->rectlText.xRight + font.lAveCharWidth))
        {
            for (y = 4; y < pPaint->rectlWindow.yTop - 4; y += 3)
            {
                if (sActive == TRUE)
                    GpiSetColor(pPaint->hps, pPluginData->lActiveShadowColor);
                else
                    GpiSetColor(pPaint->hps, pPluginData->lInactiveShadowColor);
                point.x = pPaint->rectlText.xRight + 6;
                point.y = y;
                GpiMove(pPaint->hps, &point);
                point.x = pPaint->rectlWindow.xRight - 5;
                GpiLine(pPaint->hps, &point);

                if (sActive == TRUE)
                    GpiSetColor(pPaint->hps, pPluginData->lActiveLineColor);
                else
                    GpiSetColor(pPaint->hps, pPluginData->lInactiveLineColor);
                point.x = pPaint->rectlText.xRight + 5;
                point.y++;
                GpiMove(pPaint->hps, &point);
                point.x = pPaint->rectlWindow.xRight - 6;
                GpiLine(pPaint->hps, &point);
            }
        }

        if ((pPaint->rectlWindow.xLeft + font.lAveCharWidth) < (pPaint->rectlText.xLeft))
        {
            for (y = 4; y < pPaint->rectlWindow.yTop - 4; y += 3)
            {
                if (sActive == TRUE)
                    GpiSetColor(pPaint->hps, pPluginData->lActiveShadowColor);
                else
                    GpiSetColor(pPaint->hps, pPluginData->lInactiveShadowColor);
                point.x = pPaint->rectlWindow.xLeft + 6;
                point.y = y;
                GpiMove(pPaint->hps, &point);
                point.x = pPaint->rectlText.xLeft - 5;
                GpiLine(pPaint->hps, &point);

                if (sActive == TRUE)
                    GpiSetColor(pPaint->hps, pPluginData->lActiveLineColor);
                else
                    GpiSetColor(pPaint->hps, pPluginData->lInactiveLineColor);
                point.x = pPaint->rectlWindow.xLeft + 5;
                point.y++;
                GpiMove(pPaint->hps, &point);
                point.x = pPaint->rectlText.xLeft - 6;
                GpiLine(pPaint->hps, &point);
            }
        }
    }
    return (TRUE);
}
Exemple #25
0
BOOL F_PS_GpiLine(struct  F_PS *ps, PPOINTL pptlPoint)
{
    POINTL ptl[4] = { 0, 0, 100, 100, 0, 100, 100, 0 };
    GpiLine(hpsDrawBMPBuffer, pptlPoint);
    return 0;
}
MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
     {
     static INT  cxClient, cyClient ;
     HPS         hps ;
     INT         x, y ;
     POINTL      ptl ;

     switch (msg)
	  {
          case WM_SIZE:
               cxClient = SHORT1FROMMP (mp2) ;
               cyClient = SHORT2FROMMP (mp2) ;
               return 0 ;

          case WM_PAINT:
               hps = WinBeginPaint (hwnd, NULLHANDLE, NULL) ;

               GpiErase (hps) ;

               for (x = 0 ; x < 3 ; x++)
               for (y = 0 ; y < 2 ; y++)
                    {
                         // Create an open sub-path

                    GpiBeginPath (hps, 1) ;

                    ptl.x = (1 + 10 * x) * cxClient / 30 ;
                    ptl.y = (4 +  5 * y) * cyClient / 10 ;
                    GpiMove (hps, &ptl) ;

                    ptl.x = (5 + 10 * x) * cxClient / 30 ;
                    ptl.y = (2 +  5 * y) * cyClient / 10 ;
                    GpiLine (hps, &ptl) ;

                    ptl.x = (9 + 10 * x) * cxClient / 30 ;
                    ptl.y = (4 +  5 * y) * cyClient / 10 ;
                    GpiLine (hps, &ptl) ;

                         // Create a closed sub-path

                    ptl.x = (1 + 10 * x) * cxClient / 30 ;
                    ptl.y = (3 +  5 * y) * cyClient / 10 ;
                    GpiMove (hps, &ptl) ;

                    ptl.x = (5 + 10 * x) * cxClient / 30 ;
                    ptl.y = (1 +  5 * y) * cyClient / 10 ;
                    GpiLine (hps, &ptl) ;

                    ptl.x = (9 + 10 * x) * cxClient / 30 ;
                    ptl.y = (3 +  5 * y) * cyClient / 10 ;
                    GpiLine (hps, &ptl) ;

                    GpiCloseFigure (hps) ;
                    GpiEndPath (hps) ;

                         // Possibly modify the path

                    if (y == 0)
                         {
                         GpiSetLineWidthGeom (hps, cxClient / 30) ;
                         GpiModifyPath (hps, 1, MPATH_STROKE) ;
                         }

                         // Perform the operation

                    GpiSetLineWidth (hps, LINEWIDTH_THICK) ;
                    GpiSetLineWidthGeom (hps, cxClient / 50) ;
                    GpiSetPattern (hps, PATSYM_HALFTONE) ;

                    switch (x)
                         {
                         case 0:  GpiOutlinePath (hps, 1, 0) ;
                                  break ;

                         case 1:  GpiStrokePath (hps, 1, 0) ;
                                  break ;

                         case 2:  GpiFillPath (hps, 1, FPATH_ALTERNATE) ;
                                  break ;
                         }
                    }

               WinEndPaint (hps) ;
               return 0 ;
          }
     return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
     }
/*
	draw_thread
	This is the drawing-thread.
	You have a valid presentation space handle (hps), a valid window
	handle (hwndSaver) and the configuration_data structure is loaded.
	The screen size is stored in "screenSizeX" and "screenSizeY".
	IMPORTANT NOTE 1:
	You must check the "stop_draw_thread" flag regularly. If it is set,
	free all resources you have allocated and call _endthread (or just
	return) to end the drawing-thread.
	IMPORTANT NOTE 2:
	If the "low_priority" flag is NOT set (that means you run with
	regular priority, sharing CPU usage with other programs), you should
	call DosSleep(x) with "x" set at least to 1 as often as possible, to
	allow other programs to do their work. A screen saver should not eat
	up other program's CPU time!
	IMPORTANT NOTE 3:
	For some of the PM calls to work properly, your thread needs an
	own HAB and maybe even a message queue. You have to get and release
	both of them here if you use such PM calls.

	The following sample code is from the "Pyramids" module that comes
	with the ScreenSaver distribution.
	It selects a random color and a random point on the screen, then
	draws lines in the selected color from each corner of the screen
	to the selected point (looks somewhat like a pyramid).
	It remembers a number of points (this number can be set in the
	configuration dialog). Having filled the point memory, it redraws
	the "oldest" visible pyramid in black. This has the effect that more
	and more pixels on the screen get black, only a few constantly
	changing colored lines remain.
*/
void	draw_thread(void *args)
{
	POINTL	BitmapPoints[4] = { 1, 1, screenSizeX + 2, screenSizeY + 2,
											-1, -1, screenSizeX, screenSizeY };
   POINTL l_b = { 0, 0 },
			 l_t = { 0, screenSizeY - 1 },
   		 r_b = { screenSizeX - 1, 0 },
			 r_t = { screenSizeX - 1, screenSizeY - 1 };
											
	INT i, step;
	VOID l_left()
	{
		GpiMove( hps, &l_b );
		GpiLine( hps, &l_t );
	}
	VOID l_right()
	{
		GpiMove( hps, &r_b );
		GpiLine( hps, &r_t );
	}
	VOID l_top()
	{
		GpiMove( hps, &l_t );
		GpiLine( hps, &r_t );
	}
	VOID l_bottom()
	{
		GpiMove( hps, &l_b );
		GpiLine( hps, &r_b );
	}
											

	srand(WinGetCurrentTime( hab ));
	GpiSetColor( hps, CLR_BLACK );
	l_left();
	while(!stop_draw_thread){
		if( configuration_data.drunken ){
			step = (unsigned)rand() % 8;
			switch ( step ){
				case 0:  BitmapPoints[0].x = -1;
							BitmapPoints[0].y = 0;
							BitmapPoints[1].x = screenSizeX;
							BitmapPoints[1].y = screenSizeY + 1;
							l_bottom();
							break;
				case 1: 	BitmapPoints[0].x = 0;
							BitmapPoints[0].y = 0;
							BitmapPoints[1].x = screenSizeX + 1;
							BitmapPoints[1].y = screenSizeY + 1;
							l_bottom();
							l_left();
							break;						 
				case 2: 	BitmapPoints[0].x = 0;
							BitmapPoints[0].y = -1;
							BitmapPoints[1].x = screenSizeX + 1;
							BitmapPoints[1].y = screenSizeY;
							l_left();
							break;							
				case 3: 	BitmapPoints[0].x = 0;
							BitmapPoints[0].y = -2;
							BitmapPoints[1].x = screenSizeX + 1;
							BitmapPoints[1].y = screenSizeY - 1;
							l_left();
							l_top();
							break;							
				case 4: 	BitmapPoints[0].x = -1;
							BitmapPoints[0].y = -2;
							BitmapPoints[1].x = screenSizeX;
							BitmapPoints[1].y = screenSizeY - 1;
							l_top();
							break;							
				case 5: 	BitmapPoints[0].x = -2;
							BitmapPoints[0].y = -2;
							BitmapPoints[1].x = screenSizeX - 1;
							BitmapPoints[1].y = screenSizeY - 1;
							l_top();
							l_right();
							break;							
				case 6: 	BitmapPoints[0].x = -2;
							BitmapPoints[0].y = -1;
							BitmapPoints[1].x = screenSizeX - 1;
							BitmapPoints[1].y = screenSizeY;
							l_right();
							break;							
				case 7: 	BitmapPoints[0].x = -2;
							BitmapPoints[0].y = 0;
							BitmapPoints[1].x = screenSizeX - 1;
							BitmapPoints[1].y = screenSizeY + 1;
							l_right();
							l_bottom();
							break;
			}
		}
		for( i = 1; i < 5; i++){	
			GpiBitBlt( hps, hps, 3, BitmapPoints, ROP_SRCCOPY, BBO_IGNORE );	
			if( stop_draw_thread) i = 10;
		}
		
		// sleep if necessary
		if(low_priority == FALSE)
			DosSleep(1);

		// sleep if user requests slower animation
		switch(configuration_data.animation_speed){
		case 4: break;
		case 3: DosSleep(10); break;
		case 2: DosSleep(30); break;
		case 1: DosSleep(50); break;
		case 0: DosSleep(70); break;
		}
	}

	// free resources

	_endthread();
}
/*------------------------------------------------------------------------*/
void LinDrawRotate(WINDOWINFO *pwi, POBJECT pObj, double lRotate,ULONG ulMsg,POINTL *pt)
{
   POINTL ptlCenter,ptl[2];

   pLines pLin = (pLines)pObj;

   if (!pObj) return;

   switch (ulMsg)
   {
      case WM_BUTTON1UP:
         if (!pt)
            return; /* only accept rotation in groups */

         ptlCenter = *pt;

         ptl[0].x = pLin->ptl1.x * pwi->usFormWidth;
         ptl[0].y = pLin->ptl1.y * pwi->usFormHeight;
         ptl[1].x = pLin->ptl2.x * pwi->usFormWidth;    
         ptl[1].y = pLin->ptl2.y * pwi->usFormHeight;

         ptl[0].x += pwi->fOffx;
         ptl[0].y += pwi->fOffy;
         ptl[1].x += pwi->fOffx;
         ptl[1].y += pwi->fOffy;

         RotateSqrSegment(lRotate,ptlCenter,ptl,2);

         ptl[0].x -= pwi->fOffx;
         ptl[0].y -= pwi->fOffy;
         ptl[1].x -= pwi->fOffx;
         ptl[1].y -= pwi->fOffy;

         pLin->ptl1.x = (float)ptl[0].x;
         pLin->ptl1.y = (float)ptl[0].y;
         pLin->ptl2.x = (float)ptl[1].x;
         pLin->ptl2.y = (float)ptl[1].y;
         pLin->ptl1.x /= (float)pwi->usFormWidth;
         pLin->ptl1.y /= (float)pwi->usFormHeight;
         pLin->ptl2.x /= (float)pwi->usFormWidth;
         pLin->ptl2.y /= (float)pwi->usFormHeight;
         break;
      case WM_MOUSEMOVE:
         if (!pt)
            return; /* only accept rotation in groups */

         ptlCenter = *pt;

         ptl[0].x = pLin->ptl1.x * pwi->usFormWidth;
         ptl[0].y = pLin->ptl1.y * pwi->usFormHeight;
         ptl[1].x = pLin->ptl2.x * pwi->usFormWidth;    
         ptl[1].y = pLin->ptl2.y * pwi->usFormHeight;

         ptl[0].x += pwi->fOffx;
         ptl[0].y += pwi->fOffy;
         ptl[1].x += pwi->fOffx;
         ptl[1].y += pwi->fOffy;

         RotateSqrSegment(lRotate,ptlCenter,ptl,2);
         GpiMove(pwi->hps, &ptl[0]);
         GpiLine(pwi->hps, &ptl[1]);
         break;
   }
   return;
}
/*
	draw_thread
	This is the drawing-thread.
	You have a valid presentation space handle (hps), a valid window
	handle (hwndSaver) and the configuration_data structure is loaded.
	The screen size is stored in "screenSizeX" and "screenSizeY".
	IMPORTANT NOTE 1:
	You must check the "stop_draw_thread" flag regularly. If it is set,
	free all resources you have allocated and call _endthread (or just
	return) to end the drawing-thread.
	IMPORTANT NOTE 2:
	If the "low_priority" flag is NOT set (that means you run with
	regular priority, sharing CPU usage with other programs), you should
	call DosSleep(x) with "x" set at least to 1 as often as possible, to
	allow other programs to do their work. A screen saver should not eat
	up other program's CPU time!
	IMPORTANT NOTE 3:
	For some of the PM calls to work properly, your thread needs an
	own HAB and maybe even a message queue. You have to get and release
	both of them here if you use such PM calls.

	The following sample code is from the "Pyramids" module that comes
	with the ScreenSaver distribution.
	It selects a random color and a random point on the screen, then
	draws lines in the selected color from each corner of the screen
	to the selected point (looks somewhat like a pyramid).
	It remembers a number of points (this number can be set in the
	configuration dialog). Having filled the point memory, it redraws
	the "oldest" visible pyramid in black. This has the effect that more
	and more pixels on the screen get black, only a few constantly
	changing colored lines remain.
*/
void draw_thread(void *args)
    {
	int i, j;
	const RECTL ScreenRect = { 0, 0, screenSizeX, screenSizeY };
	int color_count = 0;
	ULONG color;
	int pushleftx = 11, pushlefty = 11, pushrightx = 11, pushrighty = 11;
	BOOL	point_buffer_filled;
	BOOL first_paint = TRUE;
	POINTL	*ptleft, *ptright;
	EXCEPTIONREGISTRATIONRECORD xcpthand = { 
	    (PEXCEPTIONREGISTRATIONRECORD)0, GPFHandler };

	DosSetExceptionHandler(&xcpthand) ;

	i = 0;
	point_buffer_filled = FALSE;
	/* allocate memory for circular point buffer	*/
	ptleft = malloc(configuration_data.count * sizeof(POINTL));
	ptright = malloc(configuration_data.count * sizeof(POINTL));
	if( (ptleft == NULL) || (ptright == NULL) ) goto end;
	GpiSetLineWidth( hps, LINEWIDTH_THICK );

	srand(WinGetCurrentTime(hab));
	
	do{
	    color = ((unsigned)rand()) % 17 - 2;
	}while ( color == -1 || color == 0 || color == 7 || color == 8 );
	/* blank screen if requested	*/
	if( configuration_data.blank_screen )
	    WinFillRect( hps, &ScreenRect, CLR_BLACK );

	while(!stop_draw_thread){

	    if(point_buffer_filled){
		/* redraw old line in black	*/
		GpiSetColor(hps, CLR_BLACK);
		GpiMove(hps, &ptleft[i]);
		GpiLine(hps, &ptright[i]);
	    }
	    if( color_count == configuration_data.colors ){
		/* select random color	*/
		do{
		    color = ((unsigned)rand()) % 17 - 2;
		}while ( color == -1 || color == 0 || color == 7 || color == 8 );
		color_count = 0;
	    }
	    GpiSetColor(hps, color);
	    color_count++;	
	    if (first_paint ){		
		/* set the start coordinates	*/
		ptleft[0].x = rand() % screenSizeX;
		ptleft[0].y = rand() % screenSizeY;
		ptright[0].x = rand() % screenSizeX;
		ptright[0].y = rand() % screenSizeY;
		first_paint = FALSE;
	    } else {
		/* calculate new line points	*/
		j = i==0 ? configuration_data.count - 1 : i - 1;
		ptleft[i].x = ptleft[j].x + pushleftx; 
		ptleft[i].y = ptleft[j].y + pushlefty; 
		ptright[i].x = ptright[j].x + pushrightx;
		ptright[i].y = ptright[j].y + pushrighty; 
	    }

	    /* adjust lines if they hit a screen border */
	    if( ptleft[i].x >= screenSizeX ) {
		ptleft[i].x = 2 * screenSizeX - ptleft[i].x;
		pushleftx = - pushleftx + (rand() % 2);
	    }	
	    if( ptleft[i].y >= screenSizeY ) {
		ptleft[i].y = 2 * screenSizeY - ptleft[i].y;
		pushlefty = - pushlefty + (rand() % 2);
	    }	
	    if( ptright[i].x >= screenSizeX ) {
		ptright[i].x = 2 * screenSizeX - ptright[i].x;
		pushrightx = - pushrightx + ( rand() % 2);
	    }	
	    if( ptright[i].y >= screenSizeY ) {
		ptright[i].y = 2 * screenSizeY - ptright[i].y;
		pushrighty = - pushrighty + ( rand() % 2);
	    }
	    if( ptleft[i].x < 0 ) {	
		ptleft[i].x *= -1;
		pushleftx = - pushleftx + (rand() % 2);
	    }	
	    if( ptleft[i].y < 0 ) {
		ptleft[i].y *= -1;
		pushlefty = - pushlefty + (rand() % 2);
	    }	
	    if( ptright[i].x < 0 ) {
		ptright[i].x *= -1;
		pushrightx = - pushrightx + (rand() % 2);
	    }	
	    if( ptright[i].y < 0 ) {
		ptright[i].y *= -1;
		pushrighty = - pushrighty + (rand() % 2);
	    }	
		
	    /* draw line	*/
	    GpiMove(hps, &ptleft[i]);
	    GpiLine(hps, &ptright[i]);

	    /* sleep if necessary	*/
	    if(low_priority == FALSE)
		DosSleep(1);

	    // sleep if user requests slower animation
				 switch(configuration_data.animation_speed){
				 case 4: break;
				 case 3: DosSleep(10); break;
				 case 2: DosSleep(30); break;
				 case 1: DosSleep(50); break;
				 case 0: DosSleep(70); break;
				 }
	    i++;
	    /* move circular buffer index	*/
	    if(i == configuration_data.count){
		point_buffer_filled = TRUE;
		i = 0;
	    }	
	}
	/* free resources	*/
      end:  // goto from memory allocation
	free( ptleft );
	free( ptright );
	DosUnsetExceptionHandler(&xcpthand);
	_endthread();
    }
bool PaintButton( VRIconButton *somSelf, PUSERBUTTON pbtn )
{
    FONTMETRICS fm;
    HAB    hab;
    RECTL  rcl,
           rclTxt,
           rclImg;
    POINTL ptl,
           aptl[ TXTBOX_COUNT ];
    LONG   lFlags,
           flPic,
           flTxt,
           lStrW,
           lStrH,
           lOffset,
           lClr;
    ULONG  cb;
    BOOL   fPosition;

//FILE *f = fopen("c:\\iconbtn.log", "a");

    VRIconButtonData *somThis = VRIconButtonGetData(somSelf);
    lFlags = _vrGetWindowFlags( somSelf );

//fprintf(f, "----[ Entering PaintButton ] ----\n");

    if ( !pbtn || ( ! WinQueryWindowRect( pbtn->hwnd, &rcl )))
        return FALSE;

    // Get the current background colour
    cb = WinQueryPresParam( pbtn->hwnd, PP_BACKGROUNDCOLOR,
                            PP_BACKGROUNDCOLORINDEX, NULL,
                            sizeof( lClr ), &lClr, QPF_ID2COLORINDEX );
    if ( cb )
        GpiCreateLogColorTable( pbtn->hps, 0, LCOLF_RGB, 0, 0, NULL );
    else
        lClr = GpiQueryRGBColor( pbtn->hps, 0, SYSCLR_BUTTONMIDDLE );

    // Fill in the button background
    WinFillRect( pbtn->hps, &rcl, lClr );

    ptl.x = rcl.xLeft;
    ptl.y = rcl.yBottom;
    GpiMove( pbtn->hps, &ptl );
    ptl.x = rcl.xRight - 1;
    ptl.y = rcl.yTop - 1;
    // Draw the "default" state outline if applicable
    if ( pbtn->fsState & BDS_DEFAULT ) {
        GpiSetColor( pbtn->hps, SYSCLR_BUTTONDEFAULT );
        GpiBox( pbtn->hps, DRO_OUTLINE, &ptl, 0, 0 );
    }
    else {
        cb = WinQueryPresParam( WinQueryWindow( pbtn->hwnd, QW_PARENT ),
                                PP_BACKGROUNDCOLOR, PP_BACKGROUNDCOLORINDEX,
                                NULL, sizeof( lClr ), &lClr, QPF_ID2COLORINDEX );
        if ( cb )
            GpiSetColor( pbtn->hps, lClr );
        else
            GpiSetColor( pbtn->hps, SYSCLR_DIALOGBACKGROUND );
        GpiBox( pbtn->hps, DRO_OUTLINE, &ptl, 0, 0 );
    }

    if ( !( lFlags & BS_NOBORDER )) {
        /* Draw the button border (if appropriate) depending on the current
         * state(s).
         */
        GpiSetColor( pbtn->hps, ( _fDown || ( pbtn->fsState & BDS_HILITED )) ?
                                CLR_BLACK: SYSCLR_BUTTONDARK );
        ptl.x = rcl.xLeft + 1;
        ptl.y = rcl.yBottom + 2;
        GpiMove( pbtn->hps, &ptl );
        ptl.y = rcl.yTop - 2;
        GpiLine( pbtn->hps, &ptl );
        GpiMove( pbtn->hps, &ptl );
        ptl.x = rcl.xRight - 2;
        GpiLine( pbtn->hps, &ptl );
        GpiSetColor( pbtn->hps, ( _fDown || ( pbtn->fsState & BDS_HILITED )) ?
                                SYSCLR_BUTTONDARK: CLR_BLACK );
        ptl.x = rcl.xLeft + 1;
        ptl.y = rcl.yBottom + 1;
        GpiMove( pbtn->hps, &ptl );
        ptl.x = rcl.xRight - 2;
        GpiLine( pbtn->hps, &ptl );
        GpiMove( pbtn->hps, &ptl );
        ptl.y = rcl.yTop - 3;
        GpiLine( pbtn->hps, &ptl );

        GpiSetColor( pbtn->hps, ( _fDown || ( pbtn->fsState & BDS_HILITED )) ?
                                SYSCLR_BUTTONLIGHT: SYSCLR_BUTTONDARK );
        ptl.x = rcl.xLeft + 2;
        ptl.y = rcl.yBottom + 2;
        GpiMove( pbtn->hps, &ptl );
        ptl.x = rcl.xRight - 3;
        GpiLine( pbtn->hps, &ptl );
        GpiMove( pbtn->hps, &ptl );
        ptl.y = rcl.yTop - 3;
        GpiLine( pbtn->hps, &ptl );
        GpiSetColor( pbtn->hps, ( _fDown || ( pbtn->fsState & BDS_HILITED )) ?
                                SYSCLR_BUTTONDARK: SYSCLR_BUTTONLIGHT );
        ptl.x = rcl.xLeft + 2;
        ptl.y = rcl.yBottom + 3;
        GpiMove( pbtn->hps, &ptl );
        ptl.y = rcl.yTop - 3;
        GpiLine( pbtn->hps, &ptl );
        GpiMove( pbtn->hps, &ptl );
        ptl.x = rcl.xRight - 3;
        GpiLine( pbtn->hps, &ptl );

        if ( pbtn->fsState & BDS_HILITED ) {
            GpiSetColor( pbtn->hps, SYSCLR_BUTTONLIGHT );
            ptl.x = rcl.xLeft + 3;
            ptl.y = rcl.yBottom + 3;
            GpiMove( pbtn->hps, &ptl );
            ptl.x = rcl.xRight - 4;
            GpiLine( pbtn->hps, &ptl );
            GpiMove( pbtn->hps, &ptl );
            ptl.y = rcl.yTop - 4;
            GpiLine( pbtn->hps, &ptl );
            GpiSetColor( pbtn->hps, SYSCLR_BUTTONDARK );
            ptl.x = rcl.xLeft + 3;
            ptl.y = rcl.yBottom + 4;
            GpiMove( pbtn->hps, &ptl );
            ptl.y = rcl.yTop - 4;
            GpiLine( pbtn->hps, &ptl );
            GpiMove( pbtn->hps, &ptl );
            ptl.x = rcl.xRight - 4;
            GpiLine( pbtn->hps, &ptl );
        }

    } // if ( !( lFlags & BS_NOBORDER ))

    /* After this point, rcl is used for the clipping boundaries of the entire
     * button contents exclusive of the border.  Separate bounding rectangles
     * for the image and the text will now be calculated within this area.
     */
    if ( rcl.xRight > 6 ) {
        rcl.xLeft += 3;
        rcl.xRight -= 3;
    }
    if ( rcl.yTop > 6 ) {
        rcl.yBottom += 3;
        rcl.yTop -= 3;
    }
    memcpy( &rclTxt, &rcl, sizeof( RECTL ));
    if ( RECTL_WIDTH( rclTxt ) > 4 ) {
        rclTxt.xLeft += 2;
        rclTxt.xRight -= 2;
    }
    if ( RECTL_WIDTH( rclTxt ) > 4 ) {
        rclTxt.yBottom += 2;
        rclTxt.yTop -= 2;
    }
    if ( _pPic && ( _pPic->type & MEMP_BITMAP ) && _fResize )
        memcpy( &rclImg, &rcl, sizeof( RECTL ));
    else {
        rclImg.xLeft   = ( RECTL_WIDTH( rclTxt ) > 6 )  ?
                         rclTxt.xLeft + 3   : rclTxt.xLeft;
        rclImg.xRight  = ( RECTL_WIDTH( rclTxt ) > 6 )  ?
                         rclTxt.xRight - 3  : rclTxt.xRight;
        rclImg.yBottom = ( RECTL_HEIGHT( rclTxt ) > 6 ) ?
                         rclTxt.yBottom + 3 : rclTxt.yBottom;
        rclImg.yTop    = ( RECTL_HEIGHT( rclTxt ) > 6 ) ?
                         rclTxt.yTop - 3    : rclTxt.yTop;
    }

//fprintf(f, "rcl     = {%d %d %d %d}, width = %d, height= %d\n", rcl.xLeft, rcl.yBottom, rcl.xRight, rcl.yTop, RECTL_WIDTH(rcl), RECTL_HEIGHT(rcl) );
//fprintf(f, "rclImg  = {%d %d %d %d}, width = %d, height= %d\n", rclImg.xLeft, rclImg.yBottom, rclImg.xRight, rclImg.yTop, RECTL_WIDTH(rclImg), RECTL_HEIGHT(rclImg) );

    fPosition = _pPic && ( !_fResize || _pPic->type & MEMP_ICON ) &&
                (( _bAlign == ALIGN_LEFT ) || ( _bAlign == ALIGN_RIGHT )) ?
                TRUE : FALSE;

    /* We won't draw the text until after the image... but unless we're scaling
     * the image into the whole button, we need to calculate how much space the
     * text is going to require so we can fit the image next to it.  (Note that
     * we behave differently for top/bottom alignment vs left/right alignment -
     * with top/bottom, the text area is fixed to the height of the string plus
     * a certain margin.  With left/right alignment, the image rectangle is set
     * to the physical image size, and the text rectangle is offset from that.)
     */
    lStrW = 0;
    lStrH = 0;
    GpiQueryFontMetrics( pbtn->hps, sizeof( FONTMETRICS ), &fm );
    if ( _pszText && *_pszText ) {

        // Get the width of the text as it would be rendered in the current font
        GpiQueryTextBox( pbtn->hps, strlen( _pszText ),
                         _pszText, TXTBOX_COUNT, aptl );

        lStrW = aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x;
        lStrW += ( 2 * fm.lAveCharWidth );
        lStrH = fm.lMaxBaselineExt + fm.lInternalLeading + fm.lMaxDescender;

        // Adjust the bounding rectangles for the text and image
        switch ( _bAlign ) {
            case ALIGN_TOP:
                rclTxt.yBottom = rclTxt.yTop - lStrH;
                if ( _pPic && ( !_fResize || _pPic->type & MEMP_ICON )) {
                    if (( rclTxt.yBottom - rclImg.yBottom ) > _pPic->height )
                        rclImg.yTop = rclTxt.yBottom - 1;
                    else if (( rcl.yTop - rclImg.yBottom ) > _pPic->height )
                        rclImg.yTop = rcl.yBottom + _pPic->height;
                }
                break;
            case ALIGN_BOTTOM:
                rclTxt.yTop = rclTxt.yBottom + lStrH;
                if ( _pPic && ( !_fResize || _pPic->type & MEMP_ICON )) {
                    if ((( rclImg.yTop - rclTxt.yTop ) > _pPic->height ))
                        rclImg.yBottom = rclTxt.yTop + 1;
                    else if (( rclImg.yTop - rcl.yBottom ) > _pPic->height )
                        rclImg.yBottom = (LONG) ( rcl.yTop - _pPic->height );
                }
                break;
            case ALIGN_LEFT:
                if ( fPosition ) {
                    if (( rclTxt.xLeft + lStrW + _pPic->width ) < rclImg.xRight ) {
                        rclImg.xLeft = rclImg.xRight - _pPic->width;
                        rclTxt.xRight = rclImg.xLeft - 1;
                    }
                    else  {
                        rclTxt.xRight = rclTxt.xLeft + lStrW;
                        if (( rclImg.xRight - _pPic->width ) < RECTL_WIDTH( rcl ))
                            rclImg.xLeft = (LONG) ( rclImg.xRight - _pPic->width );
                    }
                }
                else
                    rclTxt.xRight = rclTxt.xLeft + lStrW;
                break;
            case ALIGN_RIGHT:
                if ( fPosition ) {
                    if (( rclImg.xLeft + _pPic->width + lStrW ) < rclImg.xRight ) {
                        rclImg.xRight = rclImg.xLeft + _pPic->width;
                        rclTxt.xLeft = rclImg.xRight + 1;
                    }
                    else {
                        rclTxt.xLeft = rclTxt.xRight - lStrW;
                        if (( rclImg.xLeft + _pPic->width ) < RECTL_WIDTH( rcl ))
                            rclImg.xRight = rclImg.xLeft + _pPic->width;
                    }
                }
                else
                    rclTxt.xLeft = rclTxt.xRight - lStrW;
                break;
            default: break;   // ALIGN_CENTER, no adjustment needed
        }
        if ( rclTxt.yBottom < rcl.yBottom ) rclTxt.yBottom = rcl.yBottom;
        if ( rclTxt.yTop > rcl.yTop ) rclTxt.yTop = rcl.yTop;
        if ( rclTxt.xLeft < rcl.xLeft ) rclTxt.xLeft = rcl.xLeft;
        if ( rclTxt.xRight > rcl.xRight ) rclTxt.xRight = rcl.xRight;
    }

    // Draw the image, if one is defined
    if ( _pPic ) {

        if (( pbtn->fsState & BDS_HILITED ) &&
            !( _fResize && ( _pPic->type & MEMP_BITMAP )))
        {
            rclImg.xLeft++;
            rclImg.xRight++;
            rclImg.yBottom--;
            rclImg.yTop--;
        }

        flPic = PICTDRAW_CENTER_ICON;
        if ( pbtn->fsState & BDS_DISABLED ) flPic |= PICTDRAW_DISABLE;
        if ( _pPic->type & MEMP_BITMAP ) {
            if ( _fResize )
                flPic |= PICTDRAW_STRETCH_BITMAP;
            else {
                ptl.x = ((LONG)( RECTL_WIDTH( rclImg ) - _pPic->width ) / 2 );
                ptl.y = ((LONG)( RECTL_HEIGHT( rclImg ) - _pPic->height ) / 2 );
                if ( ptl.x > 0 ) rclImg.xLeft += ptl.x;
                if ( ptl.y > 0 ) rclImg.yBottom += ptl.y;
            }
        }

        VRPictDisplay( pbtn->hwnd, pbtn->hps, _pPic, &rclImg, flPic );
    }

    // Now draw the text, if any
    if ( _pszText && *_pszText ) {

        // Get the current foreground colour
        if ( pbtn->fsState & BDS_DISABLED )
            lClr = GpiQueryRGBColor( pbtn->hps, 0, SYSCLR_MENUDISABLEDTEXT );
        else {
            cb = WinQueryPresParam( pbtn->hwnd, PP_FOREGROUNDCOLOR,
                                    PP_FOREGROUNDCOLORINDEX, NULL,
                                    sizeof( lClr ), &lClr, QPF_ID2COLORINDEX );
            if ( !cb )
                lClr = GpiQueryRGBColor( pbtn->hps, 0, SYSCLR_WINDOWTEXT );
        }
        GpiSetColor( pbtn->hps, lClr );

        // Now position and draw the button text
        switch ( _bAlign ) {

            case ALIGN_TOP:
#ifdef GPI_DRAWTEXT
                ptl.x = rclTxt.xLeft + ( RECTL_WIDTH( rclTxt ) / 2 );
                ptl.y = ( RECTL_HEIGHT( rclTxt ) < lStrH ) ? rclTxt.yTop :
                        rclTxt.yTop - ( 2 * fm.lInternalLeading );
                GpiSetTextAlignment( pbtn->hps, TA_CENTER, TA_TOP );
#else
                flTxt = DT_CENTER | (( RECTL_HEIGHT( rclTxt ) < lStrH )
                                    ? DT_TOP : DT_VCENTER ) |
                        DT_TEXTATTRS | DT_MNEMONIC;
#endif
                break;

            case ALIGN_BOTTOM:
#ifdef GPI_DRAWTEXT
                ptl.x = rclTxt.xLeft + ( RECTL_WIDTH( rclTxt ) / 2 );
                ptl.y = ( RECTL_HEIGHT( rclTxt ) < lStrH ) ? rclTxt.yBottom :
                        rclTxt.yBottom + ( 2 * fm.lInternalLeading );
                GpiSetTextAlignment( pbtn->hps, TA_CENTER, TA_BOTTOM );
#else
                flTxt = DT_CENTER | (( RECTL_HEIGHT( rclTxt ) < lStrH ) ?
                                    DT_BOTTOM : DT_VCENTER ) |
                        DT_TEXTATTRS | DT_MNEMONIC;
#endif
                break;

            case ALIGN_LEFT:
#ifdef GPI_DRAWTEXT
                ptl.x = rclTxt.xLeft + fm.lAveCharWidth;
                ptl.y = rclTxt.yBottom + (( RECTL_HEIGHT( rclTxt ) - fm.lXHeight ) / 2 );
                GpiSetTextAlignment( pbtn->hps, TA_NORMAL_HORIZ, TA_BASE );
#else
                flTxt = DT_LEFT | DT_VCENTER | DT_TEXTATTRS | DT_MNEMONIC;
                rclTxt.xLeft += fm.lAveCharWidth;
#endif
                break;

            case ALIGN_RIGHT:
#ifdef GPI_DRAWTEXT
                ptl.x = rclTxt.xLeft + fm.lAveCharWidth;
                ptl.y = rclTxt.yBottom + (( RECTL_HEIGHT( rclTxt ) - fm.lXHeight ) / 2 );
                GpiSetTextAlignment( pbtn->hps, TA_NORMAL_HORIZ, TA_BASE );
#else
                flTxt = (fPosition? DT_LEFT: DT_RIGHT) | DT_VCENTER | DT_TEXTATTRS | DT_MNEMONIC;
                if ( RECTL_WIDTH( rclTxt ) > fm.lAveCharWidth ) {
                    if ( fPosition )
                        rclTxt.xLeft += fm.lAveCharWidth;
                    else
                        rclTxt.xRight -= fm.lAveCharWidth;
                }
#endif
                break;

            default:    // ALIGN_CENTER
#ifdef GPI_DRAWTEXT
                ptl.x = rclTxt.xLeft + ( RECTL_WIDTH( rclTxt ) / 2 );
                ptl.y = rclTxt.yBottom + (( RECTL_HEIGHT( rclTxt ) - fm.lXHeight ) / 2 );
                GpiSetTextAlignment( pbtn->hps, TA_CENTER, TA_BASE );
#else
                flTxt = DT_CENTER | DT_VCENTER | DT_TEXTATTRS | DT_MNEMONIC;
#endif
                break;
        }
        if ( pbtn->fsState & BDS_HILITED ) {
            ptl.x++;
            ptl.y--;
        }
        cb = strlen( _pszText );
#ifdef GPI_DRAWTEXT
        GpiCharStringPosAt( pbtn->hps, &ptl, &rclTxt, CHS_CLIP, cb, _pszText, NULL );
#else
        WinDrawText( pbtn->hps, cb, _pszText, &rclTxt, 0, 0, flTxt );
#endif
    }

//fprintf(f, "----[ Leaving PaintButton ] ----\n\n");
//fclose(f);

    return TRUE;
}