Пример #1
0
void Interface::Mousemove(QMouseEvent *e)           /* mouse start */
{
    
    if (CTRL_Pressed && moverecci && TagliaPoi.width() > 10) {
    moverecci = true; 
    CTRL_Pressed = true;
    
    setCursor(Qt::ClosedHandCursor); 
        
        
        QRect TMPrect = TagliaPoi;
        
        Dmove = ScalePoint(e->pos());
        
        Dmove.setX(Dmove.x() - (TMPrect.width() / 2));
        Dmove.setY(Dmove.y() - (TMPrect.height() / 2));
        TMPrect.moveTo(Dmove);
        DisegnaRect(TMPrect.topLeft(),TMPrect.bottomRight());
        //////////////qDebug() << "####### TMPrect.width()  " << TMPrect.height() <<  " TMPrect.width() " << TMPrect.width(); 
        //////////////////qDebug() << "####### TagliaPoi  " << TagliaPoi; 
    return;
    }
    
    
     if (Dstart.x() > 0 ) {   
             Dstop = ScalePoint(e->pos());
             DisegnaRect(Dstart,Dstop);
            setCursor(Qt::CrossCursor);
            moverecci = false; 
            CTRL_Pressed = false;
    } 
}
Пример #2
0
// Cut a single draw set
int LicutSVG::CutDrawSet( LicutIO& lio, int set, int x, int y, int width, int height )
{
	if (set < 0 || set >= m_drawSetCount) return -1;
	SetScaling( x, y, width, height );
	int oldVerbose = lio.GetVerbose();
	lio.SetVerbose( m_verbose );
	int n;
	int send_res, reply_res;
	unsigned int lastX, lastY, curX, curY, ctl1X, ctl1Y, ctl2X, ctl2Y;
	lastX = x;
	lastY = y;
	lio.Drain( m_intercommand * 6, m_verbose );
	for (n = 0; m_drawSets[set][n].type != 0; n++)
	{
		switch (m_drawSets[set][n].type)
		{
			case 'M':	// Move
				ScalePoint( m_drawSets[set][n].pt[0], lastX, lastY );
				send_res = lio.SendCmd_MoveCut( 2, lastX, lastY );
				reply_res = lio.ReadCmdReply( m_verbose );
				lio.Drain( m_verbose, m_intercommand );
				break;
			case 'L':	// Straight line from previous point
				ScalePoint( m_drawSets[set][n].pt[0], lastX, lastY );
				send_res = lio.SendCmd_MoveCut( 0, lastX, lastY );
				reply_res = lio.ReadCmdReply( m_verbose );
				lio.Drain( m_verbose, m_intercommand );
				break;
			case 'C':	// Bezier curve from previous point
				ScalePoint( m_drawSets[set][n].pt[0], ctl1X, ctl1Y );
				ScalePoint( m_drawSets[set][n].pt[1], ctl2X, ctl2Y );
				ScalePoint( m_drawSets[set][n].pt[2], curX, curY );
				// Bezier curve data are sent in sets of 4
				send_res = lio.SendCmd_MoveCut( 1, lastX, lastY );
				reply_res = lio.ReadCmdReply( m_verbose );
				lio.Drain( m_verbose, m_intercurve ); // Very short wait to drain since no physical movement required
				send_res = lio.SendCmd_MoveCut( 1, ctl1X, ctl1Y );
				reply_res = lio.ReadCmdReply( m_verbose );
				lio.Drain( m_verbose, m_intercurve ); // Very short wait to drain since no physical movement required
				send_res = lio.SendCmd_MoveCut( 1, ctl2X, ctl2Y );
				reply_res = lio.ReadCmdReply( m_verbose );
				lio.Drain( m_verbose, m_intercurve ); // Very short wait to drain since no physical movement required
				send_res = lio.SendCmd_MoveCut( 1, curX, curY );
				reply_res = lio.ReadCmdReply( m_verbose );
				lio.Drain( m_verbose, m_intercommand );
				lastX = curX;
				lastY = curY;
				break;
			default:
				printf( "%s(..., %d...) warning: unhandled cut type %c at index %d\n",
					__FUNCTION__, set, m_drawSets[set][n].type, n );
				break;
		}
	}
	lio.SetVerbose( oldVerbose );
	// Return number of sets executed
	return n;
}
Пример #3
0
//-----------------------------------------------------------------------------
//
//	Surf3 series
//
//-----------------------------------------------------------------------------
long mglGraph::add_spoint(long &pc,mreal **p,mreal **k,mreal **b,mreal **n,
			mreal x,mreal y,mreal z,mreal nx,mreal ny,mreal nz,
			mreal k1,mreal k2,mreal k3,mreal a)
{
	static long pMax=0;
	if(!ScalePoint(x,y,z) || a==0)	return -1;
	mglColor c;
	if(OnCoord)	c = GetC(x,y,z);
	else		c = Pal[100];
	if(!(*p))
	{
		pMax = 100;	pc = 0;
		*p = (mreal *)malloc(3*pMax*sizeof(mreal));
		*n = (mreal *)malloc(3*pMax*sizeof(mreal));
		*k = (mreal *)malloc(3*pMax*sizeof(mreal));
		*b = (mreal *)malloc(4*pMax*sizeof(mreal));
	}
	b[0][4*pc] = c.r;	b[0][4*pc+1] = c.g;	b[0][4*pc+2] = c.b;
	b[0][4*pc+3] = Transparent ? a : 1;
	p[0][3*pc] = x;		p[0][3*pc+1] = y;	p[0][3*pc+2] = z;
	n[0][3*pc] = nx;	n[0][3*pc+1] = ny;	n[0][3*pc+2] = nz;
	k[0][3*pc] = k1;	k[0][3*pc+1] = k2;	k[0][3*pc+2] = k3;
	pc++;
	if(pc>=pMax)
	{
		pMax += 100;
		*p = (mreal *)realloc(*p,3*pMax*sizeof(mreal));
		*n = (mreal *)realloc(*n,3*pMax*sizeof(mreal));
		*k = (mreal *)realloc(*k,3*pMax*sizeof(mreal));
		*b = (mreal *)realloc(*b,4*pMax*sizeof(mreal));
	}
	return pc-1;
}
Пример #4
0
void GPSView::RefreshBackground(){

	int w,h ;
	GetClientSize(&w,&h);

	if (w != _currentWidth || h != _currentHeight){
		delete (_memBitmap);
		_currentWidth = w;
		_currentHeight = h;
		_memBitmap = new wxBitmap(_currentWidth, _currentHeight);
	}

	/////////////////
	// Create a memory DC
	wxMemoryDC dc;
	dc.SelectObject(*_memBitmap);

	wxColor backColor = *wxBLACK;
	dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(backColor,wxSOLID));
	dc.SetBrush(*wxTheBrushList->FindOrCreateBrush(backColor,wxSOLID));
	dc.Clear();

	dc.SetPen(*wxThePenList->FindOrCreatePen(*wxLIGHT_GREY, 1, wxSOLID));

	Point centerPoint = GetCenterPoint(_currentWidth, _currentHeight);
	int currentSize = GetDominantSize(_currentWidth, _currentHeight);

	Point minPoint = ScalePoint(m_minPoint, h);
	Point maxPoint = ScalePoint(m_maxPoint, h);

	Point lastZoomedPoint;
	for (size_t i = 0; i < m_trackPoints.size(); i++){
		Point point = m_trackPoints[i];
		Point offsetPoint = OffsetPoint(point);
		Point scaledPoint = ScalePoint(offsetPoint, h);
		Point zoomedPoint = ZoomPoint(scaledPoint, centerPoint, minPoint, maxPoint, currentSize, m_zoom);
		if (0 == i){
			lastZoomedPoint = zoomedPoint;
		}
		else{
			dc.DrawLine(lastZoomedPoint.x, lastZoomedPoint.y, zoomedPoint.x, zoomedPoint.y);
			lastZoomedPoint = zoomedPoint;
		}
	}
    Refresh();
}
Пример #5
0
//-----------------------------------------------------------------------------
//
//	CloudP series
//
//-----------------------------------------------------------------------------
void mglGraph::AVertex(mreal x,mreal y,mreal z, mreal a,mreal alpha)
{
	mglColor c;
	if(!ScalePoint(x,y,z) || isnan(a))	return;
	a = GetA(a);
	if(OnCoord)	c = GetC(x,y,z);
	else		c = GetC(a,false);
	a = alpha>0 ? (a+1)*(a+1)/4 : -(a-1)*(a-1)/4;
//	a = alpha>0 ? (a+1)/2 : (a-1)/2;
	if(a)	Ball(x,y,z,c,-alpha*a);
}
Пример #6
0
void GPSView::OnPaint( wxPaintEvent& event )
{
	wxPaintDC mainDc(this);

	wxMemoryDC dc;
	dc.SelectObject(*_memBitmap);

	//blit into the real DC
	mainDc.Blit(0,0,_currentWidth,_currentHeight,&dc,0,0);

	Point centerPoint = GetCenterPoint(_currentWidth, _currentHeight);
	int currentSize = GetDominantSize(_currentWidth, _currentHeight);
	Point minPoint = ScalePoint(m_minPoint, _currentHeight);
	Point maxPoint = ScalePoint(m_maxPoint, _currentHeight);

    mainDc.SetPen(*wxThePenList->FindOrCreatePen(*wxRED, 10, wxSOLID));
	mainDc.SetBrush(*wxTheBrushList->FindOrCreateBrush(*wxRED,wxSOLID));
    Point offsetMarker = OffsetPoint(m_marker);
    Point scaledMarker = ScalePoint(offsetMarker, _currentHeight);
    Point zoomedPoint = ZoomPoint(scaledMarker, centerPoint, minPoint, maxPoint, currentSize, m_zoom);
    mainDc.DrawCircle(wxPoint(zoomedPoint.x, zoomedPoint.y), 4);
}
Пример #7
0
void Interface::Mousepress(QMouseEvent *e)           /* mouse start */
{
    if (CTRL_Pressed) { 
    setCursor(Qt::OpenHandCursor); 
    return;
    }
    
    
    Dstart = QPoint(0,0);
    if (e->button() == Qt::LeftButton && !CTRL_Pressed) {   
        Dstart = ScalePoint(e->pos());
            setCursor(Qt::CrossCursor);
            moverecci = false; 
            CTRL_Pressed = false;
    }
}
Пример #8
0
VOID DrawHand (HPS hps, POINTL aptlIn[], INT iNum, INT iAngle,
               PWINDOWINFO pwi)
     {
     INT    iIndex ;
     POINTL aptl [5] ;

     for (iIndex = 0 ; iIndex < iNum ; iIndex++)
          aptl [iIndex] = aptlIn [iIndex] ;

     RotatePoint    (aptl, iNum, iAngle) ;
     ScalePoint     (aptl, iNum, pwi) ;
     TranslatePoint (aptl, iNum, pwi) ;

     GpiMove (hps, aptl) ;
     GpiPolyLine (hps, iNum - 1L, aptl + 1) ;
     }
Пример #9
0
void HandViewer::DisplayPostDraw()
{
	const PointListHandler& handler = handTracker.GetPointListHandler();

	XnFloat	coordinates[3 * SIZE_OF_POINT_LIST];
	
	for(PointListHandler::ConstIterator it = handler.begin(); it != handler.end(); ++it)
	{
		int	numpoints = 0;
		const PointList &pointList = it.GetPointList();
		
		XnPoint3D point;
			
		for(PointList::ConstIterator it2 = pointList.begin(); it2 != pointList.end(); ++it2)
		{
			point = *it2;
			depthGenerator.ConvertRealWorldToProjective(1, &point, &point);
			ScalePoint(point);
			coordinates[numpoints * 3] = point.X;
			coordinates[numpoints * 3 + 1] = point.Y;
			if(point.Z < HAND_CLOSE)
				coordinates[numpoints * 3 + 2] = 0;
			else
				coordinates[numpoints * 3 + 2] = point.Z;

			++numpoints;
		}
		assert(numpoints <= Constants::SIZE_OF_POINT_LIST);

		//Draw all points
		XnUInt32 nColor = it.GetKey() % LENGTHOF(COLOURS);
		glColor4f(COLOURS[nColor][0], COLOURS[nColor][1], COLOURS[nColor][2], 1.0f);
		glPointSize(3);
		glVertexPointer(3, GL_FLOAT, 0, coordinates);
		glDrawArrays(GL_LINE_STRIP, 0, numpoints);
		
		//Draw current point as a larger dot
		glPointSize(10);
		glDrawArrays(GL_POINTS, 0, 1);

		glFlush();
	}
}
Пример #10
0
const XnPoint3D HandViewer::DisplayPostDraw()
{
	typedef TrailHistory			History;
	typedef History::ConstIterator	HistoryIterator;
	typedef History::Trail			Trail;
	typedef Trail::ConstIterator	TrailIterator;

	static const float colours[][3] =
	{
		//{ 0.5f, 0.5f, 0.5f},
		{ 0.0f, 1.0f, 0.0f}//,
		//{ 0.0f, 0.5f, 1.0f},
		//{ 1.0f, 1.0f, 0.0f},
		//{ 1.0f, 0.5f, 0.0f},
		//{ 1.0f, 0.0f, 1.0f}
	};
	const TrailHistory&	history = m_HandTracker.GetHistory();

	// History points coordinates buffer
	XnFloat	coordinates[3 * MAX_HAND_TRAIL_LENGTH];

	const HistoryIterator	hend = history.end();
	for(HistoryIterator		hit = history.begin(); hit != hend; ++hit)
	{

		// Dump the history to local buffer
		int				numpoints = 0;
		const Trail&	trail = hit.GetTrail();
		const TrailIterator	tend = trail.end();
		
		XnPoint3D point;
		
		for(TrailIterator	tit = trail.begin(); tit != tend; ++tit)
		{
			point = *tit;
			m_depth.ConvertRealWorldToProjective(1, &point, &point);
			ScalePoint(point);
			coordinates[numpoints * 3] = point.X;
			coordinates[numpoints * 3 + 1] = point.Y;
			coordinates[numpoints * 3 + 2] = 0;

			++numpoints;
		}
		assert(numpoints <= MAX_HAND_TRAIL_LENGTH);

		// Draw the hand trail history
		XnUInt32 nColor = hit.GetKey() % LENGTHOF(colours);
		glColor4f(colours[nColor][0],
			colours[nColor][1],
			colours[nColor][2],
			1.0f);
		glPointSize(3);
		glVertexPointer(3, GL_FLOAT, 0, coordinates);
		glDrawArrays(GL_LINE_STRIP, 0, numpoints);
		
		// Current point as a larger dot
		glPointSize(10);
		glDrawArrays(GL_POINTS, 0, 1);
		glFlush();
		
		point.X = coordinates[0];
		point.Y = coordinates[1];
		point.Z = coordinates[2];
		return point;
	}
}
Пример #11
0
void HandViewer::DisplayPostDraw()
{
	typedef TrailHistory			History;
	typedef History::ConstIterator	HistoryIterator;
	typedef Trail::ConstIterator	TrailIterator;

	static const float colours[][3] =
	{
		{ 0.5f, 0.5f, 0.5f},
		{ 0.0f, 1.0f, 0.0f},
		{ 0.0f, 0.5f, 1.0f},
		{ 1.0f, 1.0f, 0.0f},
		{ 1.0f, 0.5f, 0.0f},
		{ 1.0f, 0.0f, 1.0f}
	};
	const TrailHistory&	history = m_HandTracker.GetHistory();

	// History points coordinates buffer
	XnFloat	coordinates[3 * MAX_HAND_TRAIL_LENGTH];

	const HistoryIterator	hend = history.End();
	for(HistoryIterator		hit = history.Begin(); hit != hend; ++hit)
	{

		// Dump the history to local buffer
		int				numpoints = 0;
		const Trail&	trail = hit->Value();

		const TrailIterator	tend = trail.End();
		for(TrailIterator	tit = trail.Begin(); tit != tend; ++tit)
		{
			XnPoint3D	point = *tit;
			m_depth.ConvertRealWorldToProjective(1, &point, &point);
			ScalePoint(point);
			coordinates[numpoints * 3] = point.X;
			coordinates[numpoints * 3 + 1] = point.Y;
			coordinates[numpoints * 3 + 2] = 0;
			std::cout << point.X << ',' << point.Y << std::endl;
			handX = &point.X;
			handY = &point.Y;
			++numpoints;
		}
		assert(numpoints <= MAX_HAND_TRAIL_LENGTH);

		// Draw the hand trail history
		XnUInt32 nColor = hit->Key() % LENGTHOF(colours);
		glColor4f(colours[nColor][0],
			colours[nColor][1],
			colours[nColor][2],
			1.0f);
		glPointSize(2);
		glVertexPointer(3, GL_FLOAT, 0, coordinates);
		//glDrawArrays(GL_LINE_STRIP, 0, numpoints);
		// Current point as a larger dot
		glPointSize(50);
		glDrawArrays(GL_POINTS, 0, 1);
		glColor4f(1,0,0,1);
		for(int i = 1; i <= 13; i++){
			glBegin(GL_LINE_LOOP);
		    glVertex2f( 3 + (i-1)*GL_WIN_SIZE_X/13, GL_WIN_SIZE_Y - 200 );
		    glVertex2f( 3 + (i-1)*GL_WIN_SIZE_X/13, GL_WIN_SIZE_Y );
		    glVertex2f( 3 + i*GL_WIN_SIZE_X/13, GL_WIN_SIZE_Y );
		    glVertex2f( 3 + i*GL_WIN_SIZE_X/13, GL_WIN_SIZE_Y - 200 );
		    glEnd();
		}
		// Play Notes
		//C1
		if((*handX<GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){ 
				//int out = system("aplay ~/Documents/C1.wav");
				std::thread music(playNote,0);
				music.detach();
				inside = true;
			}
		//C#
		else if((*handX>GL_WIN_SIZE_X/13)&&(*handX<2*GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){
				//int out = system("aplay ~/Documents/C#.wav");
				std::thread music(playNote,1);
				music.detach();
				inside = true;
			}
		//D
		else if((*handX>2*GL_WIN_SIZE_X/13)&&(*handX<3*GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){
				//int out = system("aplay ~/Documents/D.wav");
				std::thread music(playNote,2);
				music.detach();
				inside = true;
			}
		//D#
		else if((*handX>3*GL_WIN_SIZE_X/13)&&(*handX<4*GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){
				//int out = system("aplay ~/Documents/D#.wav");
				std::thread music(playNote,3);
				music.detach();
				inside = true;
			}
		//E
		else if((*handX>4*GL_WIN_SIZE_X/13)&&(*handX<5*GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){
				//int out = system("aplay ~/Documents/E.wav");
				std::thread music(playNote,4);
				music.detach();
				inside = true;
			}
		//F
		else if((*handX>5*GL_WIN_SIZE_X/13)&&(*handX<6*GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){
				//int out = system("aplay ~/Documents/F.wav");
				std::thread music(playNote,5);
				music.detach();
				inside = true;
			}
		//F#
		else if((*handX>6*GL_WIN_SIZE_X/13)&&(*handX<7*GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){
				//int out = system("aplay ~/Documents/F#.wav");
				std::thread music(playNote,6);
				music.detach();
				inside = true;
			}
		//G
		else if((*handX>7*GL_WIN_SIZE_X/13)&&(*handX<8*GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){
				//int out = system("aplay ~/Documents/G.wav");
				std::thread music(playNote,7);
				music.detach();
				inside = true;
			}
		//G#
		else if((*handX>8*GL_WIN_SIZE_X/13)&&(*handX<9*GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){
				//int out = system("aplay ~/Documents/G#.wav");
				std::thread music(playNote,8);
				music.detach();
				inside = true;
			}
		//A
		else if((*handX>9*GL_WIN_SIZE_X/13)&&(*handX<10*GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){
				//int out = system("aplay ~/Documents/A.wav");
				std::thread music(playNote,9);
				music.detach();
				inside = true;
			}
		//A#
		else if((*handX>10*GL_WIN_SIZE_X/13)&&(*handX<11*GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){
				//int out = system("aplay ~/Documents/A#.wav");
				std::thread music(playNote,10);
				music.detach();
				inside = true;
			}
		//B
		else if((*handX>11*GL_WIN_SIZE_X/13)&&(*handX<12*GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){
				//int out = system("aplay ~/Documents/B.wav");
				std::thread music(playNote,11);
				music.detach();
				inside = true;
			}
		//C2
		else if((*handX>12*GL_WIN_SIZE_X/13)&&(*handX<13*GL_WIN_SIZE_X/13)&&(*handY>GL_WIN_SIZE_Y-200)&&(inside==false)){
				//int out = system("aplay ~/Documents/C2.wav");
				std::thread music(playNote,12);
				music.detach();
				inside = true;
			}
		else if((*handY<GL_WIN_SIZE_Y-200)&&(inside==true)){
				inside = false;
			}	
		glFlush();
	}
}
Пример #12
0
MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
     {
     static DATETIME   dtPrevious ;
     static HDC        hdc ;
     static LONG       xPixelsPerMeter, yPixelsPerMeter ;
     static POINTL     aptlHour   [5] = { 0,-15, 10,0, 0,60, -10,0, 0,-15 },
                       aptlMinute [5] = { 0,-20,  5,0, 0,80,  -5,0, 0,-20 },
                       aptlSecond [2] = { 0,  0,  0,80 } ;
     static WINDOWINFO wi ;
     DATETIME          dt ;
     HPS               hps ;
     INT               iDiamMM, iAngle ;
     POINTL            aptl [3] ;

     switch (msg)
          {
          case WM_CREATE:
               hdc = WinOpenWindowDC (hwnd) ;

               DevQueryCaps (hdc, CAPS_VERTICAL_RESOLUTION,
                                  1L, &yPixelsPerMeter) ;
               DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION,
                                  1L, &xPixelsPerMeter) ;

               DosGetDateTime (&dtPrevious) ;
               dtPrevious.hours = (dtPrevious.hours * 5) % 60 +
                                   dtPrevious.minutes / 12 ;
               return 0 ;

          case WM_SIZE:
               wi.cxClient = SHORT1FROMMP (mp2) ;
               wi.cyClient = SHORT2FROMMP (mp2) ;

               iDiamMM = min (wi.cxClient * 1000L / xPixelsPerMeter,
                              wi.cyClient * 1000L / yPixelsPerMeter) ;

               wi.cxPixelDiam = xPixelsPerMeter * iDiamMM / 1000 ;
               wi.cyPixelDiam = yPixelsPerMeter * iDiamMM / 1000 ;
               return 0 ;

          case WM_TIMER:
               DosGetDateTime (&dt) ;
               dt.hours = (dt.hours * 5) % 60 + dt.minutes / 12 ;

               hps = WinGetPS (hwnd) ;
               GpiSetColor (hps, CLR_BACKGROUND) ;

               DrawHand (hps, aptlSecond, 2, dtPrevious.seconds, &wi) ;

               if (dt.hours   != dtPrevious.hours ||
                   dt.minutes != dtPrevious.minutes)
                    {
                    DrawHand (hps, aptlHour,   5, dtPrevious.hours,   &wi) ;
                    DrawHand (hps, aptlMinute, 5, dtPrevious.minutes, &wi) ;
                    }

               GpiSetColor (hps, CLR_NEUTRAL) ;

               DrawHand (hps, aptlHour,   5, dt.hours,   &wi) ;
               DrawHand (hps, aptlMinute, 5, dt.minutes, &wi) ;
               DrawHand (hps, aptlSecond, 2, dt.seconds, &wi) ;

               WinReleasePS (hps) ;
               dtPrevious = dt ;
               return 0 ;

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

               for (iAngle = 0 ; iAngle < 60 ; iAngle++)
                    {
                    aptl[0].x = 0 ;
                    aptl[0].y = 90 ;

                    RotatePoint    (aptl, 1, iAngle) ;
                    ScalePoint     (aptl, 1, &wi) ;
                    TranslatePoint (aptl, 1, &wi) ;

                    aptl[2].x = aptl[2].y = iAngle % 5 ? 2 : 10 ;

                    ScalePoint (aptl + 2, 1, &wi) ;

                    aptl[0].x -= aptl[2].x / 2 ;
                    aptl[0].y -= aptl[2].y / 2 ;

                    aptl[1].x = aptl[0].x + aptl[2].x ;
                    aptl[1].y = aptl[0].y + aptl[2].y ;

                    GpiMove (hps, aptl) ;
                    GpiBox (hps, DRO_OUTLINEFILL, aptl + 1,
                                 aptl[2].x, aptl[2].y) ;
                    }
               DrawHand (hps, aptlHour,   5, dtPrevious.hours,   &wi) ;
               DrawHand (hps, aptlMinute, 5, dtPrevious.minutes, &wi) ;
               DrawHand (hps, aptlSecond, 2, dtPrevious.seconds, &wi) ;

               WinEndPaint (hps) ;
               return 0 ;
          }
     return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
     }