Click here to Skip to main content
15,860,861 members
Articles / Multimedia / GDI
Article

Using the DrawAnimatedRects() function

, ,
Rate me:
Please Sign up or sign in to vote.
2.95/5 (9 votes)
26 Jan 2000CPOL 103.9K   3.2K   45   12
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 :), 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)


Written By
Founder CodeProject
Canada Canada
Chris Maunder is the co-founder of CodeProject and ContentLab.com, and has been a prominent figure in the software development community for nearly 30 years. Hailing from Australia, Chris has a background in Mathematics, Astrophysics, Environmental Engineering and Defence Research. His programming endeavours span everything from FORTRAN on Super Computers, C++/MFC on Windows, through to to high-load .NET web applications and Python AI applications on everything from macOS to a Raspberry Pi. Chris is a full-stack developer who is as comfortable with SQL as he is with CSS.

In the late 1990s, he and his business partner David Cunningham recognized the need for a platform that would facilitate knowledge-sharing among developers, leading to the establishment of CodeProject.com in 1999. Chris's expertise in programming and his passion for fostering a collaborative environment have played a pivotal role in the success of CodeProject.com. Over the years, the website has grown into a vibrant community where programmers worldwide can connect, exchange ideas, and find solutions to coding challenges. Chris is a prolific contributor to the developer community through his articles and tutorials, and his latest passion project, CodeProject.AI.

In addition to his work with CodeProject.com, Chris co-founded ContentLab and DeveloperMedia, two projects focussed on helping companies make their Software Projects a success. Chris's roles included Product Development, Content Creation, Client Satisfaction and Systems Automation.

Written By
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

Written By
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 Pin
Wolfram Rösler18-Nov-07 23:09
Wolfram Rösler18-Nov-07 23:09 
GeneralRe: DrawWireRects slow in Vista Pin
NormDroid18-Nov-07 23:19
professionalNormDroid18-Nov-07 23:19 
General.net Pin
tom183322-Mar-06 11:20
tom183322-Mar-06 11:20 
GeneralRe: .net Pin
NormDroid22-Mar-06 20:27
professionalNormDroid22-Mar-06 20:27 
GeneralGreat stuff, and now about that memory leak.. Pin
Tim Stubbs16-Feb-06 3:45
Tim Stubbs16-Feb-06 3:45 
GeneralRe: Great stuff, and now about that memory leak.. Pin
NormDroid16-Feb-06 4:34
professionalNormDroid16-Feb-06 4:34 
GeneralRe: Great stuff, and now about that memory leak.. Pin
Tim Stubbs16-Feb-06 4:47
Tim Stubbs16-Feb-06 4:47 
GeneralRe: Great stuff, and now about that memory leak.. Pin
NormDroid16-Feb-06 21:09
professionalNormDroid16-Feb-06 21:09 
Generalzooming Pin
sreejith ss nair28-Apr-05 20:28
sreejith ss nair28-Apr-05 20:28 
Generalmenu font change runtime Pin
2-Apr-01 20:00
suss2-Apr-01 20:00 
GeneralA small update to the listed sample so things "look right" Pin
Jason De Arte31-Mar-00 12:25
Jason De Arte31-Mar-00 12:25 
GeneralRe: A small update to the listed sample so things &quot;look right&quot; Pin
AndrewSmirnov15-Sep-04 9:18
AndrewSmirnov15-Sep-04 9:18 

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

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