【MFC系列-第23天】CMemoryDC的封装过程
生活随笔
收集整理的這篇文章主要介紹了
【MFC系列-第23天】CMemoryDC的封装过程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
CDC(HDC)繪圖類:
五大GDI對象類:CPen,CBrush,CFont,CBitmap,CRgn
23.1 LoadImage API
HANDLE LoadImage(HINSTANCE hinst,LPCTSTR lpszName, UINT uType, int cxDesired,int cyDesired,UINT fuLoad );uType參數填寫以下三種:
IMAGE_BITMAP Loads a bitmap.IMAGE_CURSOR Loads a cursor.IMAGE_ICON Loads an icon從HINSTANCE內部加載
void CTestImageDlg::OnBnClickedButton1() {static HICON hIcon = (HICON)::LoadImage(theApp.m_hInstance, (LPCTSTR)IDI_TEST, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);SetIcon(hIcon, TRUE);SetIcon(hIcon, FALSE);//*.cur }m_hBitmap = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1),IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);m_hBitmap = ::LoadBitmap(theApp.m_hInstance, MAKEINTRESOURCE(IDB_BITMAP1));從文件中直接加載
m_hBitmap = (HBITMAP)::LoadImage(NULL, _T("./ban.bmp"),IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);HICON hIcon = (HICON)::LoadImage(NULL, _T("DfIcon.ico"),IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE| LR_DEFAULTSIZE);SetIcon(hIcon, TRUE);SetIcon(hIcon, FALSE);顯示
//CDC mdc; //BITMAP bm; //::GetObject(m_hBitmap, sizeof(bm), &bm); //mdc.CreateCompatibleDC(&dc); //mdc.SelectObject(m_hBitmap); dc.BitBlt(10, 40, m_mdc.GetWidth(), mdc.GetHeight(), &m_mdc, 0, 0, SRCCOPY);23.2 解決閃爍問題:
1、禁用非客戶區輸出,讓非客戶區WM_NCPAINT產生空輸出。
2、禁用客戶區背景輸出:WM_ERASEBKGRAND消息是Invalidate(TRUE)要調用的背景輸出。
3、調用Invalidate函數時,盡量使用FALSE。
4、當有多層次輸出時,使用雙緩沖技術,在內存中做好多次輸出的草稿。
23.3 CMemoryDC類
#ifndef __MEMDC_H__ #define __MEMDC_H__ //Author:www.baojy.comclass CMemoryDC :public CDC {CSize m_size; public:void BitTrans(int nXDest, // 目標起點Xint nYDest, // 目標起點Yint nWidthDest, // 目標寬度int nHeightDest,// 目標高度CDC* pDC, // 目標DCint nXSrc, // 來源起點Xint nYSrc, // 來源起點YCOLORREF crTrans// 透明色){CMemoryDC dcImage(nWidthDest, nHeightDest,pDC);//臨時DCCBitmap bmpMask;bmpMask.CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL); // 創建單色掩碼位圖CDC dcMask;//掩碼DC dcMask.CreateCompatibleDC(pDC);dcMask.SelectObject(bmpMask);//將載入位圖的內存DC中的位圖,拷貝到臨時DC中dcImage.BitBlt( 0, 0, nWidthDest, nHeightDest, this, nXSrc, nYSrc, SRCCOPY);// 設置臨時DC的透明色dcImage.SetBkColor(crTrans);//掩碼DC的透明區域為白色其它區域為黑色dcMask.BitBlt(0, 0, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCCOPY);//臨時DC透明區域為黑色,其它區域保持不變dcImage.SetBkColor(RGB(0,0,0));dcImage.SetTextColor(RGB(255,255,255));dcImage.BitBlt( 0, 0, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);// 目標DC透明部分保持屏幕不變,其它部分變成黑色pDC ->SetBkColor(RGB(255,255,255));pDC ->SetTextColor(RGB(0,0,0));pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCPAINT);} void StretchTrans(int nXDest, // 目標起點Xint nYDest, // 目標起點Yint nWidthDest, // 目標寬度int nHeightDest, // 目標高度CDC* pDC, // 目標DCint nXSrc, // 來源起點Xint nYSrc, // 來源起點Yint nWidthSrc, // 來源寬度int nHeightSrc, // 來源高度COLORREF crTrans // 透明色){CMemoryDC dcImage(nWidthDest, nHeightDest,pDC);//臨時DCCBitmap bmpMask;// 創建單色掩碼位圖bmpMask.CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);CDC dcMask;dcMask.CreateCompatibleDC(pDC);dcMask.SelectObject(bmpMask);// 將載入位圖的內存DC中的位圖,拷貝到臨時DC中if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)dcImage.BitBlt(0, 0, nWidthDest, nHeightDest, this, nXSrc, nYSrc, SRCCOPY);elsedcImage.StretchBlt(0, 0, nWidthDest, nHeightDest, this, nXSrc, nYSrc, nWidthSrc, nHeightSrc, SRCCOPY);// 設置臨時DC的透明色dcImage.SetBkColor( crTrans);//掩碼DC的透明區域為白色其它區域為黑色dcMask.BitBlt(0,0,nWidthDest, nHeightDest,&dcImage,0,0,SRCCOPY);//臨時DC透明區域為黑色,其它區域保持不變dcImage.SetBkColor(RGB(0,0,0));dcImage.SetTextColor(RGB(255,255,255));dcImage.BitBlt(0, 0, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);// 目標DC透明部分保持屏幕不變,其它部分變成黑色pDC ->SetBkColor(RGB(255,255,255));pDC ->SetTextColor(RGB(0,0,0));pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);pDC ->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCPAINT);} CMemoryDC(){m_size.cx = m_size.cy = 0;}//從資源中加載位圖BOOL LoadBitmap(UINT nBitmapID,CDC* pDC=NULL){CBitmap bitmap;bitmap.LoadBitmap(nBitmapID);BITMAP bm;bitmap.GetBitmap(&bm);m_size.cx = bm.bmWidth;m_size.cy = bm.bmHeight;CreateCompatibleDC(pDC);SelectObject(bitmap);return TRUE;}CMemoryDC(UINT nBitmapID,CDC* pDC=NULL){LoadBitmap(nBitmapID,pDC);}//從.bmp文件中加載位圖BOOL LoadBitmap(LPCTSTR szBitmapFile,CDC* pDC=NULL){HBITMAP hBitmap = (HBITMAP)LoadImage(AfxGetInstanceHandle(),szBitmapFile,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);BITMAP bm;GetObject(hBitmap,sizeof(bm),&bm);m_size.cx = bm.bmWidth;m_size.cy = bm.bmHeight;CreateCompatibleDC(pDC);SelectObject(hBitmap); return TRUE;}CMemoryDC(LPCTSTR szBitmapFile,CDC* pDC=NULL){LoadBitmap(szBitmapFile,pDC);}//創建一張空白內存畫布BOOL Create(int cx,int cy,CDC* pDC = NULL){CreateCompatibleDC(pDC);CBitmap bitmap;if(pDC)bitmap.CreateCompatibleBitmap(pDC,cx,cy);elsebitmap.CreateCompatibleBitmap(&CClientDC(NULL),cx,cy);m_size.cx = cx;m_size.cy = cy;SelectObject(bitmap);return TRUE;}CMemoryDC(int cx,int cy,CDC* pDC = NULL){Create(cx,cy,pDC);}//摧毀BOOL DeleteDC(){if(!GetSafeHdc())return TRUE;CBitmap * pBitmap = GetCurrentBitmap();pBitmap ->DeleteObject();return CDC::DeleteDC();}~CMemoryDC(){DeleteDC();}inline int Width(){return m_size.cx;}inline int Height(){return m_size.cy;} }; #endif //__MEMDC_H__23.4 采用CMemoryDC類實現圖片旋轉
//1、加載資源位圖 //2、加載外部位圖 //3、創建空白位圖(黑色:指定高寬) //4、顯示透明和伸縮透明圖片 CMemoryDC m_dcBack; // 定義全局變量 m_dcBack.LoadBitmap(IDB_BITMAP1); // 初始化void CPageDlg::OnPaint() {CPaintDC dc(this); // 用于繪制的設備上下文CRect rect;GetClientRect(rect);CMemoryDC mdc(rect.Width(), rect.Height(),&dc);//緩沖DC:黑色mdc.FillSolidRect(rect, GetSysColor(COLOR_3DFACE)); // 緩沖DC:灰色mdc.StretchBlt(m_nLeft, 0, rect.Width() - m_nLeft * 2, rect.Height(),&m_dcBack, 0, 0, rect.Width(), rect.Height(), SRCCOPY); // 繪圖輸出到緩沖DC中dc.BitBlt(0, 0, rect.Width(),rect.Height(), &mdc, 0, 0, SRCCOPY);//一次性對界面(dc)輸出 }23.5 采用CMemoryDC類實現蝴蝶動畫
#include "MemoryDC.h" #pragma once// CfsDlg 對話框 class CfsDlg : public CDialogEx {CMemoryDC m_dc;//緩沖enum { PAGE_COUNT =7};CMemoryDC m_dcBack;CMemoryDC m_dcFly[PAGE_COUNT];struct SData{CPoint pos;CPoint dir;//5,5 -5,5 5,-5 -5,-5int nIndex;};CArray<SData> m_arr;//動態數組 public:CfsDlg(CWnd* pParent = NULL); // 標準構造函數 protected:HICON m_hIcon;virtual BOOL OnInitDialog();afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP() public:afx_msg BOOL OnEraseBkgnd(CDC* pDC);afx_msg void OnNcPaint();afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnTimer(UINT_PTR nIDEvent); };BOOL CfsDlg::OnInitDialog() {CDialogEx::OnInitDialog();srand(time(NULL));m_dcBack.LoadBitmap(_T("./images/back.bmp"));int cx = GetSystemMetrics(SM_CXSCREEN);int cy = GetSystemMetrics(SM_CYSCREEN);SetWindowPos(NULL, 0, 0, cx, cy, 0);m_dc.Create(cx, cy);int i = -1;CString str;while (++i<_countof(m_dcFly)){str.Format(_T("./images/%03d.bmp"), i + 1);m_dcFly[i].LoadBitmap(str);}SetTimer(1, 20, NULL);SetIcon(m_hIcon, TRUE); // 設置大圖標SetIcon(m_hIcon, FALSE); // 設置小圖標return TRUE; // 除非將焦點設置到控件,否則返回 TRUE }void CfsDlg::OnPaint() {CPaintDC dc(this); //界面dcCRect rect;GetClientRect(rect);//dc.BitBlt(0, 0, m_dcBack.GetWidth(), m_dcBack.GetHeight(), &m_dcBack, 0, 0, SRCCOPY);m_dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &m_dcBack, 0, 0, m_dcBack.GetWidth(), m_dcBack.GetHeight(), SRCCOPY);int i = 0,nSize = m_arr.GetSize();while (i < nSize){SData& d = m_arr[i];m_dcFly[d.nIndex].BitTrans(d.pos.x,d.pos.y ,m_dcFly->GetWidth(),m_dcFly->GetHeight(),&m_dc,0,0,0);if (++d.nIndex > 6)d.nIndex = 0;d.pos.Offset(d.dir);GetClientRect(rect);if (d.pos.x >= rect.right - m_dcFly->GetWidth() || d.pos.x <= 0)d.dir.x *= -1;if (d.pos.y >= rect.bottom - m_dcFly->GetHeight() || d.pos.y <= 0)d.dir.y *= -1; ++i;}dc.BitBlt(0, 0, rect.Width(), rect.Height(), &m_dc, 0, 0, SRCCOPY); }BOOL CfsDlg::OnEraseBkgnd(CDC* pDC) {return TRUE; }void CfsDlg::OnNcPaint() {}void CfsDlg::OnLButtonDown(UINT nFlags, CPoint point) {//無限增長的蝴蝶個數SData data = { point,{5,5},0 };if(rand()%2) //893253%2 data.dir.x *= -1;if (rand() % 2) //547547%2 data.dir.y *= -1;m_arr.Add(data);CDialogEx::OnLButtonDown(nFlags, point); }void CfsDlg::OnTimer(UINT_PTR nIDEvent) {Invalidate(FALSE);CDialogEx::OnTimer(nIDEvent); } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【MFC系列-第23天】CMemoryDC的封装过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 鬼泣5全特效电脑配置(鬼泣5高画质配置要
- 下一篇: 【多元域乘法】多项式乘法电路原理及MAT