コード例 #1
0
MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
     {
     static INT aiPuzzle[NUMROWS][NUMCOLS],
                iBlankRow, iBlankCol, cxSquare, cySquare ;
     CHAR       szNum[10] ;
     HPS        hps ;
     HWND       hwndFrame ;
     INT        iRow, iCol, iMouseRow, iMouseCol, i ;
     POINTL     ptl ;
     RECTL      rcl, rclInvalid, rclIntersect ;
     SIZEL      sizl ;

     switch (msg)
          {
          case WM_CREATE:
                              // Calculate square size in pixels

               hps = WinGetPS (hwnd) ;
               sizl.cx = sizl.cy = 0 ;
               GpiSetPS (hps, &sizl, PU_LOENGLISH) ;
               ptl.x = SQUARESIZE ;
               ptl.y = SQUARESIZE ;
               GpiConvert (hps, CVTC_PAGE, CVTC_DEVICE, 1L, &ptl) ;
               WinReleasePS (hps) ;

               cxSquare = ptl.x ;
               cySquare = ptl.y ;

                              // Calculate client window size and position

               rcl.xLeft   = (WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN) -
                                           NUMCOLS * cxSquare) / 2 ;
               rcl.yBottom = (WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN) -
                                           NUMROWS * cySquare) / 2 ;
               rcl.xRight  = rcl.xLeft   + NUMCOLS * cxSquare ;
               rcl.yTop    = rcl.yBottom + NUMROWS * cySquare ;

                              // Set frame window position and size

               hwndFrame = WinQueryWindow (hwnd, QW_PARENT) ;
               WinCalcFrameRect (hwndFrame, &rcl, FALSE) ;
               WinSetWindowPos  (hwndFrame, NULLHANDLE,
                                 rcl.xLeft, rcl.yBottom,
                                 rcl.xRight - rcl.xLeft,
                                 rcl.yTop - rcl.yBottom,
                                 SWP_MOVE | SWP_SIZE | SWP_ACTIVATE) ;

                              // Initialize the aiPuzzle array

               WinSendMsg (hwnd, WM_COMMAND, MPFROMSHORT (IDM_NORMAL), NULL) ;
               return 0 ;

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

                              // Draw the squares

               for (iRow = NUMROWS - 1 ; iRow >= 0 ; iRow--)
                    for (iCol = 0 ; iCol < NUMCOLS ; iCol++)
                         {
                         rcl.xLeft   = cxSquare * iCol ;
                         rcl.yBottom = cySquare * iRow ;
                         rcl.xRight  = rcl.xLeft   + cxSquare ;
                         rcl.yTop    = rcl.yBottom + cySquare ;

                         if (!WinIntersectRect (0, &rclIntersect,
                                                &rcl, &rclInvalid))
                              continue ;

                         if (iRow == iBlankRow && iCol == iBlankCol)
                              WinFillRect (hps, &rcl, CLR_BLACK) ;
                         else
                              {
                              WinDrawBorder (hps, &rcl, 5, 5,
                                             CLR_PALEGRAY, CLR_DARKGRAY,
                                             DB_STANDARD | DB_INTERIOR) ;

                              WinDrawBorder (hps, &rcl, 2, 2,
                                             CLR_BLACK, 0L, DB_STANDARD) ;

                              sprintf (szNum, "%d", aiPuzzle[iRow][iCol]) ;

                              WinDrawText (hps, -1, szNum,
                                           &rcl, CLR_WHITE, CLR_DARKGRAY,
                                           DT_CENTER | DT_VCENTER) ;
                              }
                         }
               WinEndPaint (hps) ;
               return 0 ;

          case WM_BUTTON1DOWN:
               iMouseCol = MOUSEMSG(&msg)->x / cxSquare ;
               iMouseRow = MOUSEMSG(&msg)->y / cySquare ;

                              // Check if mouse was in valid area

               if ( iMouseRow < 0          || iMouseCol < 0           ||
                    iMouseRow >= NUMROWS   || iMouseCol >= NUMCOLS    ||
                   (iMouseRow != iBlankRow && iMouseCol != iBlankCol) ||
                   (iMouseRow == iBlankRow && iMouseCol == iBlankCol))
                         break ;

                              // Move a row right or left

               if (iMouseRow == iBlankRow)
                    {
                    if (iMouseCol < iBlankCol)
                         for (iCol = iBlankCol ; iCol > iMouseCol ; iCol--)
                              aiPuzzle[iBlankRow][iCol] =
                                   aiPuzzle[iBlankRow][iCol - 1] ;
                    else
                         for (iCol = iBlankCol ; iCol < iMouseCol ; iCol++)
                              aiPuzzle[iBlankRow][iCol] =
                                   aiPuzzle[iBlankRow][iCol + 1] ;
                    }
                              // Move a column up or down
               else
                    {
                    if (iMouseRow < iBlankRow)
                         for (iRow = iBlankRow ; iRow > iMouseRow ; iRow--)
                              aiPuzzle[iRow][iBlankCol] =
                                   aiPuzzle[iRow - 1][iBlankCol] ;
                    else
                         for (iRow = iBlankRow ; iRow < iMouseRow ; iRow++)
                              aiPuzzle[iRow][iBlankCol] =
                                   aiPuzzle[iRow + 1][iBlankCol] ;
                    }
                              // Calculate invalid rectangle

               rcl.xLeft   = cxSquare *  min (iMouseCol, iBlankCol) ;
               rcl.yBottom = cySquare *  min (iMouseRow, iBlankRow) ;
               rcl.xRight  = cxSquare * (max (iMouseCol, iBlankCol) + 1) ;
               rcl.yTop    = cySquare * (max (iMouseRow, iBlankRow) + 1) ;

                              // Set new array and blank values

               iBlankRow = iMouseRow ;
               iBlankCol = iMouseCol ;
               aiPuzzle[iBlankRow][iBlankCol] = 0 ;

                              // Invalidate rectangle

               WinInvalidateRect (hwnd, &rcl, FALSE) ;
               break ;

          case WM_CHAR:
               if (!(CHARMSG(&msg)->fs & KC_VIRTUALKEY) ||
                     CHARMSG(&msg)->fs & KC_KEYUP)
                         return 0 ;

                              // Mimic a WM_BUTTON1DOWN message

               iMouseCol = iBlankCol ;
               iMouseRow = iBlankRow ;

               switch (CHARMSG(&msg)->vkey)
                    {
                    case VK_LEFT:   iMouseCol++ ;  break ;
                    case VK_RIGHT:  iMouseCol-- ;  break ;
                    case VK_UP:     iMouseRow-- ;  break ;
                    case VK_DOWN:   iMouseRow++ ;  break ;
                    default:        return 0 ;
                    }
               WinSendMsg (hwnd, WM_BUTTON1DOWN,
                           MPFROM2SHORT (iMouseCol * cxSquare,
                                         iMouseRow * cySquare), NULL) ;
               return 0 ;

          case WM_COMMAND:
               switch (COMMANDMSG(&msg)->cmd)
                    {
                              // Initialize aiPuzzle array

                    case IDM_NORMAL:
                    case IDM_INVERT:
                         for (iRow = 0 ; iRow < NUMROWS ; iRow++)
                              for (iCol = 0 ; iCol < NUMCOLS ; iCol++)
                                   aiPuzzle[iRow][iCol] = iCol + 1 +
                                        NUMCOLS * (NUMROWS - iRow - 1) ;

                         if (COMMANDMSG(&msg)->cmd == IDM_INVERT)
                              {
                              aiPuzzle[0][NUMCOLS-2] = NUMCOLS * NUMROWS - 2 ;
                              aiPuzzle[0][NUMCOLS-3] = NUMCOLS * NUMROWS - 1 ;
                              }
                         aiPuzzle[iBlankRow = 0][iBlankCol = NUMCOLS - 1] = 0 ;
                         WinInvalidateRect (hwnd, NULL, FALSE) ;
                         return 0 ;

                              // Randomly scramble the squares

                    case IDM_SCRAMBLE:
                         WinSetPointer (HWND_DESKTOP, WinQuerySysPointer (
                                        HWND_DESKTOP, SPTR_WAIT, FALSE)) ;

                         srand ((int) WinGetCurrentTime (0)) ;

                         for (i = 0 ; i < SCRAMBLEREP ; i++)
                              {
                              WinSendMsg (hwnd, WM_BUTTON1DOWN,
                                   MPFROM2SHORT (rand() % NUMCOLS * cxSquare,
                                        iBlankRow * cySquare), NULL) ;
                              WinUpdateWindow (hwnd) ;

                              WinSendMsg (hwnd, WM_BUTTON1DOWN,
                                   MPFROM2SHORT (iBlankCol * cxSquare,
                                        rand() % NUMROWS * cySquare), NULL) ;
                              WinUpdateWindow (hwnd) ;
                              }
                         WinSetPointer (HWND_DESKTOP, WinQuerySysPointer (
                                        HWND_DESKTOP, SPTR_ARROW, FALSE));
                         return 0 ;
                    }
               break ;
          }
     return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
     }
コード例 #2
0
/*---------------------------------------------------------------------------*/
void paintText( HPS hps,WINDOWINFO *pwi,POBJECT pObj,RECTL *prcl, int iMode )
{
   int        iBreakCount, iSurplus ;
   PCHAR      pStart, pEnd ;
   PCHAR      pText;
   POINTL     ptlStart, aptlTextBox [TXTBOX_COUNT] ;
   blocktext *pT;
   RECTL      rclColumn;
   SIZEF      sizfx;
   FIXED      fxBreakExtra;
   int        iLineBreak;
   int        iLen;
   iSurplus = 0;


   pT = (blocktext *)pObj;

   if (iMode != MODE_PREPPRINTING)
   {
      if (pwi->usdrawlayer != pT->bt.usLayer)
         return;
   }
   /*
   ** Just in case the text starts with a linebreak...
   */
   memset ((void *)aptlTextBox,0,( sizeof(POINTL) * TXTBOX_COUNT)); 
   /*
   ** Get column rectangle of first column..
   */
   getColumnOutline(pT,&rclColumn,pwi,0,(BOOL)(iMode == MODE_PREPPRINTING));

   pText = (PCHAR)pT->pszText;
     
   ptlStart.y = rclColumn.yTop ;

   if (!pText)
      return;

   if (prcl)
   {
      RECTL rclDest;
      /*
      ** prcl is only true for screen operations!
      ** For this moment we only check on the first column
      ** TODO !!! All columns
      */
      if (!WinIntersectRect(hab,&rclDest,prcl,&rclColumn))
         return;
   }

   if (iMode == MODE_PREPPRINTING)
   {
      sizfx.cx = pT->sizfx.fcx * pwi->usWidth;
      sizfx.cy = pT->sizfx.fcy * pwi->usHeight;
   }
   else
   {
      sizfx.cx = pT->sizfx.fcx * pwi->usFormWidth;
      sizfx.cy = pT->sizfx.fcy * pwi->usFormHeight;
   }

   setFont(pwi,&pT->fattrs,sizfx);

   if (iMode == MODE_PREPPRINTING)
      GpiQueryWidthTable(pwi->hps,0,MAX_NRWIDTH,pObj->lWidth);

  if (paintColumn(hps,pwi,pObj,rclColumn,iMode))
  {
     rclColumn.xLeft   += 20;
     rclColumn.yBottom += 20;
     rclColumn.xRight  -= 20;
     rclColumn.yTop    -= 20;
  }

   if (iMode != MODE_OUTLINE)
      GpiSetColor(hps,pT->bt.fColor);

   if (pwi->bPrinter)
   {
      /*
      ** Set the text on paper and get out!!
      */
      PrintBlockText(pObj,pwi);
      return;
   }


   do                                 // until end of text
   {
          iBreakCount  = 0;
          fxBreakExtra = 0;
          iLineBreak   = 0;

          while (*pText == ' ')         // Skip over leading blanks
               pText++ ;

          pStart = pText ;

          do                            // until line is known
               {
               iLineBreak   = 0;

               while (*pText == ' ')    // Skip over leading blanks
                    pText++ ;

                                        // Find next break point

               while (*pText != '\x00' && *pText != ' ' && 
                      *pText != '\r' && *pText != '\n')
                    pText++ ;

               if (*pText == '\r'|| *pText == '\n')
               {
                  pText++;
                  iLineBreak = 1;
                  if (*pText == '\n' || *pText == '\r')
                  {
                     pText++;
                     iLineBreak = 2;
                  }
               }
               /*
               ** A line with only a cariage return linefeed?
               */
               if ( ((pText - pStart) - iLineBreak) <= 0)
               {
                  pEnd  = pText ;
                  break;
               }
                                        // Determine text width

               GpiQueryTextBox (hps, (pText - pStart) - iLineBreak, pStart,
                                TXTBOX_COUNT, aptlTextBox) ;

                         // Normal case: text less wide than column

               if (aptlTextBox[TXTBOX_CONCAT].x < (rclColumn.xRight - rclColumn.xLeft))
                    {
                    iBreakCount++ ;
                    pEnd  = pText;
                    }

                         // Text wider than window with only one word

               else if (iBreakCount == 0)
                    {
                    pEnd  = pText ;
                    break ;
                    }

                         // Text wider than window, so fix up and get out
               else
                    {
                    iBreakCount-- ;
                    pText = pEnd ;
                    /*
                    ** Although we could have found a line break the
                    ** text did not fit the line at all. So...
                    */
                    iLineBreak = 0;
                    break ;
                    }
               }
          while (*pText != '\x00' && !iLineBreak) ;

                         // Get the final text box

          iLen = (int)(pEnd - pStart);
          if (iLen - iLineBreak > 0)
             GpiQueryTextBox (hps, (pEnd - pStart)-iLineBreak, pStart,
                              TXTBOX_COUNT, aptlTextBox) ;

                         // Drop down by maximum ascender

          ptlStart.y -= aptlTextBox[TXTBOX_TOPLEFT].y ;

                         // Find surplus space in text line

          iSurplus = rclColumn.xRight - rclColumn.xLeft -
                     aptlTextBox[TXTBOX_CONCAT].x ;

                        // Adjust starting position and
                        // space and character spacing

          switch (pT->nAlign)
               {
               case ALIGN_LEFT:
                    ptlStart.x = rclColumn.xLeft ;
                    break ;

               case ALIGN_RIGHT:
                    ptlStart.x = rclColumn.xLeft + iSurplus ;
                    break ;

               case ALIGN_CENTER:
                    ptlStart.x = rclColumn.xLeft + iSurplus / 2 ;
                    break ;

               case ALIGN_JUST:
                    ptlStart.x = rclColumn.xLeft ;

                    if (*pText == '\x00')
                         break ;

                    if (iBreakCount > 0)
                    {
                         fxBreakExtra = 65536 * iSurplus / iBreakCount;
                         GpiSetCharBreakExtra (hps,fxBreakExtra);
                    }
                    else if (pEnd - pStart - 1 > 0)
                    {
                         fxBreakExtra = 65536 * iSurplus / (pEnd - pStart - 1 - iLineBreak);
                         GpiSetCharExtra (hps,fxBreakExtra);
                    }
                    break ;
               }

                         // Drop down by maximum descender

          if (pT->nSpace != SPACE_NONE)
             ptlStart.y += aptlTextBox[TXTBOX_BOTTOMLEFT].y ;

                         // Display the string & return to normal
          if ((pEnd - pStart))
             GpiCharStringAt (hps, &ptlStart, (pEnd - pStart ) - iLineBreak, pStart) ;

          if (iMode == MODE_PREPPRINTING)
          {
             bTextMakePrintBlock(pObj,
                                 pwi,
                                 fxBreakExtra,
                                 iBreakCount,
                                 ptlStart,
                                 (LONG)((pEnd - pStart) -iLineBreak),
                                 pStart);
          }
          GpiSetCharExtra (hps, 0) ;
          GpiSetCharBreakExtra (hps, 0) ;

                         // Do additional line-spacing

          switch (pT->nSpace)
               {
               case SPACE_HALF:
                    ptlStart.y -= (aptlTextBox[TXTBOX_TOPLEFT].y -
                                   aptlTextBox[TXTBOX_BOTTOMLEFT].y) / 2 ;
                    break ;

               case SPACE_DOUBLE:
                    ptlStart.y -= aptlTextBox[TXTBOX_TOPLEFT].y -
                                  aptlTextBox[TXTBOX_BOTTOMLEFT].y ;
                    break ;
               }
          }

     while (*pText != '\x00' && ptlStart.y > rclColumn.yBottom) ;
}
コード例 #3
0
static void draw_stuff( HWND hwnd )
{
    HPS                 win_dc;
    RECTL               paint;
    RECTL               intersect;
#ifdef DRAW_ALL_AT_ONCE
    int                 old_top;
    int                 width, height;
    SIZEL               sizl = { 0, 0 };
    BITMAPINFOHEADER2   bmih;
    LONG                formats[24];
    POINTL              pts[3];
    LONG                old_cursor;
    LONG                hour_glass_cur;
    RECTL               interior;
    DEVOPENSTRUC        dop = { 0L, "DISPLAY", NULL, 0L,
                                0L, 0L, 0L, 0L, 0L };
#endif


    win_dc = WinBeginPaint( hwnd, 0, &paint );
    GpiCreateLogColorTable( win_dc, 0L, LCOLF_RGB, 0L, 0L, NULL );
#ifdef DRAW_ALL_AT_ONCE
    old_top = paint.yBottom;
    paint.yBottom = Draw_area.yTop;
#endif
    WinFillRect( win_dc, &paint, SYSCLR_WINDOW );
#ifdef DRAW_ALL_AT_ONCE
    paint.yBottom = old_top;
#endif
    if( WinIntersectRect( Main_hab, &intersect, &paint, &Draw_area ) ) {

#ifdef DRAW_ALL_AT_ONCE
        width = Draw_area.xRight - Draw_area.xLeft;
        height = Draw_area.yTop - Draw_area.yBottom;
        interior.xLeft = 0;
        interior.yBottom = 0;
        interior.xRight = width;
        interior.yTop = height;
        if( Draw_bitmap == NULLHANDLE ) {
            Hdc = DevOpenDC( Main_hab, OD_MEMORY, "*", 5L,
                                            (PDEVOPENDATA)&dop, NULLHANDLE );
            Mem_dc = GpiCreatePS( Main_hab, Hdc, &sizl, PU_PELS | GPIA_ASSOC );
            memset( &bmih, 0, sizeof( BITMAPINFOHEADER2 ) );
            GpiQueryDeviceBitmapFormats( Mem_dc, 24L, formats );
            bmih.cbFix = sizeof( BITMAPINFOHEADER2 );
            bmih.cx = width;
            bmih.cy = height;
            bmih.cPlanes = (USHORT) formats[0];
            bmih.cBitCount = (USHORT) formats[1];
            Draw_bitmap = GpiCreateBitmap( Mem_dc, &bmih, 0L, NULL, NULL );
            Old_bitmap = GpiSetBitmap( Mem_dc, Draw_bitmap );
            GpiCreateLogColorTable( Mem_dc, 0, LCOLF_RGB, 0, 0, NULL );
            WinFillRect( Mem_dc, &interior, SYSCLR_WINDOW );

            hour_glass_cur = WinQuerySysPointer( HWND_DESKTOP, SPTR_WAIT, FALSE );
            old_cursor = WinQueryPointer( HWND_DESKTOP );
            WinSetPointer( HWND_DESKTOP, hour_glass_cur );

            hThree_d = three_d_begin( Mem_dc, &interior );
            draw_room();
            three_d_draw( hThree_d );
            three_d_end( hThree_d );

            WinSetPointer( HWND_DESKTOP, old_cursor );
        }

        pts[0].x = Draw_area.xLeft;
        pts[0].y = Draw_area.yBottom;
        pts[1].x = Draw_area.xLeft + width;
        pts[1].y = Draw_area.yBottom + height;
        pts[2].x = 0;
        pts[2].y = 0;
        GpiBitBlt( win_dc, Mem_dc, 3, pts, ROP_SRCCOPY, BBO_IGNORE );
#else
        hThree_d = three_d_begin( win_dc, &Draw_area );
        draw_room();
        three_d_draw( hThree_d );
        three_d_end( hThree_d );
#endif

    }
    WinEndPaint( win_dc );
}