C/C++ Windows API

Moderators: Lundin
Number of threads: 450
Number of posts: 1225

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
Is the a way to rotate a line clockwise? Posted by Sonx_hvn7 on 22 Apr 2008 at 6:44 AM
I tried writing these functions but no good output. Output window freezes and line does not rotate..

case WM_PAINT:
                while (cntr++ < 180)
		{ 
		DrawLine(hdc, ptCenter, SetPOINT(ptCenter, radius), 255, 128, 128);
		Sleep(2000);
		}
		break;
	
.........


void DrawLine(HDC hdc, POINT ptCenter, POINT coord, int R, int G, int B)
{
	HPEN pen, oldPen;

	pen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));	
	oldPen = (HPEN)SelectObject(hdc, pen);				

	MoveToEx(hdc, ptCenter.x,ptCenter.y, NULL);		
	LineTo(hdc, coord.x, coord.y);					

	SelectObject(hdc, oldPen); 				
	DeleteDC(hdc);										
}

/* Calculate the line points */
POINT SetPOINT(POINT ptCenter, LONG radius)
{
	const float Deg2Rad = 0.017453292;
	POINT coord;
	static int angle=0;
	float degInRad;

	degInRad = angle*Deg2Rad	   // Convert degrees to radians
	coord.x = ptCenter.x + (cos(degInRad)*(float)radius); // Finds the adjacent value
	coord.y = ptCenter.x - (sin(degInRad)*(float)radius);	// Finds the hypotenuse value
	angle-=5;            // Prepare for the next line position (clockwise direction)

	return coord;
}

Report
Re: Is the a way to rotate a line clockwise? Posted by IDK on 22 Apr 2008 at 8:41 AM
You'll need to move the loop outside of the paint function.

Simply refresh your window with a timer.
Report
Re: Is the a way to rotate a line clockwise? Posted by AsmGuru62 on 22 Apr 2008 at 5:07 PM
: I tried writing these functions but no good output. Output window
: freezes and line does not rotate..
:
:
: 
: case WM_PAINT:
:                 while (cntr++ < 180)
: 		{ 
: 		DrawLine(hdc, ptCenter, SetPOINT(ptCenter, radius), 255, 128, 128);
: 		Sleep(2000);
: 		}
: 		break;
: 	
: .........
: 
: 
: void DrawLine(HDC hdc, POINT ptCenter, POINT coord, int R, int G, int B)
: {
: 	HPEN pen, oldPen;
: 
: 	pen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));	
: 	oldPen = (HPEN)SelectObject(hdc, pen);				
: 
: 	MoveToEx(hdc, ptCenter.x,ptCenter.y, NULL);		
: 	LineTo(hdc, coord.x, coord.y);					
: 
: 	SelectObject(hdc, oldPen); 				
: 	DeleteObject(pen);
: }
: 
: /* Calculate the line points */
: POINT SetPOINT(POINT ptCenter, LONG radius)
: {
: 	const float Deg2Rad = 0.017453292;
: 	POINT coord;
: 	static int angle=0;
: 	float degInRad;
: 
: 	degInRad = angle*Deg2Rad	   // Convert degrees to radians
: 	coord.x = ptCenter.x + (cos(degInRad)*(float)radius); // Finds the adjacent value
: 	coord.y = ptCenter.x - (sin(degInRad)*(float)radius);	// Finds the hypotenuse value
: 	angle-=5;            // Prepare for the next line position (clockwise direction)
: 
: 	return coord;
: }
: 
:
:
How the hdc was obtained? Unless you created it - you cannot call DeleteDC() on it. If you got it from BeginPaint() - you must call EndPaint(). This is the only proper way to respond to WM_PAINT.
Report
Re: Is the a way to rotate a line clockwise? Posted by Sonx_hvn7 on 23 Apr 2008 at 1:03 AM
: : I tried writing these functions but no good output. Output window
: : freezes and line does not rotate..
: :
: :
: : 
: : case WM_PAINT:
: :                 while (cntr++ < 180)
: : 		{ 
: : 		DrawLine(hdc, ptCenter, SetPOINT(ptCenter, radius), 255, 128, 128);
: : 		Sleep(2000);
: : 		}
: : 		break;
: : 	
: : .........
: : 
: : 
: : void DrawLine(HDC hdc, POINT ptCenter, POINT coord, int R, int G, int B)
: : {
: : 	HPEN pen, oldPen;
: : 
: : 	pen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));	
: : 	oldPen = (HPEN)SelectObject(hdc, pen);				
: : 
: : 	MoveToEx(hdc, ptCenter.x,ptCenter.y, NULL);		
: : 	LineTo(hdc, coord.x, coord.y);					
: : 
: : 	SelectObject(hdc, oldPen); 				
: : 	DeleteObject(pen);
: : }
: : 
: : /* Calculate the line points */
: : POINT SetPOINT(POINT ptCenter, LONG radius)
: : {
: : 	const float Deg2Rad = 0.017453292;
: : 	POINT coord;
: : 	static int angle=0;
: : 	float degInRad;
: : 
: : 	degInRad = angle*Deg2Rad	   // Convert degrees to radians
: : 	coord.x = ptCenter.x + (cos(degInRad)*(float)radius); // Finds the adjacent value
: : 	coord.y = ptCenter.x - (sin(degInRad)*(float)radius);	// Finds the hypotenuse value
: : 	angle-=5;            // Prepare for the next line position (clockwise direction)
: : 
: : 	return coord;
: : }
: : 
: :
: :
: How the hdc was obtained? Unless you created it - you
: cannot call DeleteDC() on it. If you got it from BeginPaint() - you
: must call EndPaint(). This is the only proper way to respond to
: WM_PAINT.


This is my updated code

case WM_PAINT:
          {
              hdc = BeginPaint(hWnd, &ps);
	      Win32APIGDICircle (hdc, radius, ptCenter, 0, 255, 128);
	      Win32APIGDICircle (hdc, radius-50, ptCenter, 128, 255, 128);
	      Win32APIGDICircle (hdc, radius-100, ptCenter, 255, 255, 255);
  	      
              // draw and rotate the line
	      for(static int x=0;x<180;x++){
		POINT coord = SetPOINT(ptCenter, radius);

		pen = CreatePen(PS_SOLID, 2, RGB(128, 255, 128));	
		oldPen = (HPEN)SelectObject(hdc, pen);				

		MoveToEx(hdc, ptCenter.x,ptCenter.y, NULL);		
		LineTo(hdc, coord.x, coord.y);

		Sleep(50);	// 2 secs for every rotations
	      }

	      SelectObject(hdc, oldPen); 				
	      DeleteObject(pen);
	      EndPaint(hWnd, &ps);

	      break;
          }


... how do i erase the previous line, currently all lines show forming a complete circle?


Report
Re: Is the a way to rotate a line clockwise? Posted by AsmGuru62 on 23 Apr 2008 at 4:11 AM
: This is my updated code
:
:
: 
: case WM_PAINT:
:           {
:               hdc = BeginPaint(hWnd, &ps);
: 	      Win32APIGDICircle (hdc, radius, ptCenter, 0, 255, 128);
: 	      Win32APIGDICircle (hdc, radius-50, ptCenter, 128, 255, 128);
: 	      Win32APIGDICircle (hdc, radius-100, ptCenter, 255, 255, 255);
:   	      
:               // draw and rotate the line
: 	      for(static int x=0;x<180;x++){
: 		POINT coord = SetPOINT(ptCenter, radius);
: 
: 		pen = CreatePen(PS_SOLID, 2, RGB(128, 255, 128));	
: 		oldPen = (HPEN)SelectObject(hdc, pen);				
: 		// These two ^^^ lines should be moved out before FOR() statement 

: 		MoveToEx(hdc, ptCenter.x,ptCenter.y, NULL);		
: 		LineTo(hdc, coord.x, coord.y);
: 
: 		Sleep(50);	// 2 secs for every rotations
: 	      }
: 
: 	      SelectObject(hdc, oldPen); 				
: 	      DeleteObject(pen);
: 	      EndPaint(hWnd, &ps);
: 
: 	      break;
:           }
: 
:
The code in RED will fix some resource leaks, but to make the process of really rotating a line - you need a timer or a thread. Try timer first:

1. Create a timer (SetTimer() API) when your window is receving WM_CREATE
2. Destroy created timer (KillTimer() API) when your window is receving WM_DESTROY
3. Make a case WM_TIMER in your window procedure
4. You need to draw a line, so current line coordinates must be global, so the line data can be accessible from WM_PAINT message code (to paint the line) and from WM_TIMER code (to rotate the line by the interval you need, say 2 degrees). You also can attach your data structures to the HWND using SetWindowLong() API - if you afraid of global variables (BOO! ) Globals are fine to use however.
5. In response to WM_PAINT you draw the line one time - using CURRENT line data
6. In response to WM_TIMER (once a hundred milliseconds) you change the CURRENT line data to reflect the next line location (rotated, say, by 2 degrees) Immediately after that - same code block - you must force the WM_PAINT message and that is done by two lines:
InvalidateRect (hWnd, NULL, TRUE);
UpdateWindow (hWnd);

Having done all that you will still have issues with flicker. To avoid this you need to draw in memory and disable WM_ERASEBKGND processing in your window.

The timing resolution of a timer may be low, because Windows considers WM_TIMER a message of LOWEST priority, so timing messages will come to your code as windows decides, not exactly 100 ms. With the lowering of that period the timer messages becoming more unstable. Say you need to do something every 2 ms - you better off using a thread for this. In the thread procedure do the same code as in WM_TIMER case and then simply
Sleep (2);

Report
Re: Is the a way to rotate a line clockwise? Posted by Sonx_hvn7 on 23 Apr 2008 at 11:59 PM
In response to your suggestions, this is my code...

POINT SetPOINT(LONG radius);
long ErrorHandler(char errorMessage[]);
void Win32APIGDICircle (HDC hdc, LONG radius, int R, int G, int B);
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,WPARAM wParam, LPARAM lParam);

// Globals
int	angle=0;
HICON	hIcon1;		
POINT	ptOld;       
UINT	uResult;    
POINT	coord, ptCenter = {450,300};

//---------------------------------------------------------------------------
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	MSG        Msg;
	HWND       hWnd;
	WNDCLASSEX WndClsEx;

	// Create the application window
	WndClsEx.cbSize        = sizeof(WNDCLASSEX);
	WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
	WndClsEx.lpfnWndProc   = WndProcedure;
	WndClsEx.cbClsExtra    = 0;
	WndClsEx.cbWndExtra    = 0;
	WndClsEx.hIcon		   = LoadIcon(hInstance, MAKEINTRESOURCE(400)); 
	WndClsEx.hCursor	   = LoadCursor(hInstance, MAKEINTRESOURCE(200)); 
	WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	WndClsEx.lpszMenuName  = NULL;
	WndClsEx.lpszClassName = ClsName;
	WndClsEx.hInstance     = hInstance;
	WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

	// Register the application
	RegisterClassEx(&WndClsEx);

	// Create the window object
	hWnd = CreateWindowEx(0,
		ClsName,
		WndName,
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		NULL,
		NULL,
		hInstance,
		NULL);

	// Find out if the window was created
	if( !hWnd ) // If the window was not created,
		return FALSE; // stop the application

	// Display the window to the user
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	// Decode and treat the messages
	// as long as the application is running
	while( GetMessage(&Msg, NULL, 0, 0) )
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}

	return Msg.wParam;
}

//---------------------------------------------------------------------------
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
                               WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HPEN pen, oldPen;
	HDC hdc;
	long radius=150;

	double	xLimit = sqrt ((double) (radius * radius) / 2);

	// Handle messagse
	switch(Msg)
	{
	case WM_CREATE:

		// Set the timer 
		uResult = (UINT)SetTimer(hWnd, IDT_ROTATER, 10000,(TIMERPROC) NULL); 

		break;

	case WM_PAINT:
		{		
			ZeroMemory(&ps,sizeof(PAINTSTRUCT));
			hdc = BeginPaint(hWnd, &ps);

                        // Draw a circle
			Win32APIGDICircle (hdc, radius, 0, 255, 128);
			
			// Create pen
			pen = CreatePen(PS_SOLID, 2, RGB(128, 255, 128));	
			oldPen = (HPEN)SelectObject(hdc, pen);		

			// Draw line
			SetPOINT(radius);
			MoveToEx(hdc, ptCenter.x,ptCenter.y, NULL);		
			LineTo(hdc, coord.x, coord.y);

			// Delete & Release DCs
			SelectObject(hdc, oldPen); 				
			DeleteObject(pen);
			DeleteDC(hdc);
			EndPaint(hWnd, &ps);

			// Force the WM_PAINT
			InvalidateRect (hWnd, NULL, TRUE);
			UpdateWindow(hWnd);
		}
		break; 

	case WM_TIMER: 
		angle-=2;	// change angle (rotate) 2 degrees apart
		Sleep(2);	// rotate every 2 seconds
		break;

	case WM_DESTROY:
		KillTimer(hWnd, IDT_ROTATER); 
		PostQuitMessage(WM_QUIT);
		break;

	default:
		// Process the left-over messages
		return DefWindowProc(hWnd, Msg, wParam, lParam);
	}
	// If something was not done, let it go
	return 0;
}

// Win32API GDI circle:
void Win32APIGDICircle (HDC hdc, LONG radius,int R, int G, int B)
{
	SelectObject (hdc, GetStockObject (DC_BRUSH));
	SetDCBrushColor(hdc,RGB(R,G,B));

	Ellipse (hdc, 
		ptCenter.x - radius, 
		ptCenter.y + radius,
		ptCenter.x + radius,
		ptCenter.y - radius);
}

/* Calculate the line points */
POINT SetPOINT(LONG radius)
{
	const float Deg2Rad = 0.017453292;
	float degInRad;

	degInRad = angle*Deg2Rad;   // Convert degrees to radians

	// Finds the adjacent value
        coord.x = (long)(ptCenter.x + (cos(degInRad)*(float)radius));	

        // Finds the hypotenuse value
	coord.y = (long)(ptCenter.y - (sin(degInRad)*(float)radius));	

	return coord;
}


Line doesn't rotate and the circle flickers, can't even see the line proparly... Any alterations to be made to the code?

Report
Re: Is the a way to rotate a line clockwise? Posted by AsmGuru62 on 24 Apr 2008 at 4:28 AM
: In response to your suggestions, this is my
: code...

:
:
: 
: POINT SetPOINT(LONG radius);
: long ErrorHandler(char errorMessage[]);
: void Win32APIGDICircle (HDC hdc, LONG radius, int R, int G, int B);
: LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,WPARAM wParam, LPARAM lParam);
: 
: // Globals
: int	angle=0;
: HICON	hIcon1;		
: POINT	ptOld;       
: UINT	uResult;    
: POINT	coord, ptCenter = {450,300};
: 
: //---------------------------------------------------------------------------
: INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
: {
: 	MSG        Msg;
: 	HWND       hWnd;
: 	WNDCLASSEX WndClsEx;
: 
: 	// Create the application window
: 	WndClsEx.cbSize        = sizeof(WNDCLASSEX);
: 	WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
: 	WndClsEx.lpfnWndProc   = WndProcedure;
: 	WndClsEx.cbClsExtra    = 0;
: 	WndClsEx.cbWndExtra    = 0;
: 	WndClsEx.hIcon		   = LoadIcon(hInstance, MAKEINTRESOURCE(400)); 
: 	WndClsEx.hCursor	   = LoadCursor(hInstance, MAKEINTRESOURCE(200)); 
: 	WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
: 	WndClsEx.lpszMenuName  = NULL;
: 	WndClsEx.lpszClassName = ClsName;
: 	WndClsEx.hInstance     = hInstance;
: 	WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
: 
: 	// Register the application
: 	RegisterClassEx(&WndClsEx);
: 
: 	// Create the window object
: 	hWnd = CreateWindowEx(0,
: 		ClsName,
: 		WndName,
: 		WS_OVERLAPPEDWINDOW,
: 		CW_USEDEFAULT,
: 		CW_USEDEFAULT,
: 		CW_USEDEFAULT,
: 		CW_USEDEFAULT,
: 		NULL,
: 		NULL,
: 		hInstance,
: 		NULL);
: 
: 	// Find out if the window was created
: 	if( !hWnd ) // If the window was not created,
: 		return FALSE; // stop the application
: 
: 	// Display the window to the user
: 	ShowWindow(hWnd, nCmdShow);
: 	UpdateWindow(hWnd);
: 
: 	// Decode and treat the messages
: 	// as long as the application is running
: 	while( GetMessage(&Msg, NULL, 0, 0) )
: 	{
: 		TranslateMessage(&Msg);
: 		DispatchMessage(&Msg);
: 	}
: 
: 	return Msg.wParam;
: }
: 
: //---------------------------------------------------------------------------
: LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
:                                WPARAM wParam, LPARAM lParam)
: {
: 	PAINTSTRUCT ps;
: 	HPEN pen, oldPen;
: 	HDC hdc;
: 	long radius=150;
: 
: 	double	xLimit = sqrt ((double) (radius * radius) / 2);
: 
: 	// Handle messagse
: 	switch(Msg)
: 	{
: 	case WM_CREATE:
: 
: 		// Set the timer 
: 		// Why timer set at 10 seconds?
: 		// Try 250 msec, so line will move 8 degrees per second  
: 		uResult = (UINT)SetTimer(hWnd, IDT_ROTATER, 250,(TIMERPROC) NULL); 
: 
: 		break;
: 
: 	case WM_PAINT:
: 		{		
: 			ZeroMemory(&ps,sizeof(PAINTSTRUCT));
: 			// This ^^^ is not needed
: 			hdc = BeginPaint(hWnd, &ps);
: 
:                         // Draw a circle
: 			Win32APIGDICircle (hdc, radius, 0, 255, 128);
: 			
: 			// Create pen
: 			pen = CreatePen(PS_SOLID, 2, RGB(128, 255, 128));	
: 			oldPen = (HPEN)SelectObject(hdc, pen);		
: 
: 			// Draw line
: 			SetPOINT(radius);
: 			MoveToEx(hdc, ptCenter.x,ptCenter.y, NULL);		
: 			LineTo(hdc, coord.x, coord.y);
: 
: 			// Delete & Release DCs
: 			SelectObject(hdc, oldPen); 				
: 			DeleteObject(pen);
: 			//DeleteDC(hdc);
: 			//Not good ^^^ - I removed it.
: 			EndPaint(hWnd, &ps);
: 
: 			// Force the WM_PAINT
: 			//InvalidateRect (hWnd, NULL, TRUE);
: 			//UpdateWindow(hWnd);
: 			// This ^^^ should be inside WM_TIMER after line
: 			// angle is modified 		}
: 		break; 
: 
: 	case WM_TIMER: 
: 		angle-=2;	// change angle (rotate) 2 degrees apart
: 		//Sleep(2);	// rotate every 2 seconds
: 		// This ^^^ needed if you use thread in place of timer: 

		// Moved it here (notice the "FALSE" instead of "TRUE")
		InvalidateRect (hWnd, NULL, FALSE);
		UpdateWindow(hWnd);
 		break;
: 
: 	case WM_DESTROY:
: 		KillTimer(hWnd, IDT_ROTATER); 
: 		PostQuitMessage(WM_QUIT);
: 		break;
: 
: 	default:
: 		// Process the left-over messages
: 		return DefWindowProc(hWnd, Msg, wParam, lParam);
: 	}
: 	// If something was not done, let it go
: 	return 0;
: }
: 
: // Win32API GDI circle:
: void Win32APIGDICircle (HDC hdc, LONG radius,int R, int G, int B)
: {
: 	// Some strange code... simply create a brush and select
: 	// it. Restore all resources after drawing
: 	//SelectObject (hdc, GetStockObject (DC_BRUSH));
: 	//SetDCBrushColor(hdc,RGB(R,G,B));
: 	HBRUSH hBrush = CreateSolidBrush (RGB (R,G,B));
: 	HGDIOBJ hOldBrush = SelectObject (hdc, hBrush);

: 
: 	Ellipse (hdc, 
: 		ptCenter.x - radius, 
: 		ptCenter.y + radius,
: 		ptCenter.x + radius,
: 		ptCenter.y - radius);

: 	SelectObject (hdc, hOldBrush);
: 	DeleteObject (hBrush);: }
: 
: /* Calculate the line points */
: POINT SetPOINT(LONG radius)
: {
: 	const float Deg2Rad = 0.017453292;
: 	float degInRad;
: 
: 	degInRad = angle*Deg2Rad;   // Convert degrees to radians
: 
: 	// Finds the adjacent value
:         coord.x = (long)(ptCenter.x + (cos(degInRad)*(float)radius));	
: 
:         // Finds the hypotenuse value
: 	coord.y = (long)(ptCenter.y - (sin(degInRad)*(float)radius));	
: 
: 	return coord;
: }
: 
:
:
: Line doesn't rotate and the circle flickers, can't even
: see the line proparly... Any alterations to be made to the
: code?

:
:
Report
Re: Is the a way to rotate a line clockwise? Posted by Sonx_hvn7 on 25 Apr 2008 at 4:19 AM

Thanks AsmGuru62, made changes now the line rotates but the circle'still flickering... Someone suggested that i must create a Compatible DC then draw the circle and the line on it!... This will avoid flicking, could that be true?

// Rotate.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <math.h>

#pragma hdrstop

#define IDT_ROTATER 101

//---------------------------------------------------------------------------
const char *ClsName = "RADAR_01";
const char *WndName = "Rotate Line";

POINT SetPOINT(LONG radius);
long ErrorHandler(char errorMessage[]);
void Win32APIGDICircle (HDC hdc, LONG radius, int R, int G, int B);
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,WPARAM wParam, LPARAM lParam);

// Globals
int	angle=0;
HICON	hIcon1;		
POINT	ptOld;       
UINT	uResult;    
POINT	coord, ptCenter = {450,300};

//---------------------------------------------------------------------------
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	MSG        Msg;
	HWND       hWnd;
	WNDCLASSEX WndClsEx;

	// Create the application window
	WndClsEx.cbSize        = sizeof(WNDCLASSEX);
	WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
	WndClsEx.lpfnWndProc   = WndProcedure;
	WndClsEx.cbClsExtra    = 0;
	WndClsEx.cbWndExtra    = 0;
	WndClsEx.hIcon		   = LoadIcon(hInstance, MAKEINTRESOURCE(400)); 
	WndClsEx.hCursor	   = LoadCursor(hInstance, MAKEINTRESOURCE(200)); 
	WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	WndClsEx.lpszMenuName  = NULL;
	WndClsEx.lpszClassName = ClsName;
	WndClsEx.hInstance     = hInstance;
	WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

	// Register the application
	RegisterClassEx(&WndClsEx);

	// Create the window object
	hWnd = CreateWindowEx(0,
		ClsName,
		WndName,
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		NULL,
		NULL,
		hInstance,
		NULL);

	// Find out if the window was created
	if( !hWnd ) // If the window was not created,
		return FALSE; // stop the application

	// Display the window to the user
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	// Decode and treat the messages
	// as long as the application is running
	while( GetMessage(&Msg, NULL, 0, 0) )
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}

	return Msg.wParam;
}

//---------------------------------------------------------------------------
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
							  WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HPEN pen, oldPen;
	HDC hMemDC;
	long radius=150;

	double	xLimit = sqrt ((double) (radius * radius) / 2);

	// Handle messagse
	switch(Msg)
	{
	case WM_CREATE:

		// Set the timer 
		uResult = (UINT)SetTimer(hWnd, IDT_ROTATER, 0.025,(TIMERPROC) NULL); 

		break;

	case WM_PAINT:
		{		
			hdc = BeginPaint(hWnd, &ps);

			//hdc = CreateCompatibleDC(hWnd);

			// Draw a circle
			Win32APIGDICircle (hdc, radius, 0, 255, 128);

			// Create pen
			pen = CreatePen(PS_SOLID, 2, RGB(128, 255, 128));	
			oldPen = (HPEN)SelectObject(hdc, pen);		

			// Draw line
			SetPOINT(radius);
			MoveToEx(hdc, ptCenter.x,ptCenter.y, NULL);		
			LineTo(hdc, coord.x, coord.y);

			// Delete & Release DCs
			SelectObject(hdc, oldPen); 				
			DeleteObject(pen);
			EndPaint(hWnd, &ps);
		}
		break; 

	case WM_TIMER: 
		angle-=2;
		InvalidateRect (hWnd, NULL, TRUE);
		UpdateWindow(hWnd);

		break;

	case WM_DESTROY:
		KillTimer(hWnd, IDT_ROTATER); 
		PostQuitMessage(WM_QUIT);
		break;

	default:
		// Process the left-over messages
		return DefWindowProc(hWnd, Msg, wParam, lParam);
	}
	// If something was not done, let it go
	return 0;
}
// Win32API GDI circle:
void Win32APIGDICircle (HDC hdc, LONG radius,int R, int G, int B)
{
	/*SelectObject (hdc, GetStockObject (DC_BRUSH));
	SetDCBrushColor(hdc,RGB(R,G,B));*/

	HBRUSH hBrush = CreateSolidBrush (RGB (R,G,B));
	HGDIOBJ hOldBrush = SelectObject (hdc, hBrush);

	Ellipse (hdc, 
		ptCenter.x - radius, 
		ptCenter.y + radius,
		ptCenter.x + radius,
		ptCenter.y - radius);

	SelectObject (hdc, hOldBrush);
	DeleteObject (hBrush);
}

/* Calculate the line points */
POINT SetPOINT(LONG radius)
{
	const float Deg2Rad = 0.017453292;
	float degInRad;

	degInRad = angle*Deg2Rad;   // Convert degrees to radians

	// Finds the adjacent value
	coord.x = (long)(ptCenter.x + (cos(degInRad)*(float)radius));	

	// Finds the hypotenuse value
	coord.y = (long)(ptCenter.y - (sin(degInRad)*(float)radius));	

	return coord;
}
Report
Re: Is the a way to rotate a line clockwise? Posted by AsmGuru62 on 26 Apr 2008 at 4:14 AM
:
: Thanks AsmGuru62, made changes now the line rotates but the
: circle'still flickering... Someone suggested that i must create a
: Compatible DC then draw the circle and the line on it!... This will
: avoid flicking, could that be true?
:
Yes. Drawing in memory DC and then using BitBlt() to instantly draw in one shot is the way to make games and other draw-intensive stuff. In addition to this make a change shown in RED below. It reduces flicker too, but then you need to draw what is around the circle yourself.


:
: 
: // Rotate.cpp : Defines the entry point for the console application.
: //
: 
: #include "stdafx.h"
: #include <windows.h>
: #include <math.h>
: 
: #pragma hdrstop
: 
: #define IDT_ROTATER 101
: 
: //---------------------------------------------------------------------------
: const char *ClsName = "RADAR_01";
: const char *WndName = "Rotate Line";
: 
: POINT SetPOINT(LONG radius);
: long ErrorHandler(char errorMessage[]);
: void Win32APIGDICircle (HDC hdc, LONG radius, int R, int G, int B);
: LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,WPARAM wParam, LPARAM lParam);
: 
: // Globals
: int	angle=0;
: HICON	hIcon1;		
: POINT	ptOld;       
: UINT	uResult;    
: POINT	coord, ptCenter = {450,300};
: 
: //---------------------------------------------------------------------------
: INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
: {
: 	MSG        Msg;
: 	HWND       hWnd;
: 	WNDCLASSEX WndClsEx;
: 
: 	// Create the application window
: 	WndClsEx.cbSize        = sizeof(WNDCLASSEX);
: 	WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
: 	WndClsEx.lpfnWndProc   = WndProcedure;
: 	WndClsEx.cbClsExtra    = 0;
: 	WndClsEx.cbWndExtra    = 0;
: 	WndClsEx.hIcon		   = LoadIcon(hInstance, MAKEINTRESOURCE(400)); 
: 	WndClsEx.hCursor	   = LoadCursor(hInstance, MAKEINTRESOURCE(200)); 
: 	WndClsEx.hbrBackground = NULL;
: 	WndClsEx.lpszMenuName  = NULL;
: 	WndClsEx.lpszClassName = ClsName;
: 	WndClsEx.hInstance     = hInstance;
: 	WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
: 
: 	// Register the application
: 	RegisterClassEx(&WndClsEx);
: 
: 	// Create the window object
: 	hWnd = CreateWindowEx(0,
: 		ClsName,
: 		WndName,
: 		WS_OVERLAPPEDWINDOW,
: 		CW_USEDEFAULT,
: 		CW_USEDEFAULT,
: 		CW_USEDEFAULT,
: 		CW_USEDEFAULT,
: 		NULL,
: 		NULL,
: 		hInstance,
: 		NULL);
: 
: 	// Find out if the window was created
: 	if( !hWnd ) // If the window was not created,
: 		return FALSE; // stop the application
: 
: 	// Display the window to the user
: 	ShowWindow(hWnd, nCmdShow);
: 	UpdateWindow(hWnd);
: 
: 	// Decode and treat the messages
: 	// as long as the application is running
: 	while( GetMessage(&Msg, NULL, 0, 0) )
: 	{
: 		TranslateMessage(&Msg);
: 		DispatchMessage(&Msg);
: 	}
: 
: 	return Msg.wParam;
: }
: 
: //---------------------------------------------------------------------------
: LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
: 							  WPARAM wParam, LPARAM lParam)
: {
: 	PAINTSTRUCT ps;
: 	HPEN pen, oldPen;
: 	HDC hMemDC;
: 	long radius=150;
: 
: 	double	xLimit = sqrt ((double) (radius * radius) / 2);
: 
: 	// Handle messagse
: 	switch(Msg)
: 	{
: 	case WM_CREATE:
: 
: 		// Set the timer 
: 		uResult = (UINT)SetTimer(hWnd, IDT_ROTATER, 0.025,(TIMERPROC) NULL); 
: 
: 		break;
: 
: 	case WM_PAINT:
: 		{		
: 			hdc = BeginPaint(hWnd, &ps);
: 
: 			//hdc = CreateCompatibleDC(hWnd);
: 
: 			// Draw a circle
: 			Win32APIGDICircle (hdc, radius, 0, 255, 128);
: 
: 			// Create pen
: 			pen = CreatePen(PS_SOLID, 2, RGB(128, 255, 128));	
: 			oldPen = (HPEN)SelectObject(hdc, pen);		
: 
: 			// Draw line
: 			SetPOINT(radius);
: 			MoveToEx(hdc, ptCenter.x,ptCenter.y, NULL);		
: 			LineTo(hdc, coord.x, coord.y);
: 
: 			// Delete & Release DCs
: 			SelectObject(hdc, oldPen); 				
: 			DeleteObject(pen);
: 			EndPaint(hWnd, &ps);
: 		}
: 		break; 
: 
: 	case WM_TIMER: 
: 		angle-=2;
: 		InvalidateRect (hWnd, NULL, TRUE);
: 		UpdateWindow(hWnd);
: 
: 		break;
: 
: 	case WM_DESTROY:
: 		KillTimer(hWnd, IDT_ROTATER); 
: 		PostQuitMessage(WM_QUIT);
: 		break;
: 
: 	default:
: 		// Process the left-over messages
: 		return DefWindowProc(hWnd, Msg, wParam, lParam);
: 	}
: 	// If something was not done, let it go
: 	return 0;
: }
: // Win32API GDI circle:
: void Win32APIGDICircle (HDC hdc, LONG radius,int R, int G, int B)
: {
: 	/*SelectObject (hdc, GetStockObject (DC_BRUSH));
: 	SetDCBrushColor(hdc,RGB(R,G,B));*/
: 
: 	HBRUSH hBrush = CreateSolidBrush (RGB (R,G,B));
: 	HGDIOBJ hOldBrush = SelectObject (hdc, hBrush);
: 
: 	Ellipse (hdc, 
: 		ptCenter.x - radius, 
: 		ptCenter.y + radius,
: 		ptCenter.x + radius,
: 		ptCenter.y - radius);
: 
: 	SelectObject (hdc, hOldBrush);
: 	DeleteObject (hBrush);
: }
: 
: /* Calculate the line points */
: POINT SetPOINT(LONG radius)
: {
: 	const float Deg2Rad = 0.017453292;
: 	float degInRad;
: 
: 	degInRad = angle*Deg2Rad;   // Convert degrees to radians
: 
: 	// Finds the adjacent value
: 	coord.x = (long)(ptCenter.x + (cos(degInRad)*(float)radius));	
: 
: 	// Finds the hypotenuse value
: 	coord.y = (long)(ptCenter.y - (sin(degInRad)*(float)radius));	
: 
: 	return coord;
: }
: 
:



 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.