Ridimensionamento di un'immagine
Alcune applicazioni ridimensionano le immagini; ovvero visualizzano visualizzazioni ingrandita o ridotta di un'immagine. Ad esempio, un'applicazione di disegno può fornire una funzionalità di zoom che consente all'utente di visualizzare e modificare un disegno in pixel per pixel.
Le applicazioni ridimensionano le immagini chiamando la funzione StretchBlt . Analogamente alla funzione BitBlt , StretchBlt copia i dati bitmap da una bitmap in un contesto di dispositivo di origine (DC) in una bitmap in un controller di dominio di destinazione. Tuttavia, a differenza della funzione BitBlt , StretchBlt ridimensiona l'immagine in base alle dimensioni specificate dei rettangoli di origine e di destinazione. Se il rettangolo di origine è maggiore del rettangolo di destinazione, l'immagine risultante apparirà compattata; se il rettangolo di origine è più piccolo del rettangolo di destinazione, l'immagine risultante verrà espansa.
Se il rettangolo di destinazione è più piccolo del rettangolo di origine, StretchBlt rimuove i dati di colore dall'immagine in base a una modalità di estensione specificata, come illustrato nella tabella seguente.
Modalità stretch | Metodo |
---|---|
BLACKONWHITE | Esegue un'operazione AND logica sui dati di colore per i pixel eliminati e i dati di colore per i pixel rimanenti. |
WHITEONBLACK | Esegue un'operazione OR logica sui dati di colore per i pixel eliminati e i dati di colore per i pixel rimanenti. |
COLORONCOLOR | Elimina completamente i dati di colore dei pixel eliminati. |
SEMITONO | Approssima i dati di colore originali (di origine) nella destinazione. |
Per impostare la modalità di estensione, chiamare la funzione SetStretchBltMode .
Il codice di esempio seguente viene tratto da un'applicazione che illustra tutte e quattro le modalità di estensione disponibili con la funzione StretchBlt .
#include "stdafx.h"
#include "GDIBitmapScaling.h"
#include <commctrl.h>
#include <CommDlg.h>
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_GDIBITMAPSCALING, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_GDIBITMAPSCALING));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GDIBITMAPSCALING));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_GDIBITMAPSCALING);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
#define NEW_DIB_FORMAT(lpbih) (lpbih->biSize != sizeof(BITMAPCOREHEADER))
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_SYSMENU,
CW_USEDEFAULT, 0, 1024, 768, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
static HCURSOR hcurSave;
WORD DIBNumColors (LPVOID lpv)
{
INT bits;
LPBITMAPINFOHEADER lpbih = (LPBITMAPINFOHEADER)lpv;
LPBITMAPCOREHEADER lpbch = (LPBITMAPCOREHEADER)lpv;
/* With the BITMAPINFO format headers, the size of the palette
* is in biClrUsed, whereas in the BITMAPCORE - style headers, it
* is dependent on the bits per pixel ( = 2 raised to the power of
* bits/pixel).
*/
if (NEW_DIB_FORMAT(lpbih)) {
if (lpbih->biClrUsed != 0)
return (WORD)lpbih->biClrUsed;
bits = lpbih->biBitCount;
}
else
bits = lpbch->bcBitCount;
if (bits > 8)
return 0; /* Since biClrUsed is 0, we dont have a an optimal palette */
else
return (1 << bits);
}
/* Macro to determine to round off the given value to the closest byte */
#define WIDTHBYTES(i) ((((i)+31) >> 5) << 2)
/******************************************************************************
* *
* FUNCTION : DIBInfo(HANDLE hbi, LPBITMAPINFOHEADER lpbih) *
* *
* PURPOSE : Retrieves the DIB info associated with a CF_DIB *
* format memory block. *
* *
* RETURNS : TRUE - if successful. *
* FALSE - otherwise *
* *
*****************************************************************************/
BOOL DIBInfo (HANDLE hbi, LPBITMAPINFOHEADER lpbih)
{
if (hbi){
*lpbih = *(LPBITMAPINFOHEADER)hbi;
/* fill in the default fields */
if (NEW_DIB_FORMAT(lpbih)) {
if (lpbih->biSizeImage == 0L)
lpbih->biSizeImage = WIDTHBYTES(lpbih->biWidth*lpbih->biBitCount) * lpbih->biHeight;
if (lpbih->biClrUsed == 0L)
lpbih->biClrUsed = DIBNumColors (lpbih);
}
return TRUE;
}
return FALSE;
}
/* flags for mmioSeek() */
#ifndef SEEK_SET
#define SEEK_SET 0 /* seek to an absolute position */
#define SEEK_CUR 1 /* seek relative to current position */
#define SEEK_END 2 /* seek relative to end of file */
#endif /* ifndef SEEK_SET */
VOID ReadPackedFileHeader(HFILE hFile, LPBITMAPFILEHEADER lpbmfhdr, LPDWORD lpdwOffset)
{
*lpdwOffset = _llseek(hFile, 0L, (UINT) SEEK_CUR);
_hread(hFile, (LPSTR) &lpbmfhdr->bfType, sizeof(WORD)); /* read in bfType*/
_hread(hFile, (LPSTR) &lpbmfhdr->bfSize, sizeof(DWORD) * 3); /* read in last 3 dwords*/
}
/* macro to determine if resource is a DIB */
#define ISDIB(bft) ((bft) == BFT_BITMAP)
/* Header signatutes for various resources */
#define BFT_ICON 0x4349 /* 'IC' */
#define BFT_BITMAP 0x4d42 /* 'BM' */
#define BFT_CURSOR 0x5450 /* 'PT' */
HANDLE ReadDIBBitmapInfo (INT hFile)
{
DWORD dwOffset;
HANDLE hbi = NULL;
INT size;
INT i;
WORD nNumColors;
LPRGBQUAD lprgbq;
BITMAPINFOHEADER bih;
BITMAPCOREHEADER bch;
LPBITMAPINFOHEADER lpbih;
BITMAPFILEHEADER bf;
DWORD dwDWMasks= 0;
DWORD dwWidth = 0;
DWORD dwHeight = 0;
WORD wPlanes, wBitCount;
if (hFile == HFILE_ERROR)
return NULL;
/* Read the bitmap file header */
ReadPackedFileHeader(hFile, &bf, &dwOffset);
/* Do we have a RC HEADER? */
if (!ISDIB (bf.bfType)) {
bf.bfOffBits = 0L;
_llseek(hFile, dwOffset, (UINT)SEEK_SET); /* seek back to beginning of file */
}
if (sizeof(bih) != _hread(hFile, (LPSTR)&bih, (UINT)sizeof(bih)))
return FALSE;
nNumColors = DIBNumColors (&bih);
/* Check the nature (BITMAPINFO or BITMAPCORE) of the info. block
* and extract the field information accordingly. If a BITMAPCOREHEADER,
* transfer it's field information to a BITMAPINFOHEADER-style block
*/
switch (size = (INT)bih.biSize){
case sizeof (BITMAPINFOHEADER):
break;
case sizeof (BITMAPCOREHEADER):
bch = *(LPBITMAPCOREHEADER)&bih;
dwWidth = (DWORD)bch.bcWidth;
dwHeight = (DWORD)bch.bcHeight;
wPlanes = bch.bcPlanes;
wBitCount = bch.bcBitCount;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = dwWidth;
bih.biHeight = dwHeight;
bih.biPlanes = wPlanes;
bih.biBitCount = wBitCount;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = nNumColors;
bih.biClrImportant = nNumColors;
_llseek(hFile, (LONG)sizeof (BITMAPCOREHEADER) - sizeof (BITMAPINFOHEADER), (UINT)SEEK_CUR);
break;
default:
/* Not a DIB! */
return NULL;
}
/* Fill in some default values if they are zero */
if (bih.biSizeImage == 0){
bih.biSizeImage = WIDTHBYTES((DWORD)bih.biWidth * bih.biBitCount) * bih.biHeight;
}
if (bih.biClrUsed == 0)
bih.biClrUsed = DIBNumColors(&bih);
/* Allocate for the BITMAPINFO structure and the color table. */
if ((bih.biBitCount == 16) || (bih.biBitCount == 32))
dwDWMasks = sizeof(DWORD) * 3;
hbi = GlobalAlloc (GPTR, (LONG)bih.biSize + nNumColors * sizeof(RGBQUAD) + dwDWMasks);
if (!hbi)
return NULL;
lpbih = (LPBITMAPINFOHEADER)hbi;
*lpbih = bih;
/* Get a pointer to the color table */
lprgbq = (LPRGBQUAD)((LPSTR)lpbih + bih.biSize);
if (nNumColors){
if (size == sizeof(BITMAPCOREHEADER)){
/* Convert a old color table (3 byte RGBTRIPLEs) to a new
* color table (4 byte RGBQUADs)
*/
_hread(hFile, (LPSTR)lprgbq, (UINT)nNumColors * sizeof(RGBTRIPLE));
for (i = nNumColors - 1; i >= 0; i--){
RGBQUAD rgbq;
rgbq.rgbRed = ((RGBTRIPLE*)lprgbq)[i].rgbtRed;
rgbq.rgbBlue = ((RGBTRIPLE*)lprgbq)[i].rgbtBlue;
rgbq.rgbGreen = ((RGBTRIPLE*)lprgbq)[i].rgbtGreen;
rgbq.rgbReserved = (BYTE)0;
lprgbq[i] = rgbq;
}
}
else
_hread(hFile, (LPSTR)lprgbq, (UINT)nNumColors * sizeof(RGBQUAD));
} else
if (dwDWMasks)
_hread(hFile, (LPSTR)lprgbq, dwDWMasks);
if (bf.bfOffBits != 0L){
_llseek(hFile, dwOffset + bf.bfOffBits, (UINT)SEEK_SET);
}
return hbi;
}
HGLOBAL GlobalFreeDIB(HGLOBAL hDIB)
{
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)hDIB;
if (!lpbi->biClrImportant)
return GlobalFree(hDIB);
if (GlobalFlags((HGLOBAL)lpbi->biClrImportant) == GMEM_INVALID_HANDLE) {
SetLastError(0);
return GlobalFree(hDIB);
} else
return GlobalFree((HANDLE)lpbi->biClrImportant);
}
/******************************************************************************
* *
* FUNCTION : ColorTableSize(LPVOID lpv) *
* *
* PURPOSE : Calculates the palette size in bytes. If the info. block *
* is of the BITMAPCOREHEADER type, the number of colors is *
* multiplied by 3 to give the palette size, otherwise the *
* number of colors is multiplied by 4. *
* *
* RETURNS : Color table size in number of bytes. *
* *
*****************************************************************************/
WORD ColorTableSize (LPVOID lpv)
{
LPBITMAPINFOHEADER lpbih = (LPBITMAPINFOHEADER)lpv;
if (NEW_DIB_FORMAT(lpbih))
{
if (((LPBITMAPINFOHEADER)(lpbih))->biCompression == BI_BITFIELDS)
/* Remember that 16/32bpp dibs can still have a color table */
return (sizeof(DWORD) * 3) + (DIBNumColors (lpbih) * sizeof (RGBQUAD));
else
return (DIBNumColors (lpbih) * sizeof (RGBQUAD));
}
else
return (DIBNumColors (lpbih) * sizeof (RGBTRIPLE));
}
/******************************************************************************
* *
* FUNCTION :OpenDIB(LPSTR szFilename) *
* *
* PURPOSE :Open a DIB file and create a memory DIB -- a memory handle *
* containing BITMAPINFO, palette data and the bits. *
* *
* RETURNS :A handle to the DIB. *
* *
*****************************************************************************/
HANDLE OpenDIB (LPSTR szFilename)
{
HFILE hFile;
BITMAPINFOHEADER bih;
LPBITMAPINFOHEADER lpbih;
DWORD dwLen = 0;
DWORD dwBits;
HANDLE hDIB;
HANDLE hMem;
OFSTRUCT of;
/* Open the file and read the DIB information */
hFile = OpenFile(szFilename, &of, (UINT)OF_READ);
if (hFile == HFILE_ERROR)
return NULL;
hDIB = ReadDIBBitmapInfo(hFile);
if (!hDIB)
return NULL;
DIBInfo(hDIB, &bih);
/* Calculate the memory needed to hold the DIB */
dwBits = bih.biSizeImage;
dwLen = bih.biSize + (DWORD)ColorTableSize (&bih) + dwBits;
/* Try to increase the size of the bitmap info. buffer to hold the DIB */
hMem = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE);
if (!hMem){
GlobalFreeDIB(hDIB);
hDIB = NULL;
}
else
hDIB = hMem;
/* Read in the bits */
if (hDIB){
lpbih = (LPBITMAPINFOHEADER)hDIB;
_hread(hFile, (LPSTR)lpbih + (WORD)lpbih->biSize + ColorTableSize(lpbih), dwBits);
}
_lclose(hFile);
return hDIB;
}/* Macros to display/remove hourglass cursor for lengthy operations */
#define StartWait() hcurSave = SetCursor(LoadCursor(NULL, IDC_WAIT))
#define EndWait() SetCursor(hcurSave)
/******************************************************************************
* *
* FUNCTION : BitmapFromDIB(HANDLE hDIB, HPALETTE hPal) *
* *
* PURPOSE : Will create a DDB (Device Dependent Bitmap) given a global *
* handle to a memory block in CF_DIB format *
* *
* RETURNS : A handle to the DDB. *
* *
*****************************************************************************/
HBITMAP BitmapFromDIB (HANDLE hDIB, HPALETTE hPal)
{
LPBITMAPINFOHEADER lpbih;
HPALETTE hPalOld;
HDC hDC;
HBITMAP hBitmap;
StartWait();
if (!hDIB)
return NULL;
lpbih = (LPBITMAPINFOHEADER)hDIB;
if (!lpbih)
return NULL;
hDC = GetDC(NULL);
if (hPal){
hPalOld = SelectPalette(hDC, hPal, FALSE);
RealizePalette(hDC);
}
hBitmap = CreateDIBitmap(hDC,
lpbih,
CBM_INIT,
(LPSTR)lpbih + lpbih->biSize + ColorTableSize(lpbih),
(LPBITMAPINFO)lpbih,
DIB_RGB_COLORS );
if (hPal)
SelectPalette(hDC, hPalOld, FALSE);
ReleaseDC(NULL, hDC);
EndWait();
return hBitmap;
}
/******************************************************************************
* *
* FUNCTION : DrawBitmap(HDC hDC, int x, int y, *
* HBITMAP hBitmap, DWORD dwROP) *
* *
* PURPOSE : Draws bitmap <hBitmap> at the specified position in DC <hDC> *
* *
* RETURNS : Return value of BitBlt() *
* *
*****************************************************************************/
BOOL DrawBitmap (HDC hDC, INT x, INT y, HBITMAP hBitmap, DWORD dwROP)
{
HDC hDCBits;
BITMAP Bitmap;
BOOL bResult;
if (!hDC || !hBitmap)
return FALSE;
hDCBits = CreateCompatibleDC(hDC);
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
SelectObject(hDCBits, hBitmap);
bResult = BitBlt(hDC, x, y, Bitmap.bmWidth, Bitmap.bmHeight, hDCBits, 0, 0, dwROP);
DeleteDC(hDCBits);
return bResult;
}
/*FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
PURPOSE: Processes messages for the main window.
WM_COMMAND - process the application menu
WM_PAINT - Paint the main window
WM_DESTROY - post a quit message and return*/
#define ID_LOADBITMAP 1
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
//Handle to a GDI device context
HDC hDC;
//Handle to a DDB(device-dependent bitmap)
HBITMAP hBitmap;
HFONT hFont;
NONCLIENTMETRICS ncm={0};
ncm.cbSize= sizeof(NONCLIENTMETRICS);
static HWND hwndButton;
static HWND hwndButtonExit;
static HANDLE hDIB = NULL;
char szDirName[MAX_PATH];
char szFilename[MAX_PATH]="\0";
char szBitmapName[MAX_PATH]="\\Waterfall.bmp";
//char szBitmapName[MAX_PATH]="\\tulips256.bmp";
OPENFILENAMEA ofn;
switch (message)
{
case WM_CREATE:
//Creates a font from the current theme's caption font
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, NULL, &ncm, NULL);
hFont = CreateFontIndirect(&ncm.lfCaptionFont);
//Gets the device context for the current window
hDC = GetDC(hWnd);
//Gets the directory of the current project and loads Waterfall.bmp
GetCurrentDirectoryA(MAX_PATH, szDirName);
strcat_s(szDirName, szBitmapName);
strcat_s(szFilename,szDirName);
hDIB = OpenDIB(szFilename);
hBitmap = BitmapFromDIB(hDIB, NULL);
//Draws Waterfall.bmp as a device dependent bitmap
DrawBitmap(hDC,0,0,hBitmap,SRCCOPY);
InvalidateRect(hWnd, NULL, FALSE);
ReleaseDC(hWnd,hDC);
//Draws the "Load Bitmap" button
hwndButton = CreateWindowW(TEXT("button"),TEXT("Load Bitmap"),
WS_CHILD | WS_VISIBLE | WS_BORDER, 600, 200, 150,50,
hWnd,
(HMENU)ID_LOADBITMAP,
((LPCREATESTRUCT) lParam)-> hInstance, NULL);
//Set the font of the button to the theme's caption font
SendMessage(hwndButton, WM_SETFONT, (WPARAM)hFont, TRUE );
return 0;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
//if Load Bitmap button is pressed
if (wmId == ID_LOADBITMAP && wmEvent == BN_CLICKED)
{
//Get the current directory name, and store in szDirName
GetCurrentDirectoryA(MAX_PATH, szDirName);
//Set all structure members to zero.
ZeroMemory(&ofn, sizeof(OPENFILENAMEA));
//Initializing the OPENFILENAMEA structure
ofn.lStructSize = sizeof(OPENFILENAMEA);
ofn.hwndOwner = hWnd;
ofn.lpstrFilter ="BMP Files (*.BMP)\0 *.BMP\0\0";
ofn.lpstrFile = szFilename;
ofn.nMaxFile = sizeof(szFilename);
ofn.lpstrDefExt = "BMP";
ofn.lpstrInitialDir = szDirName;
ofn.Flags = OFN_EXPLORER | OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileNameA(&ofn)) {
hDIB = OpenDIB((LPSTR)szFilename);
if (!hDIB)
MessageBox(hWnd, TEXT("Unable to load file!"), TEXT("Oops"), MB_ICONSTOP);
} else {
if (strlen((const char *)szFilename) != 0)
MessageBox(hWnd, TEXT("Unable to load file!"), TEXT("Oops"), MB_ICONSTOP);
return 0;
}
InvalidateRect(hWnd, NULL, FALSE);
}
break;
case WM_PAINT:
{
//Initializing arrays for boxes
POINT pRect1[5] = {{0,0},{400,0},{400,400},{0,400},{0,0}};
POINT pRect2[5] = {{0,500}, {200, 500}, {200, 700}, {0,700},{0,500}};
POINT pRect3[5] = {{210,500}, {410, 500}, {410, 700}, {210,700},{210,500}};
POINT pRect4[5] = {{420,500}, {620, 500}, {620, 700}, {420,700},{420,500}};
POINT pRect5[5] = {{630,500}, {830, 500}, {830, 700}, {630,700},{630,500}};
//For the white background
RECT clientRect;
HRGN hRegion1;
HRGN hRegion2;
HRGN hRegion3;
HBRUSH hBGBrush;
//Handle to a logical font
HFONT hFont;
//Get the caption font that is currently in use
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, NULL, &ncm, NULL);
hFont = CreateFontIndirect(&ncm.lfCaptionFont);
//Begin drawing
hDC = BeginPaint(hWnd, &ps);
//Draw and fill rectangles for the background
GetClientRect(hWnd, &clientRect);
hRegion1 = CreateRectRgn(clientRect.left,clientRect.top,clientRect.right,clientRect.bottom);
hBGBrush = CreateSolidBrush(RGB(255,255,255));
FillRgn(hDC, hRegion1, hBGBrush);
//Create an HBITMAP(device dependent bitmap) to be drawn
hBitmap = BitmapFromDIB(hDIB,NULL);
//Draw the DDB
DrawBitmap(hDC,0,0,hBitmap,SRCCOPY);
if(hDIB)
{
hRegion2 = CreateRectRgn(401,0,clientRect.right,401);
hRegion3 = CreateRectRgn(0,401,clientRect.right,clientRect.bottom);
FillRgn(hDC,hRegion2,hBGBrush);
FillRgn(hDC,hRegion3,hBGBrush);
//Set stretch mode as BLACKONWHITE and then copy from the
//source rectangle into the smaller rectangle
SetStretchBltMode(hDC,BLACKONWHITE);
StretchBlt(hDC,0,500,200,200,hDC, 0,0,400,400,SRCCOPY);
//Set stretch mode as WHITEONBLACK and then copy from the
//source rectangle into the smaller rectangle
SetStretchBltMode(hDC,WHITEONBLACK);
StretchBlt(hDC,210,500,200,200, hDC, 0,0,400,400, SRCCOPY);
//Set stretch mode as COLORONCOLOR and then copy from the
//source rectangle into the smaller rectangle
SetStretchBltMode(hDC,COLORONCOLOR);
StretchBlt(hDC,420,500,200,200, hDC, 0,0,400,400, SRCCOPY);
//Set stretch mode as HALFTONE and then copy from the
//source rectangle into the smaller rectangle
SetStretchBltMode(hDC,HALFTONE);
StretchBlt(hDC,630,500,200,200, hDC, 0,0,400,400, SRCCOPY);
}
//Select the caption font created earlier
SelectObject(hDC,hFont);
//Create captions for each demonstration of color loss modes
TextOut(hDC,50,480,TEXT("BLACKONWHITE"),12);
TextOut(hDC,250,480,TEXT("WHITEONBLACK"),12);
TextOut(hDC,460,480,TEXT("COLORONCOLOR"),12);
TextOut(hDC,680,480,TEXT("HALFTONE"),8);
DeleteObject(hFont);
//Selecting the stock object pen to draw with
SelectObject(hDC, GetStockObject(DC_PEN));
//The pen is gray
SetDCPenColor(hDC, RGB(80,80,80));
//Polylines are drawn from arrays of POINTs
Polyline(hDC, pRect1, 5);
Polyline(hDC, pRect2, 5);
Polyline(hDC, pRect3, 5);
Polyline(hDC, pRect4, 5);
Polyline(hDC, pRect5, 5);
FillRgn(hDC,hRegion2,hBGBrush);
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}