Click here to Skip to main content
Click here to Skip to main content

Using the DrawAnimatedRects() function

, , , 26 Jan 2000
Rate this:
Please Sign up or sign in to vote.
Shows how to use the DrawAnimatedRects function to improve the look of your apps.

Introduction

If you look at MS Word and invoke the find dialog, you can see a neat animation. I wished to mimic this and came across the DrawAnimatedRects() function. The DrawAnimatedRects() function draws a wire-frame rectangle and animates it to indicate the opening of an icon, or the minimizing or maximizing of a window. The syntax is as follows:

BOOL WINAPI DrawAnimatedRects(
  HWND hwnd,            // handle to clipping window
  int idAni,            // type of animation
  CONST RECT *lprcFrom, // rectangle coordinates (minimized)
  CONST RECT *lprcTo    // rectangle coordinates (restored)
);

The lprcFrom parameter sets where the animation will start, and the lprcTo value where the animation will end. For instance, if you wish to make a window appear to expand from a button to a window, you would set lprcFrom as the dimensions of the button, and lprcTo as the dimensions of the final window position. The effect is not as good as MS Word, but if any GUI experts can provide a MS Word Sample, it will be of great help.

Using the function

The sample application demonstrates a nice use of the function. In the demo, the About Box is animated so it appears to expand and collapse from a button inside a dialog.

To achieve this, you simply override the OnCreate and OnDestroy functions in your About Box dialog class, and add calls to DrawAnimatedRects() at the appropriate places.

To make things simple, we first store the dimensions of the button where the About Box will expand from. We add a member variable m_rectFrom to the About Box class and to make the About Box appear, we use the following.

    CAboutDlg about;
    m_ctlButton.GetWindowRect(about.m_rectFrom);
    about.DoModal();

where m_ctlButton is the button control the About Box is appearing to expand from.

Next, you need to add overrides to OnCreate and OnDestroy inside your About Box class:

int CAboutDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CDialog::OnCreate(lpCreateStruct) == -1)
        return -1;

    if (!m_rectFrom.IsRectEmpty())
    {
        CRect rectTo(lpCreateStruct->x,lpCreateStruct->y, 
            lpCreateStruct->x + lpCreateStruct->cx,
            lpCreateStruct->y + lpCreateStruct->cy);

        DrawAnimatedRects(m_hWnd, IDANI_CAPTION, m_rectFrom, rectTo);
    }

    return 0;
}

void CAboutDlg::OnDestroy() 
{
    CDialog::OnDestroy();
    if (!m_rectFrom.IsRectEmpty())
    {
        CRect rect;
        GetWindowRect(rect);
        DrawAnimatedRects(m_hWnd, IDANI_CAPTION, rect, m_rectFrom);
    }
}

This effectively draws the Windows animation sequence either before the window itself appears, or after the window has disappeared.

That's it! A simple method but an effective one.


Updated: Norm Almond has supplied some code that produces the window exploding/imploding effect using a wire frame. The syntax for his function is as follows:

void WINAPI DrawWireRects(LPRECT lprcFrom, LPRECT lprcTo, UINT nMilliSecSpeed)

The lprcFrom parameter sets where the animation will start, and the lprcTo value where the animation will end. nMilliSecSpeed is the delay in milliseconds between each wire frame being displayed (a value of 20 milliseconds works nicely).

////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    DrawWireRects
//
// DESCRIPTION: Creates exploding wire rectanges
//
// INPUTS:  LPRECT lprcFrom      Source Rectangle
//          LPRECT lprcTo        Destination Rectangle
//          UINT nMilliSecSpeed  Speed in millisecs for animation
//
// RETURN:    None
// NOTES:    None
//
//  Maintenance Log
//  Author      Date    Version     Notes
//  NT Almond   011199  1.0         Origin
//  CJ Maunder  010899  1.1         Modified rectangle transition code
//
/////////////////////////////////////////////////////////////////////////
void WINAPI DrawWireRects(LPRECT lprcFrom, LPRECT lprcTo, UINT nMilliSecSpeed)
{
    const int nNumSteps = 10;

    GdiFlush();
    Sleep(50);  // Let the desktop window sort itself out

    // if hwnd is null - "you have the CON".
    HDC hDC = ::GetDC(NULL);

    // Pen size, urmmm not too thick
    HPEN hPen = ::CreatePen(PS_SOLID, 2, RGB(0,0,0));

    int nMode = ::SetROP2(hDC, R2_NOT);
    HPEN hOldPen = (HPEN) ::SelectObject(hDC, hPen);

    for (int i = 0; i < nNumSteps; i++)
    {
        double dFraction = (double) i / (double) nNumSteps;

        RECT transition;
        transition.left   = lprcFrom->left + 
            (int)((lprcTo->left - lprcFrom->left) * dFraction);
        transition.right  = lprcFrom->right + 
            (int)((lprcTo->right - lprcFrom->right) * dFraction);
        transition.top    = lprcFrom->top + 
            (int)((lprcTo->top - lprcFrom->top) * dFraction);
        transition.bottom = lprcFrom->bottom + 
            (int)((lprcTo->bottom - lprcFrom->bottom) * dFraction);

        POINT pt[5];
        pt[0] = CPoint(transition.left, transition.top);
        pt[1] = CPoint(transition.right,transition.top);
        pt[2] = CPoint(transition.right,transition.bottom);
        pt[3] = CPoint(transition.left, transition.bottom);
        pt[4] = CPoint(transition.left, transition.top);

        // We use Polyline because we can determine our own pen size
        // Draw Sides
        ::Polyline(hDC,pt,5);

        GdiFlush();

        Sleep(nMilliSecSpeed);

        // UnDraw Sides
        ::Polyline(hDC,pt,5);

        GdiFlush();
    }

    ::SetROP2(hDC, nMode);
    ::SelectObject(hDC, hOldPen);

    ::ReleaseDC(NULL,hDC);
}

Demo project number 1 includes this new code. Norm has also produced a class that is part of Demo project number 2 that demonstrates a class CZoomRect that can be used to implement his updated Zoom Rect code.

To use his class, include the ZoomRect.h header file, create a CZoomRect object and call its Draw() method:

CRect rcStart(10,600,10,600);
CRect rcEnd(600,0,800,200);
int   nDelay = 10;

CZoomRect ZoomRect;
ZoomRect.Draw(NULL, rcStart, rcEnd, nDelay);

The first parameter is a handle to the window that should be used for drawing (or NULL for the desktop window), the second and third are the start and destination rectangles, and the last is the delay in milliseconds between frames.


Michael Dunn wrote that, in regards to the zooming-outline effect from Word 97, he remembers hearing a co-worker mention a long time ago that really early builds of Win 95 (builds from 1994) used the same effect. It may have been similar to what CE 2.0 does when opening/closing apps.

If you look in winuser.h, you'll find two legacy constants, IDANI_OPEN and IDANI_CLOSE. A first thought was that passing them to DrawAnimatedRects() would make the zooming-outline effect, but unfortunately that isn't the case. DrawAnimatedRects() only works if you pass IDANI_CAPTION.

This has turned more into a history lesson than a solution Smile | :) , but I just wanted to pass along this tidbit, in case you were wondering about those other two IDANI_* constants.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Authors

Chris Maunder
Founder CodeProject
Canada Canada
Chris is the Co-founder, Administrator, Architect, Chief Editor and Shameless Hack who wrote and runs The Code Project. He's been programming since 1988 while pretending to be, in various guises, an astrophysicist, mathematician, physicist, hydrologist, geomorphologist, defence intelligence researcher and then, when all that got a bit rough on the nerves, a web developer. He is a Microsoft Visual C++ MVP both globally and for Canada locally.
 
His programming experience includes C/C++, C#, SQL, MFC, ASP, ASP.NET, and far, far too much FORTRAN. He has worked on PocketPCs, AIX mainframes, Sun workstations, and a CRAY YMP C90 behemoth but finds notebooks take up less desk space.
 
He dodges, he weaves, and he never gets enough sleep. He is kind to small animals.
 
Chris was born and bred in Australia but splits his time between Toronto and Melbourne, depending on the weather. For relaxation he is into road cycling, snowboarding, rock climbing, and storm chasing.
Follow on   Twitter   Google+   LinkedIn

NormDroid
Software Developer (Senior) Software Kinetics
United Kingdom United Kingdom



Software Kinetics
are experts in developing customised and bespoke applications and have expertise in the development of desktop, mobile and internet applications on Windows.

We specialise in:

  • User Interface Design
  • Desktop Development
  • Windows Phone Development
  • Windows Presentation Framework
  • Windows Forms
  • Windows Communication Framework
  • Windows Services
  • Network Applications
  • Database Applications
  • Web Development
  • Web Services
  • Silverlight
  • ASP.net
 
Visit Software Kinetics
Follow on   Twitter

Santosh Rao
Architect
India India
1993 started with Computers
 
BE(Computer Science) and MS (Software Systems)
 
Industry Experience: 10 Years
 
C, C++, VC++(MFC), .NET, C#, MTS, Queuing, ASP.NET, AJAX, Java, J2EE, SunOne, JMS
 
Banking, Insurance & Pension,Health Care

Comments and Discussions

 
GeneralDrawWireRects slow in Vista PinmemberWolfram Rösler18-Nov-07 23:09 
GeneralRe: DrawWireRects slow in Vista Pinmembernorm .net18-Nov-07 23:19 
General.net Pinmembertom183322-Mar-06 11:20 
GeneralRe: .net Pinmembernorm.net22-Mar-06 20:27 
GeneralGreat stuff, and now about that memory leak.. PinmemberTim Stubbs16-Feb-06 3:45 
GeneralRe: Great stuff, and now about that memory leak.. Pinmembernorm.net16-Feb-06 4:34 
GeneralRe: Great stuff, and now about that memory leak.. PinmemberTim Stubbs16-Feb-06 4:47 
GeneralRe: Great stuff, and now about that memory leak.. Pinmembernorm.net16-Feb-06 21:09 
Time,
 
Not bugs, 'issues' Wink | ;)

 
Blogless

Generalzooming Pinmembersreejith ss nair28-Apr-05 20:28 
Generalmenu font change runtime PinmemberAnonymous2-Apr-01 20:00 
GeneralA small update to the listed sample so things "look right" PinsussJason De Arte31-Mar-00 12:25 
GeneralRe: A small update to the listed sample so things &quot;look right&quot; PinmemberAndrewSmirnov15-Sep-04 9:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 27 Jan 2000
Article Copyright 2000 by Chris Maunder, NormDroid, Santosh Rao
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid