⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 advbitmap.cpp

📁 Windows 图形编程 书籍
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------------//
//              Windows Graphics Programming: Win32 GDI and DirectDraw               //
//                             ISBN  0-13-086985-6                                   //
//                                                                                   //
//  Written            by  Yuan, Feng                             www.fengyuan.com   //
//  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
//  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
//                                                                                   //
//  FileName   : advbitmap.cpp					                                     //
//  Description: Advanced bitmap demo program, Chapter 11                            //
//  Version    : 1.00.000, May 31, 2000                                              //
//-----------------------------------------------------------------------------------//

#define STRICT
#define _WIN32_WINNT 0x0500
#define NOCRYPT

#include <windows.h>
#include <assert.h>
#include <tchar.h>
#include <math.h>

#include "..\..\include\wingraph.h"
#include "Resource.h"


class KDIBView : public KScrollCanvas
{
	typedef enum { GAP = 16 };

	virtual void    OnDraw(HDC hDC, const RECT * rcPaint);
	virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
	void			GetWndClassEx(WNDCLASSEX & wc);
	
	HMENU			m_hViewMenu;
	int				m_nViewOpt;
	HWND			m_hFrame;

public:

	HINSTANCE		m_hInst;
	KDIB			m_DIB;

	KDIBView(void)
	{
		m_hViewMenu = NULL;
		m_nViewOpt  = IDM_VIEW_STRETCHDIBITS;
	}

	bool Initialize(const TCHAR * pFileName, HINSTANCE hInstance, KStatusWindow * pStatus, HWND hFrame)
	{
		m_hFrame = hFrame;

		if ( m_DIB.LoadFile(pFileName) )
		{
			SetSize(m_DIB.GetWidth()  + GAP*2,
					m_DIB.GetHeight() + GAP*2, 5, 5);

			m_hInst   = hInstance;
			m_pStatus = pStatus;

			RegisterClass(_T("DIBView"), hInstance);
			
			return true;
		}
		else
			return false;
	}

	bool Initialize(BITMAPINFO * pDIB, HINSTANCE hInstance, KStatusWindow * pStatus, HWND hFrame)
	{
		m_hFrame = hFrame;

		if ( m_DIB.AttachDIB(pDIB, NULL, DIB_BMI_NEEDFREE) )
		{
			SetSize(m_DIB.GetWidth()  + GAP*2,
					m_DIB.GetHeight() + GAP*2, 5, 5);

			m_hInst   = hInstance;
			m_pStatus = pStatus;

			RegisterClass(_T("DIBView"), hInstance);
			
			return true;
		}
		else
			return false;
	}

	bool GetTitle(const TCHAR * pFileName, TCHAR * pTitle)
	{
		if ( pFileName )
		{
			wsprintf(pTitle, "%s, %d x %d pixel, %d bits", pFileName,
				m_DIB.GetWidth(), m_DIB.GetHeight(), m_DIB.GetDepth());

			return true;
		}
		else
			return false;
	}

	void CreateNewView(BITMAPINFO * pDIB, TCHAR * pTitle);
};


void KDIBView::GetWndClassEx(WNDCLASSEX & wc)
{
	memset(& wc, 0, sizeof(wc));

	wc.cbSize         = sizeof(WNDCLASSEX);
	wc.style          = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc    = WindowProc;
	wc.cbClsExtra     = 0;
	wc.cbWndExtra     = 0;       
	wc.hInstance      = NULL;
	wc.hIcon          = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_IMAGE));
	wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground  = (HBRUSH) (COLOR_GRAYTEXT + 1);
	wc.lpszMenuName   = NULL;
	wc.lpszClassName  = NULL;
	wc.hIconSm        = NULL;
}


// Let the main frame window handle it
void KDIBView::CreateNewView(BITMAPINFO * pDIB, TCHAR * pTitle)
{
	if ( pDIB )
		SendMessage(m_hFrame, WM_USER, (WPARAM) pDIB, (LPARAM) pTitle);
}


LRESULT KDIBView::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch( uMsg )
	{
		case WM_CREATE:
			m_hWnd		= hWnd;
			m_hViewMenu = LoadMenu(m_hInst, MAKEINTRESOURCE(IDR_DIBVIEW));
			return 0;

		case WM_PAINT:
			return KScrollCanvas::WndProc(hWnd, uMsg, wParam, lParam);

		case WM_SIZE:
		case WM_HSCROLL:
		case WM_VSCROLL:
		{
			LRESULT lr = KScrollCanvas::WndProc(hWnd, uMsg, wParam, lParam);

			int nMin, nMax, nPos;

			GetScrollRange(m_hWnd, SB_VERT, &nMin, &nMax);

			nPos = GetScrollPos(m_hWnd, SB_VERT);

			TCHAR mess[32];
			wsprintf(mess, "%d %d %d", nMin, nPos, nMax);
			m_pStatus->SetText(0, mess);

			return lr;
		}

		case WM_COMMAND:
			switch ( LOWORD(wParam) )
			{
				case IDM_VIEW_OVALMASK:
				case IDM_VIEW_STRETCHDIBCLIP:
				case IDM_VIEW_STRETCHBLTOVAL:
				case IDM_VIEW_STRETCHDIBITS:
				case IDM_VIEW_STRETCHDIBITS4:
				case IDM_VIEW_SETDIBITSTODEVICE:
				case IDM_VIEW_FITWINDOW:

				case IDM_VIEW_MASKRED:
				case IDM_VIEW_MASKGREEN:
				case IDM_VIEW_MASKBLUE:
				case IDM_VIEW_FADEIN:					
				case IDM_VIEW_ALPHAFADE:
				case IDM_VIEW_CUBE:
				case IDM_VIEW_CUBEPIXEL:
				case IDM_VIEW_SIMUPLGBLT:
					if ( LOWORD(wParam)!= m_nViewOpt )
					{
						m_nViewOpt = LOWORD(wParam);

						switch ( LOWORD(wParam) )
						{
							case IDM_VIEW_STRETCHDIBCLIP:
							case IDM_VIEW_OVALMASK:
							case IDM_VIEW_STRETCHBLTOVAL:
							case IDM_VIEW_STRETCHDIBITS:
							case IDM_VIEW_SETDIBITSTODEVICE:
							case IDM_VIEW_FADEIN:
							case IDM_VIEW_ALPHAFADE:
								SetSize(m_DIB.GetWidth() + GAP*2, m_DIB.GetHeight() + GAP*2, 5, 5, true);
								break;

							case IDM_VIEW_CUBE:
							case IDM_VIEW_CUBEPIXEL:
							case IDM_VIEW_SIMUPLGBLT:
							case IDM_VIEW_STRETCHDIBITS4:
								SetSize(m_DIB.GetWidth()*2 + GAP*3, m_DIB.GetHeight()*2 + GAP*3, 5, 5, true);
								break;
						}

						InvalidateRect(hWnd, NULL, TRUE);
					}
					return 0;

				case IDM_VIEW_DIBHEXDUMP:
					SendMessage(GetParent(GetParent(hWnd)), WM_USER+1, (WPARAM) & m_DIB, 0);	
			}
			return 0;

		default:
			return CommonMDIChildProc(hWnd, uMsg, wParam, lParam, m_hViewMenu, 3);
	}
}


void TransparentBltDrawIcon(HDC hDC, int x, int y, HICON hIcon)
{
	ICONINFO iconinfo;
	GetIconInfo(hIcon, & iconinfo);

	BITMAP bmp;
	GetObject(iconinfo.hbmMask, sizeof(bmp), & bmp);

	HDC hMemDC = CreateCompatibleDC(NULL);
	HGDIOBJ hOld = SelectObject(hMemDC, iconinfo.hbmColor);

	COLORREF crTrans = GetPixel(hMemDC, 0, 0);

	G_TransparentBlt(hDC,    x, y, bmp.bmWidth, bmp.bmHeight, 
		           hMemDC, 0, 0, bmp.bmWidth, bmp.bmHeight,
		           crTrans);

	SelectObject(hMemDC, hOld);
	DeleteObject(iconinfo.hbmMask);
	DeleteObject(iconinfo.hbmColor);
	DeleteObject(hMemDC);
}


void TestPlgBlt(HDC hDC, int x, int y, int w, int h, const BITMAPINFO * pBMI, const void * pBits, HINSTANCE hInstance, bool bSimulate)
{
	HBITMAP hBmp   = CreateDIBSection(hDC, pBMI, DIB_RGB_COLORS, NULL, NULL, NULL);
	HDC     hMemDC = CreateCompatibleDC(hDC);

	SelectObject(hMemDC, hBmp);
	StretchDIBits(hMemDC, 0, 0, w, h, 0, 0, w, h, pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
	
	HBITMAP hBack = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_WOOD01));
	BITMAP bmp;
	GetObject(hBack, sizeof(bmp), & bmp);
	MaskCube(hDC, 200, x, y, bmp.bmWidth, bmp.bmHeight, hBack, hMemDC, false, bSimulate);
	DeleteObject(hBack);

	MaskCube(hDC, 200, x, y, w, h, hBmp, hMemDC, true, bSimulate);

	DeleteObject(hMemDC);
	DeleteObject(hBmp);
}


void TestDIBTransform(HDC hDC, int x, int y, int w, int h, KDIB * pSrc)
{
	KAffine affine;

	affine.Rotate(-15);

	HBITMAP hBitmap = pSrc->TransformBitmap(& affine.m_xm, RGB(0xFF, 0xFF, 0), KDIB::method_direct);

	HDC hMemDC = CreateCompatibleDC(hDC);
	SelectObject(hMemDC, hBitmap);
	
	BITMAP bmp;

	GetObject(hBitmap, sizeof(BITMAP), & bmp);
	BitBlt(hDC, x, y, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, SRCCOPY);
	DeleteObject(hMemDC);
	DeleteObject(hBitmap);
}


BOOL OvalStretchDIBits(HDC hDC, int XDest, int YDest, int nDestWidth, int nDestHeight, 
			  int XSrc, int YSrc, int nSrcWidth, int nSrcHeight,
			  const void *pBits, const BITMAPINFO *pBMI, UINT iUsage)
{
	StretchDIBits(hDC, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, 
		nSrcWidth, nSrcHeight, pBits, pBMI, iUsage, SRCINVERT);

	SaveDC(hDC);
	SelectObject(hDC, GetStockObject(BLACK_BRUSH));
	SelectObject(hDC, GetStockObject(BLACK_PEN));
	Ellipse(hDC, XDest, YDest, XDest + nDestWidth, YDest + nDestHeight);
	RestoreDC(hDC, -1);

	return StretchDIBits(hDC, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, 
		nSrcWidth, nSrcHeight, pBits, pBMI, iUsage, SRCINVERT);
}


BOOL ClipOvalStretchDIBits(HDC hDC, int XDest, int YDest, int nDestWidth, int nDestHeight, 
			  int XSrc, int YSrc, int nSrcWidth, int nSrcHeight,
			  const void *pBits, const BITMAPINFO *pBMI, UINT iUsage)
{
	RECT rect = { XDest, YDest, XDest + nDestWidth, YDest + nDestHeight };
	LPtoDP(hDC, (POINT *) & rect, 2);

	HRGN hRgn = CreateEllipticRgnIndirect(& rect);

	SaveDC(hDC);

	SelectClipRgn(hDC, hRgn);
	DeleteObject(hRgn);

	BOOL rslt = StretchDIBits(hDC, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, 
		nSrcWidth, nSrcHeight, pBits, pBMI, iUsage, SRCCOPY);
	
	RestoreDC(hDC, -1);

	return rslt;
}


BOOL AlphaFade(HDC hDCDst, int XDst, int YDst, int nDstWidth, int nDstHeight,
			   HDC hDCSrc, int XSrc, int YSrc, int nSrcWidth, int nSrcHeight)
{
	for (int i=5; i>=1; i--)
	{
		// 1/5, 1/4, 1/3, 1/2, 1/1
		BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255 / i , 0 };

		AlphaBlend(hDCDst, XDst, YDst, nDstWidth, nDstHeight,
			       hDCSrc, YSrc, YSrc, nSrcWidth, nSrcHeight,
				   blend);
	}

	return TRUE;
}


BOOL OvalStretchBlt(HDC hDC,    int XDest, int YDest, int nDestWidth, int nDestHeight, 
				    HDC hDCSrc, int XSrc,  int YSrc,  int nSrcWidth,  int nSrcHeight)
{
	// Make the region outside the ellipse be BLACK in source surface
	SaveDC(hDCSrc);
	BeginPath(hDCSrc);
	Rectangle(hDCSrc, XSrc, YSrc, XSrc + nSrcWidth+1, YSrc + nSrcHeight+1);
	Ellipse(hDCSrc, XSrc, YSrc, XSrc + nSrcWidth, YSrc + nSrcHeight);
	EndPath(hDCSrc);
	SelectObject(hDCSrc, GetStockObject(BLACK_BRUSH));
	SelectObject(hDCSrc, GetStockObject(BLACK_PEN));
	FillPath(hDCSrc);
	RestoreDC(hDCSrc, -1);
	
	// Draw a BLACK ellipse in destination surface
	SaveDC(hDC);
	SelectObject(hDC, GetStockObject(BLACK_BRUSH));
	SelectObject(hDC, GetStockObject(BLACK_PEN));
	Ellipse(hDC, XDest, YDest, XDest + nDestWidth, YDest + nDestHeight);
	RestoreDC(hDC, -1);

	// Merge source surface to destination
	return StretchBlt(hDC, XDest, YDest, nDestWidth, nDestHeight, hDCSrc, XSrc, YSrc, 
		nSrcWidth, nSrcHeight, SRCPAINT);
}


extern DWORD dibtick;


void KDIBView::OnDraw(HDC hDC, const RECT * rcPaint)
{
	DWORD tm = GetTickCount();
	
	dibtick = 0;
	int w = m_DIB.GetWidth();
	int h = m_DIB.GetHeight();

	switch ( m_nViewOpt )
	{
		case IDM_VIEW_FITWINDOW:
			{
				RECT rect;

				GetClientRect(m_hWnd, & rect);
				m_DIB.DrawDIB(hDC, 0, 0, rect.right, rect.bottom, 0, 0, w, h, SRCCOPY);
			}
			break;

		case IDM_VIEW_MASKRED:
			{
				HDC     hMemDC = CreateCompatibleDC(NULL);
				HBITMAP hBmp = ChannelSplit(m_DIB.GetBMI(), m_DIB.GetBits(), RGB(0xFF, 0, 0), hMemDC);

				BitBlt(hDC, 0, 0, w, h, hMemDC, 0, 0, SRCCOPY);
				DeleteObject(hBmp);
				DeleteObject(hMemDC);

			//	CGDIObject red(hDC, CreateSolidBrush(RGB(0xFF, 0, 0)));
			//	m_DIB.DrawDIB(hDC, GAP,   GAP,    w, h, 0, 0,  w,  h, MERGECOPY);
			}
			break;

		case IDM_VIEW_MASKGREEN:
			{
				KGDIObject red(hDC, CreateSolidBrush(RGB(0, 0xFF, 0)));
				m_DIB.DrawDIB(hDC, GAP,   GAP,    w, h, 0, 0,  w,  h, MERGECOPY);
			}
			break;

		case IDM_VIEW_MASKBLUE:
			{
				KGDIObject red(hDC, CreateSolidBrush(RGB(0, 0, 0xFF )));
				m_DIB.DrawDIB(hDC, GAP,   GAP,    w, h, 0, 0,  w,  h, MERGECOPY);
			}
			break;

		case IDM_VIEW_FADEIN:
			FadeIn(hDC, GAP, GAP, w, h, m_DIB.GetBMI(), m_DIB.GetBits());
			break;

		case IDM_VIEW_OVALMASK:
			OvalStretchDIBits(hDC, GAP, GAP, w, h, 0, 0, w, h, m_DIB.GetBits(), m_DIB.GetBMI(), DIB_RGB_COLORS);
			break;

		case IDM_VIEW_STRETCHDIBCLIP:
			ClipOvalStretchDIBits(hDC, GAP, GAP, w, h, 0, 0, w, h, m_DIB.GetBits(), m_DIB.GetBMI(), DIB_RGB_COLORS);
			break;

		case IDM_VIEW_ALPHAFADE:
			{
				HBITMAP hBmp = m_DIB.ConvertToDDB(hDC);
				HDC hMemDC   = CreateCompatibleDC(hDC);
				SelectObject(hMemDC, hBmp);

				AlphaFade(hDC, GAP, GAP, w, h, hMemDC, 0, 0, w, h);
				
				DeleteObject(hMemDC);
				DeleteObject(hBmp);
			}
			break;

		case IDM_VIEW_STRETCHBLTOVAL:
			{
				HBITMAP hBmp = m_DIB.ConvertToDDB(hDC);
				HDC hMemDC   = CreateCompatibleDC(hDC);
				SelectObject(hMemDC, hBmp);

				OvalStretchBlt(hDC, GAP, GAP, w, h, hMemDC, 0, 0, w, h);
				
				DeleteObject(hMemDC);
				DeleteObject(hBmp);
			}
			break;

		case IDM_VIEW_STRETCHDIBITS:
			m_DIB.DrawDIB(hDC, GAP,   GAP,    w, h, 0, 0,  w,  h, SRCCOPY);
			break;

		case IDM_VIEW_STRETCHDIBITS4:
			m_DIB.DrawDIB(hDC, GAP,     GAP,     w, h, 0, 0,  w,  h, SRCCOPY);
			m_DIB.DrawDIB(hDC, GAP*2+w, GAP,     w, h, w, 0, -w,  h, SRCCOPY);
			m_DIB.DrawDIB(hDC, GAP,     GAP*2+h, w, h, 0, h,  w, -h, SRCCOPY);
			m_DIB.DrawDIB(hDC, GAP*2+w, GAP*2+h, w, h, w, h, -w, -h, SRCCOPY);
			break;

		case IDM_VIEW_SETDIBITSTODEVICE:
			if ( ! m_DIB.IsCompressed() )
			{
				int  bps      = m_DIB.GetBPS();
				BYTE * buffer = new BYTE[bps];

				for (int i=0; i<m_DIB.GetHeight(); i++)
				{
					memcpy(buffer, m_DIB.GetBits() + bps*i, bps);

					for (int j=0; j<bps; j++)
						buffer[j] = ~ buffer[j];

					m_DIB.SetDIB(hDC, GAP, GAP, i, 1, buffer);
				}
				delete [] buffer;
			}
			break;

		case IDM_VIEW_CUBE:
			TestPlgBlt(hDC, GAP, GAP, w, h, m_DIB.GetBMI(), m_DIB.GetBits(), m_hInst, false);
			break;

		case IDM_VIEW_SIMUPLGBLT:
			TestPlgBlt(hDC, GAP, GAP, w, h, m_DIB.GetBMI(), m_DIB.GetBits(), m_hInst, true);
			break;

		case IDM_VIEW_CUBEPIXEL:
			TestDIBTransform(hDC, GAP, GAP, w, h, & m_DIB);
			break;

	}
	RestoreDC(hDC, -1);

	tm = GetTickCount() - tm;

	if ( dibtick )
		tm = dibtick;

	TCHAR mess[32];
	wsprintf(mess, "Time %d ms", tm);
	m_pStatus->SetText(1, mess);
}

//////////////////////////////////////////////

void TestRop3(HINSTANCE hInstance, HDC hDC);

void TestIcons(HDC hDC)
{
	static HINSTANCE hMod = NULL;
	
	if ( hMod==NULL )
		hMod = LoadLibrary("Shell32.dll");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -