The BLOWUP1 program, shown in Figure 4-9, uses SetCapture and ReleaseCapture and a few other interesting techniques. The program lets you use the mouse to block out any rectangular area of the screen. BLOWUP1 then copies the contents of that rectangular area into its own client area, stretching or compressing the image as appropriate. (See Figure 4-10 on page 169.)
BLOWUP1.MAK
#-----------------------
# BLOWUP1.MAK make file
#-----------------------
blowup1.exe : blowup1.obj blowup1.def
link blowup1, /align:16, NUL, /nod slibcew libw, blowup1
rc blowup1.exe
blowup1.obj : blowup1.c
cl -c -Gsw -Ow -W2 -Zp blowup1.c
BLOWUP1.C
/*------------------------------------------------
BLOWUP1.C -- Screen Capture Mouse Demo Program
(c) Charles Petzold, 1990
------------------------------------------------*/
#include <windows.h>
long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
static char szAppName[] = "BlowUp1" ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
if (!hPrevInstance)
{
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
RegisterClass (&wndclass) ;
}
hwnd = CreateWindow (szAppName, "Blow-Up Mouse Demo",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, nCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
void InvertBlock (HWND hwnd, POINT ptBeg, POINT ptEnd)
{
HDC hdc ;
hdc = CreateDC ("DISPLAY", NULL, NULL, NULL) ;
ClientToScreen (hwnd, &ptBeg) ;
ClientToScreen (hwnd, &ptEnd) ;
PatBlt (hdc, ptBeg.x, ptBeg.y, ptEnd.x - ptBeg.x, ptEnd.y - ptBeg.y,
DSTINVERT) ;
DeleteDC (hdc) ;
}
long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
{
static BOOL fCapturing, fBlocking ;
static POINT ptBeg, ptEnd ;
HDC hdc ;
RECT rect ;
switch (message)
{
case WM_LBUTTONDOWN :
if (!fCapturing)
{
fCapturing = TRUE ;
SetCapture (hwnd) ;
SetCursor (LoadCursor (NULL, IDC_CROSS)) ;
}
else if (!fBlocking)
{
fBlocking = TRUE ;
ptBeg = MAKEPOINT (lParam) ;
}
return 0 ;
case WM_MOUSEMOVE :
if (fBlocking)
{
ptEnd = MAKEPOINT (lParam) ;
InvertBlock (hwnd, ptBeg, ptEnd) ;
InvertBlock (hwnd, ptBeg, ptEnd) ;
}
return 0 ;
case WM_LBUTTONUP :
if (fBlocking)
{
fCapturing = fBlocking = FALSE ;
ptEnd = MAKEPOINT (lParam) ;
SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
hdc = GetDC (hwnd) ;
GetClientRect (hwnd, &rect) ;
StretchBlt (hdc, 0, 0, rect.right, rect.bottom,
hdc, ptBeg.x, ptBeg.y,
ptEnd.x - ptBeg.x, ptEnd.y - ptBeg.y,
SRCCOPY) ;
ReleaseDC (hwnd, hdc) ;
SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
ReleaseCapture () ;
}
return 0 ;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
BLOWUP1.DEF
;------------------------------------
; BLOWUP1.DEF module definition file
;------------------------------------
NAME BLOWUP1
DESCRIPTION 'Blow-Up Mouse Demo Program (c) Charles Petzold, 1990'
EXETYPE WINDOWS
STUB 'WINSTUB.EXE'
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
HEAPSIZE 1024
STACKSIZE 8192
EXPORTS WndProc
The job of stretching and compressing bitmapped images may seem complex, but it's simplified for us by a Windows GDI function called StretchBlt. (The abbreviation Blt is pronounced ”blit.“ The function is related to the Windows BitBlt function, which stands for ”bit-block transfer.“ These functions are discussed in more detail in Chapter 13.)
Here's how to use BLOWUP1:
1.Click the mouse in BLOWUP1's client area. The mouse cursor changes to a cross hair.
2.Position the mouse cursor over the upper left corner of the area of the screen you want to transfer.
3.Press the mouse button, drag the mouse to the lower right corner, and release the mouse button. The mouse cursor changes to an hourglass.
4.In a few seconds (or perhaps a little longer), the area that you blocked out is copied to BLOWUP1's client area, compressed or expanded appropriately.
If you block out a rectangle by moving from the upper right corner to the lower left corner, BLOWUP1 displays a mirror image. If you move from the lower left to the upper right, BLOWUP1 displays an upside-down image. And if you move from lower right to upper left, the program combines the two effects.
BLOWUP1 does not retain the captured image, and doesn't process the WM_PAINT message. If you change the size of the window, the window will be erased.