//**********************************************************************
//
// copy.c
//
// Source file for Device-Independent Bitmap (DIB) API. Provides
// the following functions:
//
// CopyWindowToDIB() - Copies a window to a DIB
// CopyScreenToDIB() - Copies entire screen to a DIB
// CopyWindowToBitmap()- Copies a window to a standard Bitmap
// CopyScreenToBitmap()- Copies entire screen to a standard Bitmap
// PaintDIB() - Displays DIB in the specified DC
// PaintBitmap() - Displays bitmap in the specified DC
//
// The following functions are called from DIBUTIL.C:
//
// DIBToBitmap() - Creates a bitmap from a DIB
// BitmapToDIB() - Creates a DIB from a bitmap
// DIBWidth() - Gets the width of the DIB
// DIBHeight() - Gets the height of the DIB
// CreateDIBPalette() - Gets the DIB's palette
// GetSystemPalette() - Gets the current palette
//
// Written by Microsoft Product Support Services, Developer Support.
// Copyright 1991-1998 Microsoft Corporation. All rights reserved.
//**********************************************************************
#define STRICT // enable strict type checking
#include <WINDOWS.H>
#include "DIBUTIL.H"
#include "DIBAPI.H"
/*************************************************************************
*
* CopyWindowToDIB()
*
* Parameters:
*
* HWND hWnd - specifies the window
*
* WORD fPrintArea - specifies the window area to copy into the device-
* independent bitmap
*
* Return Value:
*
* HDIB - identifies the device-independent bitmap
*
* Description:
*
* This function copies the specified part(s) of the window to a device-
* independent bitmap.
*
************************************************************************/
HDIB CopyWindowToDIB(HWND hWnd, WORD fPrintArea)
{
HDIB hDIB = NULL; // handle to DIB
// check for a valid window handle
if (!hWnd)
return NULL;
switch (fPrintArea)
{
case PW_WINDOW: // copy entire window
{
RECT rectWnd;
// get the window rectangle
GetWindowRect(hWnd, &rectWnd);
// get the DIB of the window by calling
// CopyScreenToDIB and passing it the window rect
hDIB = CopyScreenToDIB(&rectWnd);
break;
}
case PW_CLIENT: // copy client area
{
RECT rectClient;
POINT pt1, pt2;
// get the client area dimensions
GetClientRect(hWnd, &rectClient);
// convert client coords to screen coords
pt1.x = rectClient.left;
pt1.y = rectClient.top;
pt2.x = rectClient.right;
pt2.y = rectClient.bottom;
ClientToScreen(hWnd, &pt1);
ClientToScreen(hWnd, &pt2);
rectClient.left = pt1.x;
rectClient.top = pt1.y;
rectClient.right = pt2.x;
rectClient.bottom = pt2.y;
// get the DIB of the client area by calling
// CopyScreenToDIB and passing it the client rect
hDIB = CopyScreenToDIB(&rectClient);
break;
}
default: // invalid print area
return NULL;
}
// return the handle to the DIB
return hDIB;
}
/*************************************************************************
*
* CopyScreenToDIB()
*
* Parameter:
*
* LPRECT lpRect - specifies the window
*
* Return Value:
*
* HDIB - identifies the device-independent bitmap
*
* Description:
*
* This function copies the specified part of the screen to a device-
* independent bitmap.
*
************************************************************************/
HDIB CopyScreenToDIB(LPRECT lpRect)
{
HBITMAP hBitmap; // handle to device-dependent bitmap
HPALETTE hPalette; // handle to palette
HDIB hDIB = NULL; // handle to DIB
// get the device-dependent bitmap in lpRect by calling
// CopyScreenToBitmap and passing it the rectangle to grab
hBitmap = CopyScreenToBitmap(lpRect);
// check for a valid bitmap handle
if (!hBitmap)
return NULL;
// get the current palette
hPalette = GetSystemPalette();
// convert the bitmap to a DIB
hDIB = BitmapToDIB(hBitmap, hPalette);
// clean up
DeleteObject(hPalette);
DeleteObject(hBitmap);
// return handle to the packed-DIB
return hDIB;
}
/*************************************************************************
*
* CopyWindowToBitmap()
*
* Parameters:
*
* HWND hWnd - specifies the window
*
* WORD fPrintArea - specifies the window area to copy into the device-
* dependent bitmap
*
* Return Value:
*
* HDIB - identifies the device-dependent bitmap
*
* Description:
*
* This function copies the specified part(s) of the window to a device-
* dependent bitmap.
*
*
************************************************************************/
HBITMAP CopyWindowToBitmap(HWND hWnd, WORD fPrintArea)
{
HBITMAP hBitmap = NULL; // handle to device-dependent bitmap
// check for a valid window handle
if (!hWnd)
return NULL;
switch (fPrintArea)
{
case PW_WINDOW: // copy entire window
{
RECT rectWnd;
// get the window rectangle
GetWindowRect(hWnd, &rectWnd);
// get the bitmap of that window by calling
// CopyScreenToBitmap and passing it the window rect
hBitmap = CopyScreenToBitmap(&rectWnd);
break;
}
case PW_CLIENT: // copy client area
{
RECT rectClient;
POINT pt1, pt2;
// get client dimensions
GetClientRect(hWnd, &rectClient);
// convert client coords to screen coords
pt1.x = rectClient.left;
pt1.y = rectClient.top;
pt2.x = rectClient.right;
pt2.y = rectClient.bottom;
ClientToScreen(hWnd, &pt1);
ClientToScreen(hWnd, &pt2);
rectClient.left = pt1.x;
rectClient.top = pt1.y;
rectClient.right = pt2.x;
rectClient.bottom = pt2.y;
// get the bitmap of the client area by calling
// CopyScreenToBitmap and passing it the client rect
hBitmap = CopyScreenToBitmap(&rectClient);
break;
}
default: // invalid print area
return NULL;
}
// return handle to the bitmap
return hBitmap;
}
/*************************************************************************
*
* CopyScreenToBitmap()
*
* Parameter:
*
* LPRECT lpRect - specifies the window
*
* Return Value:
*
* HDIB - identifies the device-dependent bitmap
*
* Description:
*
* This function copies the specified part of the screen to a device-
* dependent bitmap.
*
*
************************************************************************/
HBITMAP CopyScreenToBitmap(LPRECT lpRect)
{
HDC hScrDC, hMemDC; // screen DC and memory DC
HBITMAP hBitmap, hOldBitmap; // handles to deice-dependent bitmaps
int nX, nY, nX2, nY2; // coordinates of rectangle to grab
int nWidth, nHeight; // DIB width and height
int xScrn, yScrn; // screen resolution
// check for an empty rectangle
if (IsRectEmpty(lpRect))
return NULL;
// create a DC for the screen and create
// a memory DC compatible to screen DC
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
hMemDC = CreateCompatibleDC(hScrDC);
// get points of rectangle to grab
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
// get screen resolution
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
//make sure bitmap rectangle is visible
if (nX < 0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > xScrn)
nX2 = xScrn;
if (nY2 > yScrn)
nY2 = yScrn;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// create a bitmap compatible with the screen DC
hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
// select new bitmap into memory DC
hOldBitmap = SelectObject(hMemDC, hBitmap);
// bitblt screen DC to memory DC
BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY);
// select old bitmap back into memory DC and get handle to
// bitmap of the screen
hBitmap = SelectObject(hMemDC, hOldBitmap);
// clean up
DeleteDC(hScrDC);
DeleteDC(hMemDC);
// return handle to the bitmap
return hBitmap;
}
/*************************************************************************
*
* PaintDIB()
*
* Parameters:
*
* HDC hDC - DC to do output to
*
* LPRECT lpDCRect - rectangle on DC to do output to
*
* HDIB hDIB - handle to global memory with a DIB spec
* in it followed by the DIB bits
*
* LPRECT lpDIBRect - rectangle of DIB to output into lpDCRect
*
* Return Value:
*
* BOOL - TRUE if DIB was drawn, FALSE otherwise
*
* Description:
* Painting routine for a DIB. Calls StretchDIBits() or
* SetDIBitsToDevice() to paint the DIB. The DIB is
* output to the specified DC, at the coordinates given
* in lpDCRect. The area of the DIB to be output is
* given by lpDIBRect.
*
* NOTE: This function always selects the palette as background. Before
* calling this function, be sure your palette is selected to desired
* priority (foreground or background).
*
*
************************************************************************/
BOOL PaintDIB(HDC hDC, LPRECT lpDCRect, HDIB hDIB, LPRECT lpDIBRect,
HPALETTE hPal)
{
LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER
LPSTR lpDIBBits; // Pointer to DIB bits
BOOL bSuccess=FALSE; // Success/fail flag
HPALETTE hOldPal=NULL; // Previous palette
// Check for valid DIB handle
if (!hDIB)
return FALSE;
// Lock down the DIB, and get a pointer to the beginning of the bit
// buffer
lpDIBHdr = GlobalLock(hDIB);
lpDIBBits = FindDIBBits(lpDIBHdr);
// Select and realize our palette as background
if (hPal)
{
hOldPal = SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
}
// Make sure to use the stretching mode best for color pictures
SetStretchBltMode(hDC, COLORONCOLOR);
// Determine whether to call StretchDIBits() or SetDIBitsToDevice()
if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) &&
(RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
{
bSuccess = SetDIBitsToDevice(hDC, lpDCRect->left, lpDCRect->top,
RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect), lpDIBRect->left,
(int)DIBHeight(lpDIBHdr) - lpDIBRect->top -
RECTHEIGHT(lpDIBRect), 0, DIBHeight(lpDIBHdr), lpDIBBits,
(LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS);
}
else
bSuccess = StretchDIBits(hDC, lpDCRect->left, lpDCRect->top,
RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect), lpDIBRect->left,
lpDIBRect->top, RECTWIDTH(lpDIBRect), RECTHEIGHT(lpDIBRect),
lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY);
// Unlock the memory block
GlobalUnlock(hDIB);
// Reselect old palette
if (hOldPal)
SelectPalette(hDC, hOldPal, FALSE);
// Return with success/fail flag
return bSuccess;
}
/*************************************************************************
*
* PaintBitmap()
*
* Parameters:
*
* HDC hDC - DC to do output to
*
* LPRECT lpDCRect - rectangle on DC to do output to
*
* HBITMAP hDDB - handle to device-dependent bitmap (DDB)
*
* LPRECT lpDDBRect - rectangle of DDB to output into lpDCRect
*
* HPALETTE hPalette - handle to the palette to use with hDDB
*
* Return Value:
*
* BOOL - TRUE if bitmap was drawn, FLASE otherwise
*
* Description:
*
* Painting routine for a DDB. Calls BitBlt() or
* StretchBlt() to paint the DDB. The DDB is
* output to the specified DC, at the coordinates given
* in lpDCRect. The area of the DDB to be output is
* given by lpDDBRect. The specified palette is used.
*
* NOTE: This function always selects the palette as background. Before
* calling this function, be sure your palette is selected to desired
* priority (foreground or background).
*
************************************************************************/
BOOL PaintBitmap(HDC hDC, LPRECT lpDCRect, HBITMAP hDDB, LPRECT lpDDBRect,
HPALETTE hPal)
{
HDC hMemDC; // Handle to memory DC
HBITMAP hOldBitmap; // Handle to previous bitmap
HPALETTE hOldPal1 = NULL; // Handle to previous palette
HPALETTE hOldPal2 = NULL; // Handle to previous palette
BOOL bSuccess = FALSE; // Success/fail flag
// Create a memory DC
hMemDC = CreateCompatibleDC (hDC);
// If this failed, return FALSE
if (!hMemDC)
return FALSE;
// If we have a palette, select and realize it
if (hPal)
{
hOldPal1 = SelectPalette(hMemDC, hPal, TRUE);
hOldPal2 = SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
}
// Select bitmap into the memory DC
hOldBitmap = SelectObject (hMemDC, hDDB);
// Make sure to use the stretching mode best for color pictures
SetStretchBltMode (hDC, COLORONCOLOR);
// Determine whether to call StretchBlt() or BitBlt()
if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDDBRect)) &&
(RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDDBRect)))
bSuccess = BitBlt(hDC, lpDCRect->left, lpDCRect->top,
lpDCRect->right - lpDCRect->left,
lpDCRect->bottom - lpDCRect->top, hMemDC, lpDDBRect->left,
lpDDBRect->top, SRCCOPY);
else
bSuccess = StretchBlt(hDC, lpDCRect->left, lpDCRect->top,
lpDCRect->right - lpDCRect->left,
lpDCRect->bottom - lpDCRect->top, hMemDC, lpDDBRect->left,
lpDDBRect->top, lpDDBRect->right - lpDDBRect->left,
lpDDBRect->bottom - lpDDBRect->top, SRCCOPY);
// Clean up
SelectObject(hMemDC, hOldBitmap);
if (hOldPal1)
SelectPalette (hMemDC, hOldPal1, FALSE);
if (hOldPal2)
SelectPalette (hDC, hOldPal2, FALSE);
DeleteDC (hMemDC);
// Return with success/fail flag
return bSuccess;
}