最新visualC++编程200例书籍源码包括对数据库的操作

源代码在线查看: unibutton.cpp

软件大小: 23820 K
上传用户: junbo2009
关键词: visualC 200 编程 书籍
下载地址: 免注册下载 普通下载 VIP

相关代码

				// UniButton.cpp : implementation file
				//
				
				#include "stdafx.h"
				#include "MySphereButton.h"
				#include "UniButton.h"
				
				#ifdef _DEBUG
				#define new DEBUG_NEW
				#undef THIS_FILE
				static char THIS_FILE[] = __FILE__;
				#endif
				
				/////////////////////////////////////////////////////////////////////////////
				// CUniButton
				
				CUniButton::CUniButton()
				{
					m_nColor = GetSysColor(COLOR_BTNFACE);
					m_sColor = m_nColor;
					m_hColor = m_nColor;
					m_dColor = m_nColor;
					m_nBorder = 1;
					m_lfEscapement = 0;
					m_pNormal = NULL;
					m_pSelected = NULL;
					m_pHover = NULL;
					m_pDisabled = NULL;
					m_hRgn = 0;
					m_bHover = false;
					m_bCapture = false;
					m_bMouseDown = false;
					m_bNeedBitmaps = true;
				}
				
				CUniButton::~CUniButton()
				{
					delete m_pNormal;
					delete m_pSelected;
					delete m_pHover;
					delete m_pDisabled;
					DeleteObject(m_hRgn);
				}
				
				BEGIN_MESSAGE_MAP(CUniButton, CButton)
					//{{AFX_MSG_MAP(CUniButton)
					ON_WM_ERASEBKGND()
					ON_WM_MOUSEMOVE()
					ON_WM_CREATE()
					ON_WM_LBUTTONDOWN()
					ON_WM_LBUTTONUP()
					//}}AFX_MSG_MAP
				END_MESSAGE_MAP()
				
				/////////////////////////////////////////////////////////////////////////////
				// CUniButton message handlers
				
				BOOL CUniButton::Create(LPCTSTR lpszCaption, DWORD dwStyle, const CPoint point, const HRGN hRgn, CWnd* pParentWnd, UINT nID)
				{
					// store region in member variable
					DeleteObject(m_hRgn);
					m_hRgn = CreateRectRgn(0, 0, 31, 31);
					CRect box(0, 0, 0, 0);
					if (m_hRgn != 0) 
						CombineRgn(m_hRgn, hRgn, 0, RGN_COPY);
				
					// make sure that region bounding rect is located in (0, 0)
					GetRgnBox(m_hRgn, &box);
					OffsetRgn(m_hRgn, -box.left, -box.top);
					GetRgnBox(m_hRgn, &box);
				
					// update position of region center for caption output
					m_CenterPoint = CPoint(box.left + box.Width() /2 , box.top + box.Height() /2);
					box.OffsetRect(point);
				
					return CButton::Create(lpszCaption, dwStyle, box, pParentWnd, nID);
				}
				
				BOOL CUniButton::Create(LPCTSTR lpszCaption, DWORD dwStyle, const CPoint point, const HRGN hRgn, CWnd* pParentWnd, UINT nID, COLORREF color)
				{
					m_sColor = color;
					m_hColor = color;
				
					// call another constructor
					return Create(lpszCaption, dwStyle, point, hRgn, pParentWnd, nID);
				}
				
				BOOL CUniButton::Create(LPCTSTR lpszCaption, DWORD dwStyle, const CPoint point, const HRGN hRgn, CWnd* pParentWnd, UINT nID, UINT nBorder, LONG lfEscapement, COLORREF nColor, COLORREF sColor, COLORREF hColor, COLORREF dColor)
				{
					m_lfEscapement = lfEscapement;
					return Create(lpszCaption, dwStyle, point, hRgn, pParentWnd, nID, nBorder, nColor, sColor, hColor, dColor);
				}
				
				BOOL CUniButton::Create(LPCTSTR lpszCaption, DWORD dwStyle, const CPoint point, const HRGN hRgn, CWnd* pParentWnd, UINT nID, UINT nBorder, COLORREF nColor, COLORREF sColor, COLORREF hColor, COLORREF dColor)
				{
					// change default colors
					m_nBorder = nBorder;
					m_nColor = nColor;
					m_sColor = sColor;
					m_hColor = hColor;
					m_dColor = dColor;
				
					// call another constructor
					return Create(lpszCaption, dwStyle, point, hRgn, pParentWnd, nID);
				}
				
				void CUniButton::PreSubclassWindow() 
				{
					// change window style to allow owner draw
					ModifyStyle(0, BS_OWNERDRAW | BS_PUSHBUTTON);	
					CButton::PreSubclassWindow();
				}
				
				int CUniButton::OnCreate(LPCREATESTRUCT lpCreateStruct) 
				{
					if (CButton::OnCreate(lpCreateStruct) == -1)
						return -1;
				
					// assign new region to a window
					m_bNeedBitmaps = true;
					SetWindowRgn(m_hRgn, true);
				
					return 0;
				}
				
				void CUniButton::OnLButtonDown(UINT nFlags, CPoint point) 
				{
					// record that mouse is down
					m_bMouseDown = true;
					if (!m_bCapture) {
						SetCapture();
						m_bCapture = true;
					}
					CButton::OnLButtonDown(nFlags, point);
				}
				
				void CUniButton::OnLButtonUp(UINT nFlags, CPoint point) 
				{
					// record that mouse is released
					CButton::OnLButtonUp(nFlags, point);
				
					m_bMouseDown = false;	
					if (m_bCapture) {
						ReleaseCapture();
						m_bCapture = false;
					}
					CheckHover(point);
				}
				
				void CUniButton::OnMouseMove(UINT nFlags, CPoint point) 
				{
					// Test if mouse is above the button.
					if (!m_bMouseDown)
						CheckHover(point);
				
					CButton::OnMouseMove(nFlags, point);
				}
				
				void CUniButton::CheckHover(CPoint point)
				{
						if (HitTest(point)) {
							if (!m_bCapture) {
								SetCapture();
								m_bCapture = true;
							}
							if (!m_bHover) {
								m_bHover = true;
								RedrawWindow();
							}
						}
						else {
							if (m_bCapture) {
								ReleaseCapture();
								m_bCapture = false;
							}
							m_bHover = false;
							RedrawWindow();
						}
				}
				
				LRESULT CUniButton::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
				{
					// I have noticed that default windows buttons can be clicked very quickly.
					// Double or single click both result in a button being pushed down.
					// For owner drawn buttons this is not the case. Double click does
					// not push button down. Here is a solution for the problem:
					// double click message is substituted for single click.
				
					if (message == WM_LBUTTONDBLCLK)
						message = WM_LBUTTONDOWN;
					
					return CButton::DefWindowProc(message, wParam, lParam);
				}
				
				BOOL CUniButton::HitTest(CPoint point)
				{
					BOOL result = false;
				
					// Obtain handle to window region.
					HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
					GetWindowRgn(hRgn);
					CRect rgnRect;
					GetRgnBox(hRgn, &rgnRect);
				
					// First check if point is in region bounding rect.
					// Then check if point is in the region in adition to being in the bouding rect.
					result = PtInRect(&rgnRect, point) && PtInRegion(hRgn, point.x, point.y);
				
					// Clean up and exit.
					DeleteObject(hRgn);
					return result;
				}
				
				BOOL CUniButton::OnEraseBkgnd(CDC* pDC) 
				{
					// do not erase background
					return 1;
				}
				
				//////////////////////// DRAWING ROUTINES ////////////////////////////
				
				void CUniButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
				{
					// prepare DC
					CDC* pDC = CDC::FromHandle(lpDrawItemStruct -> hDC);
					CRect rect;
					GetClientRect(rect);
				
					// prepare bitmaps they need to be prepared
					if (m_bNeedBitmaps)
						PrepareStateBitmaps(pDC, &rect);
				
					// draw button to the screen
					DrawButton(pDC, &rect, lpDrawItemStruct -> itemState);
				}
				
				void CUniButton::PrepareStateBitmaps(CDC * pDC, CRect * pRect)
				{
					// prepare memory DC
					CDC * pMemDC;
					pMemDC = new CDC;
					pMemDC -> CreateCompatibleDC(pDC);
				
					// prepare bitmaps for all button states and for the mask
					PrepareNormalState(pDC, pMemDC, pRect);
					PrepareSelectedState(pDC, pMemDC, pRect);
					PrepareHoverState(pDC, pMemDC, pRect);
					PrepareDisabledState(pDC, pMemDC, pRect);
				
					// clean up
					delete pMemDC; 
					m_bNeedBitmaps = false;
				}
				
				
				void CUniButton::PrepareNormalState(CDC * pDC, CDC * pMemDC, CRect * pRect)
				{
					// prepare MYBS_NORMAL state bitmap
					delete m_pNormal;
					m_pNormal = new CBitmap;
					PaintRgn(pDC, pMemDC, m_pNormal, m_nColor, pRect, true, false);
				}
				
				void CUniButton::PrepareSelectedState(CDC * pDC, CDC * pMemDC, CRect * pRect)
				{
					// prepare MYBS_SELECTED state bitmap
					delete m_pSelected;
					m_pSelected = new CBitmap;
					PaintRgn(pDC, pMemDC, m_pSelected, m_sColor, pRect, true, true);
				}
				
				void CUniButton::PrepareHoverState(CDC * pDC, CDC * pMemDC, CRect * pRect)
				{
					// prepare MYBS_HOVER state bitmap
					delete m_pHover;
					m_pHover = new CBitmap;
					PaintRgn(pDC, pMemDC, m_pHover, m_hColor, pRect, true, false);
				}
				
				void CUniButton::PrepareDisabledState(CDC * pDC, CDC * pMemDC, CRect * pRect)
				{
					// prepare MYBS_DISABLED state bitmap
					delete m_pDisabled;
					m_pDisabled = new CBitmap;
					PaintRgn(pDC, pMemDC, m_pDisabled, m_dColor, pRect, false, false);
				}
				
				void CUniButton::PaintRgn(CDC * pDC, CDC * pMemDC, CBitmap * pBitmap, COLORREF color, CRect * pRect, BOOL bEnabled, BOOL bSunken)
				{
					// create bitmap
					pBitmap -> CreateCompatibleBitmap(pDC, pRect -> Width(), pRect -> Height());
					CBitmap * pOldBitmap = pMemDC -> SelectObject(pBitmap); 
				
					// prepare region
					HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
					GetWindowRgn(hRgn);
				
					// fill rect a with transparent color and fill rgn
					HBRUSH hBrush = CreateSolidBrush(color);
					pMemDC -> FillSolidRect(pRect, RGB(0, 0, 0));
					FillRgn(pMemDC -> GetSafeHdc(), hRgn, hBrush);
					DeleteObject(hBrush);
				
					// draw 3D border and text
					DrawButtonCaption(pMemDC -> GetSafeHdc(), pRect, bEnabled, bSunken);
					FrameRgn3D(pMemDC -> GetSafeHdc(), hRgn, bSunken);
				
					// clean up
					DeleteObject(hRgn);
					pMemDC -> SelectObject(pOldBitmap); 
				}
				
				void CUniButton::DrawButtonCaption(HDC hDC, CRect * pRect, BOOL bEnabled, BOOL bSunken) 
				{
					// select parent font
					int nOldMode = SetBkMode(hDC, TRANSPARENT);
					CString text;
					GetWindowText(text);
					LOGFONT lf;
					GetParent() -> GetFont() -> GetLogFont(&lf);
					HFONT hFont = CreateFontIndirect(&lf);
					HFONT hOldFont = (HFONT) SelectObject(hDC, hFont);
				
					// determine point where to output text
					TEXTMETRIC tm;
					GetTextMetrics(hDC, &tm);
					CPoint p = CPoint(m_CenterPoint.x, m_CenterPoint.y + tm.tmHeight/ 2); 
					if (bSunken) 
						p.Offset(m_nBorder, m_nBorder); 
						
					// draw button caption depending upon button state
					if (bEnabled) {
						SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT));
						SetTextAlign(hDC, TA_CENTER | TA_BOTTOM);
						TextOut(hDC, p.x, p.y, text, text.GetLength());
					}
					else {
						SetTextColor(hDC, GetSysColor(COLOR_3DHILIGHT));
						TextOut(hDC, p.x + 1, p.y + 1, text, text.GetLength());
						SetTextColor(hDC, GetSysColor(COLOR_3DSHADOW));
						TextOut(hDC, p.x, p.y, text, text.GetLength());
					}
				
					SelectObject(hDC, hOldFont);
					DeleteObject(hFont);
					SetBkMode(hDC, nOldMode);
				}
				
				void CUniButton::FrameRgn3D(HDC hDC, const HRGN hRgn, BOOL bSunken)
				{
					// we need two differenr regions to keep base region and border region
					HBRUSH hBrush;
					HRGN hBaseRgn = CreateRectRgn(0, 0, 0, 0);
				
					COLORREF ltOuter, ltInner, rbOuter, rbInner;	// colors of inner and outer shadow for top-left and right-bottom corners
				
					// decide on color scheme
					if (!bSunken) {
						ltOuter = GetSysColor(COLOR_3DLIGHT);
						ltInner = GetSysColor(COLOR_3DHILIGHT);
						rbOuter = GetSysColor(COLOR_3DDKSHADOW);
						rbInner = GetSysColor(COLOR_3DSHADOW);
					}
					else {
						rbInner = GetSysColor(COLOR_3DLIGHT);
						rbOuter = GetSysColor(COLOR_3DHILIGHT);
						ltInner = GetSysColor(COLOR_3DDKSHADOW);
						ltOuter = GetSysColor(COLOR_3DSHADOW);
					}
				
					// offset highlight and shadow regions
					// substract them from the base region 
					switch (m_nBorder)
					{
					case 2:
						CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
						OffsetRgn(hBaseRgn, 2, 2);
						CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
						hBrush = CreateSolidBrush(ltInner);
						FillRgn(hDC, hBaseRgn, hBrush);
						DeleteObject(hBrush);
				
						CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
						OffsetRgn(hBaseRgn, -2, -2);
						CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
						hBrush = CreateSolidBrush(rbInner);
						FillRgn(hDC, hBaseRgn, hBrush);
						DeleteObject(hBrush);
				
						CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
						OffsetRgn(hBaseRgn, 1, 1);
						CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
						hBrush = CreateSolidBrush(ltOuter);
						FillRgn(hDC, hBaseRgn, hBrush);
						DeleteObject(hBrush);
				
						CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
						OffsetRgn(hBaseRgn, -1, -1);
						CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
						hBrush = CreateSolidBrush(rbOuter);
						FillRgn(hDC, hBaseRgn, hBrush);
						DeleteObject(hBrush);
						break;
					default:
						CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
						OffsetRgn(hBaseRgn, 1, 1);
						CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
						hBrush = CreateSolidBrush(ltInner);
						FillRgn(hDC, hBaseRgn, hBrush);
						DeleteObject(hBrush);
				
						CombineRgn(hBaseRgn, hRgn, 0, RGN_COPY);
						OffsetRgn(hBaseRgn, -1, -1);
						CombineRgn(hBaseRgn, hRgn, hBaseRgn, RGN_DIFF);
						hBrush = CreateSolidBrush(rbOuter);
						FillRgn(hDC, hBaseRgn, hBrush);
						DeleteObject(hBrush);
						break;
					}
					
					// clean up regions
					DeleteObject(hBaseRgn);
				}
				
				void CUniButton::DrawButton(CDC * pDC, CRect * pRect, UINT state)
				{
					// create memory DC
					CDC * pMemDC = new CDC;
					pMemDC -> CreateCompatibleDC(pDC);
					CBitmap * pOldBitmap;
				
					// get region
					HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
					GetWindowRgn(hRgn);
				
					// select bitmap to paint depending upon button state
					if (state & ODS_DISABLED)
						pOldBitmap = pMemDC -> SelectObject(m_pDisabled);
					else {
						if (state & ODS_SELECTED)
							pOldBitmap = pMemDC -> SelectObject(m_pSelected);
						else {
							if (m_bHover)
								pOldBitmap = pMemDC -> SelectObject(m_pHover);
							else 
								pOldBitmap = pMemDC -> SelectObject(m_pNormal);
						}	
					}
				
					// paint using region for clipping
					::SelectClipRgn(pDC -> GetSafeHdc(), hRgn);
					pDC -> BitBlt(0, 0, pRect -> Width(), pRect -> Height(), pMemDC, 0, 0, SRCCOPY);
					::SelectClipRgn(pDC -> GetSafeHdc(), NULL);
				
					// clean up
					DeleteObject(hRgn);
					pMemDC -> SelectObject(pOldBitmap);
					delete pMemDC;
				}
				
				void CUniButton::RgnPixelWork(CDC * pDC, CRgn * pRgn)
				{
					// get size of data composing region
					int size = pRgn -> GetRegionData(NULL, 0);
					HANDLE hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
					RGNDATA * pData = (RGNDATA *)GlobalLock(hData);
				
					// retrieve region data
					int res = pRgn -> GetRegionData(pData, size);
					RECT * pRect = (RECT *) pData -> Buffer;
				
					// now we know how region is represented and we are able to manipulate it as we like
					for (DWORD i = 0; i < pData -> rdh.nCount; i++) {
						RECT rect = *(pRect + i);
						for (int x = rect.left; x < rect.right; x++)
							for (int y = rect.top; y < rect.bottom; y++) {
								// use SetPixel(x, y, color) to do pixel work
							}
					}
				
					// free region data
					GlobalUnlock(hData);
					GlobalFree(hData);
				}
							

相关资源