Home Articles Books Downloads FAQs Tips

Q: Screen capture the desktop.


Answer:

This FAQ is an extension to the FAQ on how to create a TCanvas object for the entire screen. This technique first creates a TCanvas object for the screen. An Image control then calls the TCanvas::CopyRect function to copy the screen image into the TImage object.

  // First, get an HDC for the entire screen with the API GetDC function.
  // Then create a Canvas based on the DC.
  HDC dc = GetDC(0);
  Graphics::TCanvas *ScreenCanvas = new Graphics::TCanvas;
  ScreenCanvas->Handle = dc;

  // Resize the TImage control to match the size of the screen.
  // Then copy from the screen Canvas to the TImage Canvas.
  Image1->Picture->Bitmap->Width = Screen->Width;
  Image1->Picture->Bitmap->Height= Screen->Height;
  TRect rect = Rect(0,0,Screen->Width, Screen->Height);
  Image1->Picture->Bitmap->Canvas->CopyRect(rect, ScreenCanvas, rect);

  // cleanup
  delete ScreenCanvas;
  ReleaseDC(NULL,dc);

You can capture a specific window by obtaining a DC for that window instead of getting a DC for the entire screen. This code captures the C++Builder main window if it's visible.

  // The BCB IDE window has the window class "TAppBuilder"
  HWND BCBHandle = FindWindow("TAppBuilder",NULL);
  if(BCBHandle)
  {
    // Create a TCanvas for the BCB IDE window. GetWindowDC returns a DC for the
    // whole window, including the menu, title bar and border.
    HDC dc = GetWindowDC(BCBHandle);
    Graphics::TCanvas *ScreenCanvas = new Graphics::TCanvas;
    ScreenCanvas->Handle = dc;

    // need to create a TRect that is the same width and height as the ClipRect
    // of the Canvas, but whose left and top members are zero.
    TRect rect = ScreenCanvas->ClipRect;
    rect.Right  = rect.Right  - rect.Left;
    rect.Bottom = rect.Bottom - rect.Top;
    rect.Top = rect.Left = 0;

    // resize the bitmap of the Image, and then copy the contents of the
    // BCB ide canvas to the bitmap's canvas. Then clean up the canvas and DC
    Image1->Picture->Bitmap->Width = rect.Right;
    Image1->Picture->Bitmap->Height= rect.Bottom;
    Image1->Picture->Bitmap->Canvas->CopyRect(rect,
                                              ScreenCanvas,
                                              ScreenCanvas->ClipRect);
    delete ScreenCanvas;
    ReleaseDC(BCBHandle,dc);
  }

Note: The ClipRect property of TCanvas is recalculated every time the property is read. This is good, because the clipping rect of a window changes every time the window is moved or resized. ClipRect re-reads the info so the Canvas keeps up with changes to its underlying HWND and HDC (this did not play a role in the example code)

Note: You must remember to call ReleaseDC for the HDC handle.

Note: Both GetDC and GetWindowDC take an HWND as their argument. GetDC returns a DC for the client area of the specified window. GetWindowDC returns a DC that can draw on both the non-client and client areas of the window. In other words, you can paint the title bar and menu of a window if you obtain the DC with GetWindowDC.



Copyright © 1997-2000 by Harold Howe.
All rights reserved.