Click Here!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Fast Track Visual C++ 6.0 Programming
(Publisher: John Wiley & Sons, Inc.)
Author(s): Steve Holzner
ISBN: 0471312908
Publication Date: 09/01/98

Bookmark It

Search this book:
 
Previous Table of Contents Next


Chapter 6
Advanced Screen and Metafile Graphics

In this chapter, we work with some advanced graphics topics, both on the screen and in graphics metafiles. We explore screen graphics by seeing how to implement screen capture—copying a selection from the screen and copying it to the clipboard. This shows us a number of things: how to work with and copy bitmaps at a low level, how to get a device context for the entire screen, how to capture mouse events that happen outside our window, and more.

Next, we spend time solving one of the oldest problems for Windows programmers—refreshing a window when it needs to be refreshed. If the graphics in your window are complex or depend on many user actions, it can be difficult to restore them easily when the time comes to do so. Here, we use metafiles—memory or disk files that store device context actions—to provide an easy way to store what’s gone into your display and restore that display as needed by replaying the metafile.

We start with screen capture, into which we put a lot of Visual C++ power.

Screen Capture

Our screen capture program, Copier, lets the user copy part or all of the screen, displays what’s been copied, and allows it to be placed into the clipboard. Users need only outline the area of the screen they want to copy using the mouse, and we can capture it.

Create a new MDI project named Copier and open ClassWizard. We start by working with the mouse.

Capturing the Mouse

In the Copier program, we need to capture the mouse so that we can use the mouse even though it goes outside our program’s window. When we’ve captured the mouse, we are able to let the user draw a box on the screen to enclose the part of the screen they want to capture.

Recent versions of Windows have some security concerns with mouse capture—especially by hostile programs—so there are some new rules. Instead of letting a program capture the mouse without restriction, the program that captures the mouse must first own the mouse. Because of this, to capture the mouse, the user must first press the left mouse button in our program, then drag the mouse to the location they want to copy on the screen. While keeping the left mouse button down, they can then use the right mouse button to outline the area to capture; when they release the right mouse button, we are able to capture the area they’ve outlined.

The mouse capture process begins when the left mouse button goes down, so we start by adding OnLButtonDown() to the view class.

void CCopierView::OnLButtonDown(UINT nFlags, CPoint point)

{
    // TODO: Add your message handler code here and/or call default

    CView::OnLButtonDown(nFlags, point);

}

We begin by capturing the mouse using SetCapture().

void CCopierView::OnLButtonDown(UINT nFlags, CPoint point)

{
    SetCapture();                              ⇐
        .
        .
        .

    CView::OnLButtonDown(nFlags, point);

}

Now we get all mouse messages until we either release the mouse ourselves or the left mouse button goes up. Because the capture operation has started, we set a new flag, CaptureFlag, to true and add it to the view class’s header.

void CCopierView::OnLButtonDown(UINT nFlags, CPoint point)

{
    SetCapture();               
    CaptureFlag = true;                      ⇐
        .
        .
        .

    CView::OnLButtonDown(nFlags, point);

}

We support another flag here, DrawFlag (add that flag to the view class’s header as well), which indicates whether the user is using the right mouse button to outline the area on the screen to capture (in this case we should be drawing a rectangle the user can stretch to outline that area). When the left mouse button goes down, we set DrawFlag to false.

void CCopierView::OnLButtonDown(UINT nFlags, CPoint point)

{
    SetCapture();               
    CaptureFlag = true;                        ⇐
    DrawFlag = false;                          ⇐

    CView::OnLButtonDown(nFlags, point);

}

When the left mouse button goes up, the capturing process is over, so we release the mouse and set our two flags to false in OnLButtonUp().

void CCopierView::OnLButtonUp(UINT nFlags, CPoint point)

{
    ReleaseCapture();                               ⇐
    CaptureFlag = false;                       ⇐
    DrawFlag = false;                          ⇐

    CView::OnLButtonUp(nFlags, point);

}

Now that we’ve captured the mouse, we put it to work. When the user uses the right mouse button, an area on the screen is outlined. We can stretch a rectangle over that area to indicate the capture area. To draw that rectangle outside our own window, we have to get a device context for the entire screen.

Drawing Anywhere on the Screen

When the user presses the right mouse button (and while the left mouse button is still pressed), we start drawing the outline rectangle on the screen to indicate the capture area. As soon as the right mouse button goes down, we set DrawFlag to true in OnRButtonDown().

void CCopierView::OnRButtonDown(UINT nFlags, CPoint point)

{
    if(CaptureFlag){

        DrawFlag = true;                     ⇐
             .
             .
             .
    }

    CView::OnRButtonDown(nFlags, point);

}

In addition, we save the point at which the right mouse button went down, because that point marks one corner of the capture area. We call that point the anchor point.

Anchor Point

      x-------------------------
      |                       |
      |                       |
      |                       |
      |                       |
      |                       |
      |                       |
      --------------------------

How do we get this point if it’s outside our window? We use the special function GetMessagePos(), which returns the current location of the mouse in screen coordinates (as opposed to the point passed to us in the point parameter, which is a client coordinate). We store the anchor point in a new CPoint object that we add to the view, AnchorPoint.

void CCopierView::OnRButtonDown(UINT nFlags, CPoint point)

{
    if(CaptureFlag){

        DrawFlag = true;

        AnchorPoint = GetMessagePos();                    ⇐
    }

    CView::OnRButtonDown(nFlags, point);

}

This is all it takes to record the anchor point for our drawing work. When the user moves the mouse to a new location while keeping the right and left mouse buttons pressed, we record the new mouse location in OnMouseMove() and call that new location CurrentPoint.

Anchor Point

      x-------------------------
      |                       |
      |                       |
      |                       |
      |                       |
      |                       |
      |                       |
      --------------------------x CurrentPoint

After the rectangle is drawn to the current location, we call that location the previous point to prepare for additional mouse moves.

Anchor Point

      x-------------------------
      |                       |
      |                       |
      |                       |
      |                       |
      |                       |
      |                       |
      -------------------------x PreviousPoint

If the mouse moves again, there is a new current point, so we erase the rectangle that stretches from the anchor point to the previous point and redraw the rectangle from the anchor point to the new current point.

Anchor Point

      x-------------------------------
      |                            |
      |                            |
      |                            |
      |                            |
      |                            |
      |                            |
      ------------------------------x CurrentPoint


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.