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); }
/*----------------------------------------------------------------------*/ 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 GRAPHBOARD::ShowPointerPos( HPS hps, LONG ptx, LONG pty ) { POINTL Point; Point.x = LowerLeftPlace.x + (GetBoardCol( ptx ) - 1) * dist; Point.y = LowerLeftPlace.y + (GetBoardRow( pty ) - 1) * dist; if( Point.x == DrawPoint.x && Point.y == DrawPoint.y ) return; // nothing to do if( GetfShowLines() ){ // if the help lines are visible, turn them off SetfShowLines( FALSE ); DisplayLines( hps ); } GpiSetMix( hps, FM_XOR ); GpiSetColor( hps, CLR_DARKGRAY ); if( DrawPoint.x >= LowerLeftPlace.x && DrawPoint.y >= LowerLeftPlace.y ) { // there exists a visible square that must be removed DrawPoint.x -= dist / 3; DrawPoint.y -= dist / 3; GpiMove( hps, &DrawPoint ); DrawPoint.x += 2 * dist / 3; DrawPoint.y += 2 * dist / 3; GpiBox( hps, DRO_OUTLINEFILL, &DrawPoint, 0, 0 ); } DrawPoint.x = Point.x; // DrawPoint is set to the new point DrawPoint.y = Point.y; if( Point.x >= LowerLeftPlace.x && Point.y >= LowerLeftPlace.y ){ // neither GetBoardCol nor GetBoardRow returned 0 => point is visible Point.x -= dist / 3; Point.y -= dist / 3; GpiMove( hps, &Point ); Point.x += 2 * dist / 3; Point.y += 2 * dist / 3; GpiBox( hps, DRO_OUTLINEFILL, &Point, 0, 0 ); } GpiSetMix( hps, FM_OVERPAINT ); }
ListBoxItemProvider &ListBoxItemProvider :: drawEmphasis ( IListBox *listBox, const TgtLocation &target ) { // If same target, then it's already drawn. if ( target == lastTarget ) return *this; // Get presentation space and make it mode INVERT. IPresSpaceHandle hps = DrgGetPS( listBox->handle() ); GpiSetMix( hps, FM_INVERT ); // "Undraw" current target emphasis: draw( hps, listBox, lastTarget ); // Set new target and draw it. lastTarget = target; draw( hps, listBox, lastTarget ); DrgReleasePS( hps ); return *this; }
/****************************************************************\ * *-------------------------------------------------------------- * * Name:ClkTimer() * * Purpose: Handles window timer events * * * * Usage: * * Method: * - * * - * - * * - * - * * Returns: * 1 - if sucessful execution completed * 0 - if error \****************************************************************/ VOID ClkTimer (HWND hwnd) { DATETIME dtNew; static LONG lTimeChangeCheck = 0L; LONG lTime; DosGetDateTime ( &dtNew ) ; if (cp.usDispMode & DM_ANALOG) { /* get the new time */ DosGetDateTime (&dtNew); /* adjust the hour hand */ dtNew.hours = (dtNew.hours * (UCHAR) 5 ) % (UCHAR) 60 + dtNew.minutes / (UCHAR)12; /* if we must move the hour and minute hands, redraw it all */ if (dtNew.minutes != dt.minutes) { ClkDrawFace(hpsBuffer); ClkDrawDate(hpsBuffer, DM_REDRAW); ClkDrawHand(hpsBuffer, HT_HOUR_SHADE, dtNew.hours); ClkDrawHand(hpsBuffer, HT_MINUTE_SHADE, dtNew.minutes); ClkDrawHand(hpsBuffer, HT_HOUR, dtNew.hours); ClkDrawHand(hpsBuffer, HT_MINUTE, dtNew.minutes); UpdateScreen (hps, NULL); if (fShowSecondHand && (cp.usDispMode & DM_SECONDHAND)) { GpiSetMix(hps, FM_INVERT); ClkDrawHand(hps, HT_SECOND, dtNew.seconds); } } /* otherwise just undraw the old second hand and draw the new */ else if (fShowSecondHand && (cp.usDispMode & DM_SECONDHAND)) { GpiSetMix(hps, FM_INVERT); ClkDrawHand(hps, HT_SECOND, dt.seconds); ClkDrawHand(hps, HT_SECOND, dtNew.seconds); } dt = dtNew ; } else /*Must be Digital*/ { DrawDigitalTime(hwnd); } /* *if this is the first *time through init it */ if(!lTimeChangeCheck) { time(&lTimeChangeCheck); } /* *a quick check to see if *any other session *adjusted our time *if so reset the timer */ else { time(&lTime); /* *did the clock get changed by more than 60 seconds */ if( lTime > ( lTimeChangeCheck + 60L ) || lTimeChangeCheck > ( lTime + 60L ) ) { AlarmSetTimer(cp.alarm.uchHour, cp.alarm.uchMinutes); } lTimeChangeCheck = lTime; } }
/****************************************************************\ * *-------------------------------------------------------------- * * Name:ClkCommand() * * Purpose:Handle WM_COMMAND events. * * * * Usage: * * Method: * - * * - * - * * - * - * * Returns: * VOID * \****************************************************************/ VOID ClkCommand ( HWND hwnd , MPARAM mp1, MPARAM mp2 ) { DATETIME dtNew ; switch ( SHORT1FROMMP ( mp1 ) ) { case IDM_TICKS : WinDlgBox ( HWND_DESKTOP , hwndFrame , ClkTicksDlgProc , NULLHANDLE , IDD_TICKS , (PVOID )NULL ) ; break; case IDM_EXIT: /* *post the event semaphore *for our alarm thread */ fEndThread = TRUE; DosPostEventSem(TimerResources.hTimerDev); WinPostMsg(hwnd, WM_QUIT,MPVOID, MPVOID); break; case IDM_COLORS : WinDlgBox ( HWND_DESKTOP , hwndFrame ,ClkColorsDlgProc , NULLHANDLE , IDD_COLORS , NULL ) ; SetRGBColors(); ClkSize(hwnd); break ; case IDM_TOGGLECONTROLS : if (cp.fControlsHidden) { ClkShowFrameControls( hwndFrame ); } else { ClkHideFrameControls ( hwndFrame ) ; } break ; case IDM_DATETIME: if (hDateTime == NULLHANDLE) { WinDlgBox(HWND_DESKTOP,hwndFrame,TimeDlgProc, NULLHANDLE,IDD_TIME ,NULL); dt.minutes += 2; /*Fool the ClkTimer proc. It will now think it have to redraw*/ } else { WinSetFocus (HWND_DESKTOP, hDateTime); } break; case IDM_ALARM: if (hAlarmTime == (HWND)NULL) { WinDlgBox(HWND_DESKTOP,hwndFrame,AlarmDlgProc, NULLHANDLE,IDD_ALARM ,NULL); } else { WinSetFocus(HWND_DESKTOP,hAlarmTime); } break; case IDM_SECONDHAND: cp.usDispMode = ((cp.usDispMode & DM_SECONDHAND) ? (cp.usDispMode & (~DM_SECONDHAND)) : (cp.usDispMode | DM_SECONDHAND)); GpiSetMix(hps, FM_INVERT); /* * Depending on the current mode draw or remove the second hand. */ if (cp.usDispMode & DM_SECONDHAND) { DosGetDateTime(&dtNew); ClkDrawHand(hps, HT_SECOND, dtNew.seconds); dt.seconds = dtNew.seconds; } else { ClkDrawHand(hps, HT_SECOND, dt.seconds); } WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_SECONDHAND, TRUE), MPFROM2SHORT( MIA_CHECKED, ( (cp.usDispMode & DM_SECONDHAND)? MIA_CHECKED : ~MIA_CHECKED) ) ); break; case IDM_TIME: cp.usDispMode = ((cp.usDispMode & DM_TIME) ? (cp.usDispMode & (~DM_TIME)) : (cp.usDispMode | DM_TIME)); WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDM_TIME, TRUE), MPFROM2SHORT(MIA_CHECKED, ((cp.usDispMode & DM_TIME) ? MIA_CHECKED : ~MIA_CHECKED))); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_DATE, TRUE), MPFROM2SHORT( MIA_DISABLED, ( (!(cp.usDispMode & DM_TIME)) ? MIA_DISABLED : ~MIA_DISABLED) ) ); ClkSize(hwnd); WinInvalidateRect(hwnd, NULL, TRUE); break; case IDM_DATE: cp.usDispMode = ((cp.usDispMode & DM_DATE) ? (cp.usDispMode & (~DM_DATE)) : (cp.usDispMode | DM_DATE)); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_DATE, TRUE), MPFROM2SHORT( MIA_CHECKED, ( (cp.usDispMode & DM_DATE)? MIA_CHECKED : ~MIA_CHECKED) ) ); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_TIME, TRUE), MPFROM2SHORT( MIA_DISABLED, ( ((!(cp.usDispMode & DM_DATE)) || (cp.usDispMode & DM_ANALOG))? MIA_DISABLED : ~MIA_DISABLED) ) ); ClkSize(hwnd); WinInvalidateRect(hwnd,(PRECTL)NULL,TRUE); break; case IDM_DIGITAL: cp.usDispMode |= DM_DIGITAL; cp.usDispMode &= (~DM_ANALOG); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_DIGITAL, TRUE), MPFROM2SHORT( MIA_CHECKED, MIA_CHECKED)); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_ANALOG , TRUE), MPFROM2SHORT( MIA_CHECKED, ~MIA_CHECKED)); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_SECONDHAND, TRUE), MPFROM2SHORT( MIA_DISABLED, MIA_DISABLED)); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_TICKS, TRUE), MPFROM2SHORT( MIA_DISABLED, MIA_DISABLED)); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_TIME, TRUE), MPFROM2SHORT( MIA_DISABLED, ( ((!(cp.usDispMode & DM_DATE)) || (cp.usDispMode & DM_ANALOG))? MIA_DISABLED : ~MIA_DISABLED) ) ); WinInvalidateRect(hwnd,(PRECTL)NULL,TRUE); break; case IDM_ANALOG : cp.usDispMode |= DM_ANALOG; cp.usDispMode &= (~DM_DIGITAL); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_ANALOG, TRUE), MPFROM2SHORT( MIA_CHECKED, MIA_CHECKED)); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_DIGITAL, TRUE), MPFROM2SHORT( MIA_CHECKED, ~MIA_CHECKED)); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_TIME, TRUE), MPFROM2SHORT( MIA_DISABLED, MIA_DISABLED)); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_DATE, TRUE), MPFROM2SHORT( MIA_DISABLED, ~MIA_DISABLED)); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_SECONDHAND, TRUE), MPFROM2SHORT( MIA_DISABLED, ~MIA_DISABLED)); WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_TICKS, TRUE), MPFROM2SHORT( MIA_DISABLED, ~MIA_DISABLED)); cp.usDispMode |= DM_TIME; WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT( IDM_TIME, TRUE), MPFROM2SHORT( MIA_CHECKED, MIA_CHECKED)); WinInvalidateRect(hwnd,(PRECTL)NULL,TRUE); break; case IDM_HELPHELPFORHELP: HelpHelpForHelp(mp2); break; case IDM_HELPEXTENDED: HelpExtended(mp2); break; case IDM_HELPKEYS: HelpKeys(mp2); break; case IDM_HELPINDEX: HelpIndex(mp2); break; case IDM_HELPTUTORIAL: HelpTutorial(mp2); break; case IDM_HELPABOUT: HelpAbout(mp2); break; case IDM_ALARM_EXPIRED: WinMessageBox(HWND_DESKTOP, hwndFrame, (PSZ)"Alarm Expired", (PSZ)"The Bells Are Ringing", 0, MB_OK); break; } }
VOID PMfrWriteClipbrdBmp(HAB hab) { HDC hdcClip; /* memory DC and PS to extract from the clipboard */ HPS hpsClip; HBITMAP hbmClip; SIZEL sizl; BITMAPINFOHEADER bmp; ULONG _far *alRGBColors; LONG errorcode; char _far *fp1; char _far *fp2; int i; if (WinOpenClipbrd(hab)) { /* get the memory DC and PS to copy the bitmap */ hdcClip = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ; sizl.cx = cp.cx; sizl.cy = cp.cy; hpsClip = GpiCreatePS (hab, hdcClip, &sizl, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC); bmp.cbFix = sizeof bmp; bmp.cx = cp.cx; bmp.cy = cp.cy; bmp.cPlanes = cp.cPlanes; bmp.cBitCount = cp.cBitCount; hbmClip = GpiCreateBitmap (hpsClip, &bmp, 0L, NULL, NULL); GpiSetBitmap(hpsClip, hbmClip); /* initialize and black out the bitmap */ alRGBColors = (ULONG _far *) _fmalloc(sizeof(ULONG) * cp.colors); /* beginning of source array */ fp2 = (char _far *) &cp.pbmiMemory->argbColor[0]; /* beginning of dest array */ fp1 = (char _far *) &alRGBColors[0]; for (i = 0; i < cp.colors; i++) { /* copy base bytes for number of screen colors */ alRGBColors[i] = 0; _fmemcpy(fp1, fp2, sizeof(RGB) ); fp1 += sizeof(ULONG); fp2 += sizeof(RGB); } GpiSetMix ( hpsClip, FM_OVERPAINT) ; GpiSetBackMix (hpsClip, BM_LEAVEALONE) ; GpiCreateLogColorTable(hpsClip, LCOL_RESET | LCOL_REALIZABLE, LCOLF_CONSECRGB, 0L, cp.colors, alRGBColors); /* now copy the bits */ cp.pbmiMemory->cx = cp.cx; cp.pbmiMemory->cy = cp.cy; cp.pbmiMemory->cPlanes = cp.cPlanes; cp.pbmiMemory->cBitCount = cp.cBitCount; errorcode = GpiSetBitmapBits(hpsClip, 0L, (LONG) cp.cy, cp.pixels, cp.pbmiMemory); /* unlink the new bitmap */ GpiSetBitmap(hpsClip, (HBITMAP) NULL); /* write to the clipboard */ WinEmptyClipbrd (hab); WinSetClipbrdData (hab, (ULONG) hbmClip, CF_BITMAP, CFI_HANDLE); /* now clean up */ _ffree(alRGBColors); GpiDestroyPS(hpsClip); DevCloseDC(hdcClip); WinCloseClipbrd(hab); } }
MRESULT EXPENTRY ClientWndProc ( HWND hwndWnd, ULONG ulMsg, MPARAM mpParm1, MPARAM mpParm2 ) { switch ( ulMsg ) { // For HELP debugging #if 0 case HM_ERROR: { CHAR szTempBuffer[256]; sprintf( szTempBuffer, "Received HM_ERROR message, mp1=0X%8.8X", (ULONG)mpParm1 ); WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, szTempBuffer, "HM_ERROR", 0, MB_OK ); } break; case HM_EXT_HELP_UNDEFINED: WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, "Received HM_EXT_HELP_UNDEFINED message", "HM_EXT_HELP_UNDEFINED", 0, MB_OK ); break; case HM_HELPSUBITEM_NOT_FOUND: WinMessageBox ( HWND_DESKTOP, HWND_DESKTOP, "Received HM_HELPSUBITEM_NOT_FOUND message", "HM_HELPSUBITEM_NOT_FOUND", 0, MB_OK ); break; #endif case HM_QUERY_KEYS_HELP: return (MRESULT)IDP_KEYS_INFO; break; case WM_BUTTON1CLICK: MoveCursorToPointer( hwndWnd, (*(POINTS *)&mpParm1).x, (*(POINTS *)&mpParm1).y ); break; #if 0 case WM_BUTTON2CLICK: { HPS hpsClient; POINTL ptl; INT xC, yC; xC = ( ( (*(POINTS *)&mpParm1).x - cxChar) / cxChar ); yC = ( ( cyClient - (*(POINTS *)&mpParm1).y ) / cyChar ); hpsClient = WinGetPS( hwndWnd ); GpiSetColor( hpsClient, CLR_PALEGRAY ); if ( xC < 10 ) GpiSetMix( hpsClient, FM_XOR ); else if ( xC < 20 ) GpiSetMix( hpsClient, FM_INVERT ); else if ( xC < 30 ) GpiSetMix( hpsClient, FM_NOTXORSRC ); else if ( xC < 40 ) GpiSetMix( hpsClient, FM_NOTMASKSRC ); else if ( xC < 50 ) GpiSetMix( hpsClient, FM_SUBTRACT ); /// GpiSetBackColor( hpsClient, CLR_PALEGRAY ); /// GpiSetBackMix( hpsClient, BM_OVERPAINT ); /// ptl.x = ( ( (*(POINTS *)&mpParm1).x - cxChar ) / cxChar ) * cxChar + cxChar; /// ptl.y = ( ( (*(POINTS *)&mpParm1).y - cyClient ) / cyChar - 1 ) * cyChar + cyClient; ptl.x = cxChar + ( xC * cxChar ); ptl.y = cyClient - ( ( yC + 1) * cyChar ); GpiMove( hpsClient, &ptl ); ptl.x += cxChar; ptl.y += cyChar; if ( yC < 5 ) GpiBox( hpsClient, DRO_FILL, &ptl, 0, 0 ); else GpiBox( hpsClient, DRO_OUTLINE, &ptl, 0, 0 ); /// GpiSetBackColor( hpsClient, CLR_BACKGROUND ); /// GpiSetMix( hpsClient, FM_DEFAULT ); WinReleasePS( hpsClient ); } break; #endif case WM_CHAR: if ( !( CHARMSG(&ulMsg)->fs & KC_KEYUP ) ) { if ( CHARMSG(&ulMsg)->fs & KC_CHAR ) { ProcessCharMsg( hwndWnd, ulMsg, mpParm1, mpParm2 ); } else if ( CHARMSG(&ulMsg)->fs & KC_VIRTUALKEY ) { if ( !ProcessCursorMsg( hwndWnd, ulMsg, mpParm1, mpParm2 ) ) { return WinDefWindowProc( hwndWnd, ulMsg, mpParm1, mpParm2 ); } } } break; case WM_CLOSE: if ( QueryAbandonChanges( hwndWnd ) ) return WinDefWindowProc ( hwndWnd, ulMsg, mpParm1, mpParm2 ); break; case WM_COMMAND: return ProcessCommandMsg( hwndWnd, ulMsg, mpParm1, mpParm2 ); break; case WM_CREATE: hwndMenu = WinWindowFromID( WinQueryWindow( hwndWnd, QW_PARENT ), FID_MENU ); hwndHScroll = WinWindowFromID( WinQueryWindow( hwndWnd, QW_PARENT ), FID_HORZSCROLL ); hwndVScroll = WinWindowFromID( WinQueryWindow( hwndWnd, QW_PARENT ), FID_VERTSCROLL ); SetWindowTitle( hwndWnd ); break; case WM_DESTROY: ClearFile( hwndWnd ); break; case WM_ERASEBACKGROUND: return MRFROMSHORT ( TRUE ) ; case WM_HELP: ProcessHelpMessage( hwndWnd, mpParm1, mpParm2 ); break; case WM_HSCROLL: if ( !ProcessHScrollMsg( hwndWnd, ulMsg, mpParm1, mpParm2 ) ) return WinDefWindowProc( hwndWnd, ulMsg, mpParm1, mpParm2 ); break; case WM_PAINT: PaintScreen( hwndWnd ); break; case WM_SAVEAPPLICATION: SaveSettings( hwndWnd, habAnchor ); return WinDefWindowProc( hwndWnd, ulMsg, mpParm1, mpParm2 ); break; case WM_SETFOCUS: if ( SHORT1FROMMP( mpParm2 ) ) CreateCursor( hwndWnd ); else DestroyCursor( hwndWnd ); break; case WM_SIZE: UpdateWindowSize( hwndWnd, SHORT1FROMMP( mpParm2), SHORT2FROMMP( mpParm2 ) ); if ( hwndWnd == WinQueryFocus( HWND_DESKTOP ) ) { DestroyCursor( hwndWnd ); CreateCursor( hwndWnd ); } break; case WM_VSCROLL: if ( !ProcessVScrollMsg( hwndWnd, ulMsg, mpParm1, mpParm2 ) ) return WinDefWindowProc( hwndWnd, ulMsg, mpParm1, mpParm2 ); break; default: return WinDefWindowProc( hwndWnd, ulMsg, mpParm1, mpParm2 ); break; } return MRFROMSHORT ( FALSE ) ; }
// returns TRUE if a line has been painted BOOL GRAPHBOARD::OneLine( const HPS hps, POINTL from, POINTL to, INT time_on, INT time_off ) { if( from.x == to.x && from.y == to.y ) return FALSE; // nothing to do POINTL fromLeftTop, fromRightBot, fromRightTop, toLeftTop, toRightBot, toRightTop; const CHAR CenterOffset = 1, PointDist = 2; // 1 and 2 // from and to really are fromLeftBot and toLeftBot from.x -= CenterOffset; fromLeftTop.x = from.x; from.y -= CenterOffset; fromRightBot.y = from.y; to.x -= CenterOffset; toLeftTop.x = to.x; to.y -= CenterOffset; toRightBot.y = to.y; fromRightTop.y = fromLeftTop.y = from.y + PointDist; fromRightTop.x = fromRightBot.x = from.x + PointDist; toRightTop.y = toLeftTop.y = to.y + PointDist; toRightTop.x = toRightBot.x = to.x + PointDist; if( (from.x < to.x && from.y < to.y ) || ( from.x > to.x && from.y > to.y ) ){ // if the diagonal is painted from lower left to upper right, // do an exchange from <-> fromLeftTop and to <-> toLeftTop. // this is necessary for nicer painting // so in this case from is fromLeftTop and fromLeftTop is fromLeftBot from.x += PointDist; fromRightBot.x -= PointDist; to.x += PointDist; toRightBot.x -= PointDist; } GpiBeginPath( hps, 1L ); GpiMove( hps, &from ); GpiLine( hps, &to ); GpiLine( hps, &toRightBot ); GpiLine( hps, &fromRightBot ); GpiLine( hps, &from ); GpiLine( hps, &to ); GpiLine( hps, &toRightTop ); GpiLine( hps, &fromRightTop ); GpiLine( hps, &from ); GpiLine( hps, &to ); GpiLine( hps, &toLeftTop ); GpiLine( hps, &fromLeftTop ); GpiLine( hps, &from ); GpiEndPath( hps ); GpiSetColor( hps, CLR_BLUE ); GpiSetMix( hps, FM_XOR ); GpiFillPath ( hps, 1L, FPATH_WINDING ); if( time_on ){ // if the line will be visible for a short while and then rem. DosSleep( time_on ); GpiBeginPath( hps, 1L ); GpiMove( hps, &from ); GpiLine( hps, &to ); GpiLine( hps, &toRightBot ); GpiLine( hps, &fromRightBot ); GpiLine( hps, &from ); GpiLine( hps, &to ); GpiLine( hps, &toRightTop ); GpiLine( hps, &fromRightTop ); GpiLine( hps, &from ); GpiLine( hps, &to ); GpiLine( hps, &toLeftTop ); GpiLine( hps, &fromLeftTop ); GpiLine( hps, &from ); GpiEndPath( hps ); GpiFillPath ( hps, 1L, FPATH_WINDING ); // remove it if( time_off ) DosSleep( time_off ); // wait after removing the line } return TRUE; // line(s) has / have been painted }