Code:
// Rotate.c :
//
#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);
HDC MemoryDCForArea (HDC hdc, int iAreaWidth, int iAreaHeight, int iCommandWhatToDo );
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,WPARAM wParam, LPARAM lParam);
// Globals
int angle=0;
HICON hIcon1;
POINT ptOld;
UINT_PTR 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)(COLOR_BTNFACE+1);
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);
if( !hWnd )
return FALSE;
// Display the window to the user
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return (int) Msg.wParam;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HPEN pen, oldPen;
HDC hdc;
HDC MemDC;
HBRUSH hbrBkGnd;
HBITMAP hBitmap, hOldBitmap;
RECT rec;
long radius=150;
double xLimit = sqrt ((double) (radius * radius) / 2);
// Handle messagse
switch(Msg)
{
case WM_CREATE:
// Set the timer
uResult = SetTimer(hWnd, IDT_ROTATER, (UINT) 0.015,(TIMERPROC) NULL);
break;
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
/* Retrieve the client's area width and height */
GetClientRect(hWnd, &rec);
MemDC = CreateCompatibleDC (hdc);
hBitmap = CreateCompatibleBitmap (
hdc, rec.right-rec.left, rec.bottom-rec.top
);
hOldBitmap = SelectObject (MemDC, hBitmap);
// Force background color to grey
hbrBkGnd = CreateSolidBrush( RGB(0xD3, 0xD3, 0xD3) );
FillRect(MemDC, &rec, hbrBkGnd);
DeleteObject(hbrBkGnd);
// Draw a circle
Win32APIGDICircle (MemDC, radius, 0, 255, 128);
// Create pen
pen = CreatePen(PS_SOLID, 2, RGB(128, 255, 128));
oldPen = (HPEN)SelectObject(MemDC, pen);
// Draw line
SetPOINT(radius);
MoveToEx(MemDC, ptCenter.x,ptCenter.y, NULL);
LineTo(MemDC, coord.x, coord.y);
// Delete Pen
SelectObject(MemDC, oldPen);
DeleteObject(pen);
/* Render circle to screen from memory DC */
BitBlt(hdc,0,0,rec.right,rec.bottom,MemDC,0,0,SRCCOPY);
// Delete & Release DCs
SelectObject(MemDC, hOldBitmap);
DeleteObject(hBitmap);
DeleteDC(MemDC);
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;
case WM_ERASEBKGND:
{
return (LRESULT)1;
}
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)
{
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 double Deg2Rad = 0.017453292;
double degInRad;
degInRad = angle*Deg2Rad; // Convert degrees to radians
// Finds the adjacent value
coord.x = (long)(ptCenter.x + (cos(degInRad)*radius));
// Finds the hypotenuse value
coord.y = (long)(ptCenter.y - (sin(degInRad)*radius));
return coord;
}
This is how the rendering on memory DC is done and it works 100% (no flickering at all)