Quantcast
Channel: The Old New Thing
Viewing all articles
Browse latest Browse all 3085

How can I display a live screenshot of a piece of another application?

$
0
0

Today's Little Program takes a rectangular portion of another application and continuously replicates it in its own client area. You might want to do this if you want to monitor a portion of an application like a custom progress bar, and the application doesn't use the Windows 7 taskbar progress indicator feature. (Maybe it's an old application.)

Take our scratch program and make the following changes:

#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <ole2.h>
#include <commctrl.h>
#include <shlwapi.h>
#include <stdio.h>
#include <dwmapi.h>

HINSTANCE g_hinst;                          /* This application's HINSTANCE */
HWND g_hwndChild;                           /* Optional child window */
HTHUMBNAIL g_hthumb;

BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
  DWM_THUMBNAIL_PROPERTIES props = {};
  HWND hwndTarget;
  if (sscanf(reinterpret_cast<PCSTR>(lpcs->lpCreateParams),
               "%p %ld %ld %ld %ld", &hwndTarget,
               &props.rcSource.left, &props.rcSource.top,
               &props.rcSource.right, &props.rcSource.bottom) == 5) {
    DwmRegisterThumbnail(hwnd, hwndTarget, &g_hthumb);
    props.dwFlags = DWM_TNP_VISIBLE | DWM_TNP_RECTSOURCE |
                    DWM_TNP_RECTDESTINATION;
    props.rcDestination = props.rcSource;
    OffsetRect(&props.rcSource,
               -props.rcSource.left, -props.rcSource.top);
    props.fVisible = TRUE;
    DwmUpdateThumbnailProperties(g_hthumb, &props);
  }
  return TRUE;
}  

void
OnDestroy(HWND hwnd)
{
  if (g_hthumb) DwmUnregisterThumbnail(g_hthumb);
  PostQuitMessage(0);
}

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev,
                   LPSTR lpCmdLine, int nShowCmd)
{
   ...

        hwnd = CreateWindow(
            "Scratch",                      /* Class Name */
            "Scratch",                      /* Title */
            WS_OVERLAPPEDWINDOW,            /* Style */
            CW_USEDEFAULT, CW_USEDEFAULT,   /* Position */
            CW_USEDEFAULT, CW_USEDEFAULT,   /* Size */
            NULL,                           /* Parent */
            NULL,                           /* No menu */
            hinst,                          /* Instance */
            lpCmdLine);
    ...
}

Our Little Program passes its command line through to the WM_CREATE message, which parses it as a pointer (for Visual C++, a hex value with no 0x prefix) and four integers representing the left, top, right, and bottom coordinates a rectangle within that window. (For example, to get the upper left 100 pixels of the window, pass 0 0 100 100.) It creates a thumbnail from that window and positions it inside the scratch window.

Use Spy or whatever program to get a window handle and run the progarm with the window handle and four integers (described above). A live slice of the window will appear in the scratch program.

Making it easier to select the target window and a rectangle from it is left as an exercise. This is just a Little Program.


Viewing all articles
Browse latest Browse all 3085

Trending Articles