GDI+

xiaoxiao2021-02-28  70

界面编程总结(1) http://blog.csdn.net/byxdaz/article/details/5499564 白乔原创:VC之美化界面篇 http://blog.csdn.net/bluejoe2000/article/details/4269540#comments 双缓冲技术(基于GDI+实现) http://blog.csdn.net/woaisia/article/details/46788965 设置对话框背景色 SetBackgroundColor(RGB(0,0,255));

一、GDI+初始化

(1)、引用stdafx.h

#include <GdiPlus.h> using namespace Gdiplus; #pragma comment( lib, "Gdiplus.lib")

(2)、public CWinApp头文件定义两个全局变量

GdiplusStartupinput m_Gdiplus ULONG_PTR m_pGdiToken

(3)、在应用程序或对话框初始化时加载GDI+(InitInstance)

GdiplusStartup(&m_pGdiToken,&m_Gdiplus,NULL)

(4)、在应用程序结束时卸载GDI+(ExitInstance)

GdiplusShutdown(m_pGdiToken)

二、简单的GDI+双缓冲的分析与实现

1.在内存中建立一块“虚拟画布”:

 //获取窗口客区宽高  RECT r;  GetClientRect(m_hWnd,&r);  m_bufW=r.right; m_bufH=r.bottom;  //在内存中建立一个Image的派生类Bitma对象做为"画布"  Bitmap memBitmap(m_bufW,m_bufH);

2.获取这块内存画布的Graphics引用:

 Graphics memGr(&memBitmap);

3.在这块内存画布上绘图:

 //这里可以通过memGr在memBitmap上绘制多个图元  //我只举例绘制了一张图片  Image* pimage=NULL;  pimage=new Image(L"res//图片1.png");  int w=pimage->GetWidth();  int h=pimage->GetHeight();  memGr.DrawImage(pimage,0,0,0,0,w,h,UnitPixel);  delete pimage;  pimage=NULL;

4、将内存画布画到窗口中

 m_hDC = GetDC(m_hWnd);  Graphics gr(m_hDC);  gr.DrawImage(&memBitmap,0,0);   ReleaseDC(m_hWnd,m_hDC);

三、背景透明

//1///

CMyListCtrl::OnEraseBkgnd(CDC* pDC) {     CMyListCtrl *pParent = (CMyListCtrl*)GetParent();     CWnd *pParent = GetParent();       CRect rc;     GetWindowRect(rc);     pParent->ScreenToClient(rc);     pParent->InvalidateRect(rc,false);     pParent->UpdateWindow();     CDC *dcParent = pParent->GetDC();       pDC->BitBlt(0,0,rc.Width(),rc.Height(),dcParent,rc.left,rc.top,SRCCOPY);     pParent->ReleaseDC(dcParent);  return true; }

/2

::OnEraseBkgnd(CDC* pDC) {    if (m_Bmp.GetSafeHandle() == NULL)    {       CRect Rect;       GetWindowRect(&Rect);       CWnd *pParent = GetParent();       ASSERT(pParent);       pParent->ScreenToClient(&Rect);  //convert our corrdinates to our parents             //copy what's on the parents at this point       CDC *pDC = pParent->GetDC();       CDC MemDC;       MemDC.CreateCompatibleDC(pDC);       m_Bmp.CreateCompatibleBitmap(pDC,Rect.Width(),Rect.Height());       CBitmap *pOldBmp = MemDC.SelectObject(&m_Bmp);       MemDC.BitBlt(0,0,Rect.Width(),Rect.Height(),pDC,Rect.left,Rect.top,SRCCOPY);       MemDC.SelectObject(pOldBmp);       pParent->ReleaseDC(pDC);    }    else //copy what we copied off the parent the first time back onto the parent    {       CRect Rect;       GetClientRect(Rect);       CDC MemDC;       MemDC.CreateCompatibleDC(pDC);       CBitmap *pOldBmp = MemDC.SelectObject(&m_Bmp);       pDC->BitBlt(0,0,Rect.Width(),Rect.Height(),&MemDC,0,0,SRCCOPY);       MemDC.SelectObject(pOldBmp);    }    return TRUE; }

3//

HBRUSH CMFCDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) {  HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);  //这种情况除非背景是纯色才行 /* if(nCtlColor == CTLCOLOR_BTN)  {   pDC->SetBkMode(TRANSPARENT);   hbr = (HBRUSH) ::GetStockObject(NULL_BRUSH);  } */  //没办法,搞一个万能的。很奇怪,在背景是图片的情况下,nCtlColor都不等于CTLCOLOR_BTN了,但经过断点可以肯定,  //每个控件都会进入这个消息  UINT id = pWnd->GetDlgCtrlID();  if(id == IDC_RADIO1 || id == IDC_CHECK1|| id== IDC_LIST1)  {      pDC->SetBkMode(TRANSPARENT);   CRect rc;   pWnd->GetWindowRect(&rc);   ScreenToClient(&rc);   CDC* dc = GetDC();   pDC->BitBlt(0,0,rc.Width(),rc.Height(),dc,rc.left,rc.top,SRCCOPY); //把父窗口背景图片先画到按钮上   ReleaseDC(dc);   hbr = (HBRUSH) ::GetStockObject(NULL_BRUSH);  }    return hbr; }

四、GDI+双缓冲

方案1

CDC dcMemory; dcMemory.CreateCompatibleDC(&dc); CBitmap bmp; bmp.CreateCompatibleBitmap(&dc,1024,768); dcMemory.SelectObject(&bmp);   Graphics _Graphics(dcMemory.m_hDC); Gdiplus::Image image(_T("res//asus.png")); _Graphics.DrawImage(&image,0,0,1024,768); //这是在GDI+中的写法。   dc.BitBlt(0,0,1024,768,&dcMemory,0,0,SRCCOPY); _Graphics.ReleaseHDC(dcMemory.m_hDC); dcMemory.DeleteDC(); bmp.DeleteObject();

方案2(不可取)

(1)在内存中新建画布

Bitmap bmp=new Bitmap(600,600);

(2)获取这块内存画布的Graphics引用

Graphics g=Graphics.FromImage(bmp);

(3)在这块内存画布上绘图

g.FillEllipse(brush,10,10,10,10);

(4)将内存画布画到窗口

Graphics graphice(dc.m_hDC); graphics.DrawImage(&bmp,rect.left,rect.top,rect.right,rect.bottom);

五、 资源加载方法

 CGdiPlusBitmapResource* pBitmap = new CGdiPlusBitmapResource;  if (pBitmap->Load(IDB_LOGO, _T("PNG")))  {   CClientDC dc(this);   Gdiplus::Graphics graphics(dc);   graphics.DrawImage(*pBitmap, 0, 0);  }  else  {   //AfxMessageBox("Failure loading image");  }  delete pBitmap;  */ / //picture控件 type=Owner Draw  /*  //第一种,显示实际png图片,与控件大小无关  //CPaintDC *pDC = new CPaintDC(GetDlgItem(IDC_STATIC_PIC));也可以  CClientDC *pDC = new CClientDC(GetDlgItem(IDC_STATIC_PIC));  CRect rect;  GetDlgItem(IDC_STATIC_PIC)->GetWindowRect(&rect);  Graphics graphics(pDC->m_hDC); // Create a GDI+ graphics object  Image image(_T("1.png")); // Construct an image  graphics.DrawImage(&image, 0, 0, image.GetWidth(), image.GetHeight());  delete pDC;   */ // /*  //第二种,铺满控件  Image image(_T("1.png")); //载入指定路径的图像文件  CWnd* pwnd = GetDlgItem(IDC_STATIC_PIC);//IDC_PIC 为图像控件的 ID  CDC* dc = pwnd->GetDC(); //获取图像控件的设备上下文  CRect rect;  pwnd->GetClientRect(&rect); //获取客户区域的信息  Graphics graph(dc->GetSafeHdc());  graph.DrawImage(&image, 0, 0, rect.Width(), rect.Height()); //在指定图像控件的区域中绘制图像  ReleaseDC(dc); //释放资源   */ ///  /*方法二   CBrush m_brBk;   CPaintDC dc(this);   CBitmap bitmap;   bitmap.LoadBitmap(IDB_BITMAP1);//这个IDB_BITMAP1要自己添加;   m_brBk.CreatePatternBrush(&bitmap);   CBrush* pOldBrush= dc.SelectObject(&m_brBk);   dc.Rectangle(0, 0, 200, 200);// 这些参数可以调整图片添加位置和大小 dc.SelectObject(pOldBrush);     */  /*方法三   CPaintDC dc(this);      CBitmap m_bmpBK;      m_bmpBK.LoadBitmap(IDB_BITMAP1);      CRect rect;      GetClientRect(&rect);//获得目标尺寸即窗口客户区的坐标       BITMAP bitMap;//位图结构体       m_bmpBK.GetBitmap(&bitMap);//获得原图片尺寸        CDC dcMem; //目标DC       dcMem.CreateCompatibleDC(&dc); //创建与dc兼容的内存DC       dcMem.SelectObject(&m_bmpBK);//将位图对象m_bmpBK选入内存DC       dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &dcMem, 0, 0, bitMap.bmWidth, bitMap.bmHeight, SRCCOPY);   */  /*方法四    HANDLE m_hBmp;      CPaintDC dc(this); // 用于绘制的设备上下文      m_hBmp = LoadImage(NULL, _T("Demo.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);      CBitmap bmp;//定义位图对象      bmp.Attach(m_hBmp);//将位图关联到位图句柄      CDC memDC;//定义一个设备上下文      memDC.CreateCompatibleDC(&dc);//创建兼容性的设备上下文      memDC.SelectObject(&bmp);//选中位图对象      BITMAP BitInfo;          //定义位图结构      bmp.GetBitmap(&BitInfo);//获取位图信息                                //获取位图信息      int x = BitInfo.bmWidth;                                //获取位图宽度      int y = BitInfo.bmHeight;                               //获取位图高度      dc.BitBlt(0, 0, x, y, &memDC, 0, 0, SRCCOPY);//绘制位图      bmp.Detach();//分离位图句柄      memDC.DeleteDC();//释放设备上下文      bmp.DeleteObject();//释放位图对象    */
转载请注明原文地址: https://www.6miu.com/read-79056.html

最新回复(0)