Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Is the a way to rotate a line clockwise?

Sonx_hvn7Sonx_hvn7 Member Posts: 54
I tried writing these functions but no good output. Output window freezes and line does not rotate..

[code]
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;
}
[/code]

Comments

  • IDKIDK Member Posts: 1,784
    You'll need to move the loop outside of the paint function.

    Simply refresh your window with a timer.
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : I tried writing these functions but no good output. Output window
    : freezes and line does not rotate..
    :
    : [code]:
    : 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);
    : [color=Red]DeleteObject(pen);[/color]
    : }
    :
    : /* 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;
    : }
    : [/code]:
    :
    [color=Blue]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.[/color]
  • Sonx_hvn7Sonx_hvn7 Member Posts: 54
    : : I tried writing these functions but no good output. Output window
    : : freezes and line does not rotate..
    : :
    : : [code]: :
    : : 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);
    : : [color=Red]DeleteObject(pen);[/color]
    : : }
    : :
    : : /* 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;
    : : }
    : : [/code]: :
    : :
    : [color=Blue]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.[/color]

    This is my updated code

    [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;
    }
    [/code]

    [color=Blue]... how do i erase the previous line, currently all lines show forming a complete circle?[/color]


  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : This is my updated code
    :
    : [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);
    :
    : [color=Red]pen = CreatePen(PS_SOLID, 2, RGB(128, 255, 128));[/color]
    : [color=Red]oldPen = (HPEN)SelectObject(hdc, pen);[/color]
    : [color=Red]// These two ^^^ lines should be moved out before FOR() statement[/color]

    : 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;
    : }
    : [/code]:
    [color=Blue]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:
    [code]
    InvalidateRect (hWnd, NULL, TRUE);
    UpdateWindow (hWnd);
    [/code]
    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
    [code]
    Sleep (2);
    [/code]
    [/color]
  • Sonx_hvn7Sonx_hvn7 Member Posts: 54
    [color=Blue]In response to your suggestions, this is my code...[/color]

    [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;
    }
    [/code]

    [color=Blue] Line doesn't rotate and the circle flickers, can't even see the line proparly... Any alterations to be made to the code?[/color]

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : [color=Blue]In response to your suggestions, this is my
    : code...[/color]
    :
    : [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
    : [color=Red]// Why timer set at 10 seconds?[/color]
    : [color=Red]// Try 250 msec, so line will move 8 degrees per second[/color]
    : uResult = (UINT)SetTimer(hWnd, IDT_ROTATER, [color=Red]250[/color],(TIMERPROC) NULL);
    :
    : break;
    :
    : case WM_PAINT:
    : {
    : ZeroMemory(&ps,sizeof(PAINTSTRUCT));
    : [color=Red]// This ^^^ is not needed[/color]
    : 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);
    : [color=Red]//DeleteDC(hdc);[/color]
    : [color=Red]//Not good ^^^ - I removed it.[/color]
    : EndPaint(hWnd, &ps);
    :
    [color=Red]: // Force the WM_PAINT
    : //InvalidateRect (hWnd, NULL, TRUE);
    : //UpdateWindow(hWnd);
    : // This ^^^ should be inside WM_TIMER after line
    : // angle is modified[/color] }
    : break;
    :
    : case WM_TIMER:
    : angle-=2; // change angle (rotate) 2 degrees apart
    [color=Red]: //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);
    [/color] 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)
    : {
    [color=Red]: // 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));[/color]
    : 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);

    [color=Red]: SelectObject (hdc, hOldBrush);
    : DeleteObject (hBrush);[/color]: }
    :
    : /* 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;
    : }
    : [/code]:
    :
    : [color=Blue] Line doesn't rotate and the circle flickers, can't even
    : see the line proparly... Any alterations to be made to the
    : code?[/color]
    :
    :
  • Sonx_hvn7Sonx_hvn7 Member Posts: 54

    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?

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

    #include "stdafx.h"
    #include
    #include

    #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;
    }
    [/code]
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    :
    : 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?
    :
    [color=Blue]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.
    [/color]

    : [code]:
    : // Rotate.cpp : Defines the entry point for the console application.
    : //
    :
    : #include "stdafx.h"
    : #include
    : #include
    :
    : #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));
    [color=Red]: WndClsEx.hbrBackground = NULL;[/color]
    : 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;
    : }
    : [/code]:
Sign In or Register to comment.