国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
基于對話框的簡單雙緩沖繪圖框架
作者:朱金燦
來源:http://blog.csdn.net/clever101/
 

     基于文檔視圖結構程序的雙緩沖繪圖框架比較多,那么如何在對話框上繪圖呢?以前通常的做法是拖一個靜態(tài)文本控件或其它控件當作繪圖區(qū)域或者在這個區(qū)域上創(chuàng)建一個視圖出來??戳宋④浀囊粋€示例程序DrawCli(一個繪圖的單文檔程序),產生了一些靈感,決心把它移植到對話框繪圖上,摸索了一下,搞了一個基于對話框的簡單雙緩沖繪圖框架。
 

     具體代碼如下,對話框頭文件代碼:
 

     view plaincopy to clipboardprint?
#include <vector>  
//@brief 直線結構體  
struct stLine  
{  
    stLine(CPoint &Begin,CPoint &End)  
    {  
        m_Begin = Begin;  
        m_End = End;  
    }  
    //@brief 起點  
    CPoint m_Begin;  
    //@brief 終點  
    CPoint m_End;  
};  
class CDoubleBufDrawDlg : public CDialog  
{  
    DECLARE_DYNAMIC(CDoubleBufDrawDlg)  
public:  
    CDoubleBufDrawDlg(CWnd* pParent = NULL);   // 標準構造函數  
    virtual ~CDoubleBufDrawDlg();  
// 對話框數據  
    enum { IDD = IDD_DIALOG_GDIPLUS };  
protected:  
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持  
    DECLARE_MESSAGE_MAP()  
public:  
    virtual BOOL OnInitDialog();  
    afx_msg void OnBnClickedDrawPoint();  
    afx_msg void OnBnClickedDrawLine();  
    afx_msg void OnSize(UINT nType, int cx, int cy);  
    void AdjustControls();  
    afx_msg void OnPaint();  
protected:  
    //   
    void InitDrawPara();  
protected:  
    //@brief 上一個點  
    CPoint m_PrePt;  
    //@brief 鼠標按下點  
    CPoint m_DownPt;  
    //@brief 直線結構體數組  
    std::vector<stLine> m_Lines;  
public:  
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);  
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);  
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);  
};  
#include <vector>
//@brief 直線結構體
struct stLine
{
 stLine(CPoint &Begin,CPoint &End)
 {
        m_Begin = Begin;
  m_End = End;
 }
 //@brief 起點
 CPoint m_Begin;
 //@brief 終點
    CPoint m_End;
};
class CDoubleBufDrawDlg : public CDialog
{
 DECLARE_DYNAMIC(CDoubleBufDrawDlg)
public:
 CDoubleBufDrawDlg(CWnd* pParent = NULL);   // 標準構造函數
 virtual ~CDoubleBufDrawDlg();
// 對話框數據
 enum { IDD = IDD_DIALOG_GDIPLUS };
protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
 DECLARE_MESSAGE_MAP()
public:
 virtual BOOL OnInitDialog();
 afx_msg void OnBnClickedDrawPoint();
 afx_msg void OnBnClickedDrawLine();
 afx_msg void OnSize(UINT nType, int cx, int cy);
 void AdjustControls();
 afx_msg void OnPaint();
protected:
 //
    void InitDrawPara();
protected:
 //@brief 上一個點
 CPoint m_PrePt;
 //@brief 鼠標按下點
 CPoint m_DownPt;
 //@brief 直線結構體數組
 std::vector<stLine> m_Lines;
public:
 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
 afx_msg void OnMouseMove(UINT nFlags, CPoint point);
 afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
}; 
 
 
 
    Cpp文件源碼(這里只列出主要函數):
 

    view plaincopy to clipboardprint?
//@brief 初始化繪圖參數  
void CDoubleBufDrawDlg::InitDrawPara()  
{  
    m_PrePt = CPoint(-1,-1);  
    m_DownPt = CPoint(-1,-1);  
}  
CDoubleBufDrawDlg::CDoubleBufDrawDlg(CWnd* pParent /*=NULL*/)  
: CDialog(CDoubleBufDrawDlg::IDD, pParent)  
{  
    InitDrawPara();  
}  
void CDoubleBufDrawDlg::OnLButtonDown(UINT nFlags, CPoint point)  
{  
    // TODO: 在此添加消息處理程序代碼和/或調用默認值  
    // 記錄鼠標按下點  
    m_DownPt = point;  
    CDialog::OnLButtonDown(nFlags, point);  
}  
void CDoubleBufDrawDlg::OnMouseMove(UINT nFlags, CPoint point)  
{  
    // TODO: 在此添加消息處理程序代碼和/或調用默認值  
    // 假如在移動鼠標的同時按下左鍵  
    if (MK_LBUTTON&nFlags)  
    {  
        CDC *pDC = GetDC();  
        pDC->SetROP2(R2_NOTXORPEN);  
    // 將繪圖區(qū)域限制在對話框的客戶區(qū)上面的/4區(qū)域  
CRect rtDraw(rtClient.top,rtClient.left,rtClient.Width(),3*(rtClient.Height()/4));  
    CRgn DrawRgn;  
    DrawRgn.CreateRectRgn(rtDraw.left,rtDraw.top,rtDraw.right,rtDraw.bottom);  
    pDC->SelectClipRgn(&DrawRgn);  
        if (m_PrePt.x!=-1)  
        {  
            // 擦除上一條線  
            pDC->MoveTo(m_DownPt);  
            pDC->LineTo(m_PrePt);  
        }  
        // 畫線  
        pDC->MoveTo(m_DownPt);  
        pDC->LineTo(point);  
        ReleaseDC(pDC);  
        m_PrePt = point;  
    }  
    CDialog::OnMouseMove(nFlags, point);  
}  
void CDoubleBufDrawDlg::OnLButtonUp(UINT nFlags, CPoint point)  
{  
    // TODO: 在此添加消息處理程序代碼和/或調用默認值  
    // 將繪制的直線加入到直線數組  
    m_Lines.push_back(stLine(m_DownPt,point));  
    // 初始化繪圖參數  
    InitDrawPara();  
    CDialog::OnLButtonUp(nFlags, point);  
}  
void CDoubleBufDrawDlg::OnPaint()  
{  
    // 最小時繪制菜單圖標,因為我是在一個單文檔程序中彈出該對話框的,故不需要繪制圖標  
    // 如果是基于對話框的程序則需要繪制圖標  
    if (IsIconic())  
    {  
        CPaintDC dc(this); // device context for painting  
        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);  
        // Center icon in client rectangle  
        //int cxIcon = GetSystemMetrics(SM_CXICON);  
        //int cyIcon = GetSystemMetrics(SM_CYICON);  
        //CRect rect;  
        //GetClientRect(&rect);  
        //int x = (rect.Width() - cxIcon + 1) / 2;  
        //int y = (rect.Height() - cyIcon + 1) / 2;  
        //// Draw the icon  
        //dc.DrawIcon(x, y, m_hIcon);  
    }  
    else 
    {  
        CPaintDC dc(this);  
        // 定義一個兼容DC  
        CDC CompaDC;  
        // 初始化繪圖DC指針  
        CDC* pDrawDC = &dc;  
        CBitmap bitmap;  
        CBitmap* pOldBitmap = 0;  
        CRect rtClient;  
        GetClientRect(&rtClient);  
        // 將對話框的客戶區(qū)上面的/4區(qū)域設為繪圖區(qū)域  
        CRect rtDraw(rtClient.top,rtClient.left,rtClient.Width(),3*(rtClient.Height()/4));  
        // 假如不是打印機DC  
        if (!dc.IsPrinting())  
        {  
            // 創(chuàng)建兼容DC,創(chuàng)建兼容位圖,將兼容位圖選進兼容DC  
            if (CompaDC.CreateCompatibleDC(&dc))  
            {  
                if (bitmap.CreateCompatibleBitmap(&dc,rtDraw.Width(),rtDraw.Height()))  
                {  
                    pDrawDC = &CompaDC;  
                    pOldBitmap = CompaDC.SelectObject(&bitmap);  
                }  
            }  
        }  
        // 定義一個白色畫刷,將背景色設為白色  
        CBrush brush;  
        if (!brush.CreateSolidBrush(RGB(255,255,255)))  
            return;  
        brush.UnrealizeObject();  
        pDrawDC->FillRect(rtDraw,&brush);  
        // 繪制直線  
        for (size_t i = 0;i<m_Lines.size();i++)  
        {  
            pDrawDC->MoveTo(m_Lines[i].m_Begin);  
            pDrawDC->LineTo(m_Lines[i].m_End);  
        }  
        // 使用GDI+繪制一個線性漸變畫刷  
        Gdiplus::Graphics graphics(pDrawDC->m_hDC);  
        LinearGradientBrush linGrBrush(Point(100,0),Point(100,100),Color(255,255,0,0),Color(255,0,255,0));  
        Color colors[] = {  
            Color(255, 255, 0, 0),   // red  
            Color(255, 255, 255, 0), //yellow  
            Color(255, 0, 0, 255),   // blue  
            Color(255, 0, 255, 0)};  // green  
            REAL positions[] = {  
                0.0f,     
                0.33f,     
                0.66f,  
                1.0f};    
                linGrBrush.SetInterpolationColors(colors, positions,4);  
                // 填充指定區(qū)域矩形  
                graphics.FillRectangle(&linGrBrush,100,0,100,100);  
                graphics.ReleaseHDC(pDrawDC->m_hDC);  
                if (pDrawDC != &dc)  
                {  
                    // 將繪圖DC貼到真正的設備DC上  
                    dc.BitBlt(rtDraw.left,rtDraw.top,rtDraw.Width(),rtDraw.Height(),&CompaDC, 0, 0, SRCCOPY);  
                    CompaDC.SelectObject(pOldBitmap);  
                }  
    }  
}  
//@brief 初始化繪圖參數
void CDoubleBufDrawDlg::InitDrawPara()
{
 m_PrePt = CPoint(-1,-1);
 m_DownPt = CPoint(-1,-1);
}
CDoubleBufDrawDlg::CDoubleBufDrawDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDoubleBufDrawDlg::IDD, pParent)
{
 InitDrawPara();
}
void CDoubleBufDrawDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
 // TODO: 在此添加消息處理程序代碼和/或調用默認值
 // 記錄鼠標按下點
 m_DownPt = point;
 CDialog::OnLButtonDown(nFlags, point);
}
void CDoubleBufDrawDlg::OnMouseMove(UINT nFlags, CPoint point)
{
 // TODO: 在此添加消息處理程序代碼和/或調用默認值
 // 假如在移動鼠標的同時按下左鍵
 if (MK_LBUTTON&nFlags)
 {
  CDC *pDC = GetDC();
  pDC->SetROP2(R2_NOTXORPEN);
    // 將繪圖區(qū)域限制在對話框的客戶區(qū)上面的/4區(qū)域
CRect rtDraw(rtClient.top,rtClient.left,rtClient.Width(),3*(rtClient.Height()/4));
 CRgn DrawRgn;
 DrawRgn.CreateRectRgn(rtDraw.left,rtDraw.top,rtDraw.right,rtDraw.bottom);
 pDC->SelectClipRgn(&DrawRgn);
  if (m_PrePt.x!=-1)
  {
   // 擦除上一條線
   pDC->MoveTo(m_DownPt);
   pDC->LineTo(m_PrePt);
  }
  // 畫線
  pDC->MoveTo(m_DownPt);
  pDC->LineTo(point);
  ReleaseDC(pDC);
  m_PrePt = point;
 }
 CDialog::OnMouseMove(nFlags, point);
}
void CDoubleBufDrawDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
 // TODO: 在此添加消息處理程序代碼和/或調用默認值
 // 將繪制的直線加入到直線數組
 m_Lines.push_back(stLine(m_DownPt,point));
 // 初始化繪圖參數
 InitDrawPara();
 CDialog::OnLButtonUp(nFlags, point);
}
void CDoubleBufDrawDlg::OnPaint()
{
 // 最小時繪制菜單圖標,因為我是在一個單文檔程序中彈出該對話框的,故不需要繪制圖標
 // 如果是基于對話框的程序則需要繪制圖標
 if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting
  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  // Center icon in client rectangle
  //int cxIcon = GetSystemMetrics(SM_CXICON);
  //int cyIcon = GetSystemMetrics(SM_CYICON);
  //CRect rect;
  //GetClientRect(&rect);
  //int x = (rect.Width() - cxIcon + 1) / 2;
  //int y = (rect.Height() - cyIcon + 1) / 2;
  //// Draw the icon
  //dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CPaintDC dc(this);
  // 定義一個兼容DC
  CDC CompaDC;
  // 初始化繪圖DC指針
  CDC* pDrawDC = &dc;
  CBitmap bitmap;
  CBitmap* pOldBitmap = 0;
  CRect rtClient;
  GetClientRect(&rtClient);
  // 將對話框的客戶區(qū)上面的/4區(qū)域設為繪圖區(qū)域
  CRect rtDraw(rtClient.top,rtClient.left,rtClient.Width(),3*(rtClient.Height()/4));
  // 假如不是打印機DC
  if (!dc.IsPrinting())
  {
   // 創(chuàng)建兼容DC,創(chuàng)建兼容位圖,將兼容位圖選進兼容DC
   if (CompaDC.CreateCompatibleDC(&dc))
   {
    if (bitmap.CreateCompatibleBitmap(&dc,rtDraw.Width(),rtDraw.Height()))
    {
     pDrawDC = &CompaDC;
     pOldBitmap = CompaDC.SelectObject(&bitmap);
    }
   }
  }
  // 定義一個白色畫刷,將背景色設為白色
  CBrush brush;
  if (!brush.CreateSolidBrush(RGB(255,255,255)))
   return;
  brush.UnrealizeObject();
  pDrawDC->FillRect(rtDraw,&brush);
  // 繪制直線
  for (size_t i = 0;i<m_Lines.size();i++)
  {
   pDrawDC->MoveTo(m_Lines[i].m_Begin);
   pDrawDC->LineTo(m_Lines[i].m_End);
  }
  // 使用GDI+繪制一個線性漸變畫刷
  Gdiplus::Graphics graphics(pDrawDC->m_hDC);
  LinearGradientBrush linGrBrush(Point(100,0),Point(100,100),Color(255,255,0,0),Color(255,0,255,0));
  Color colors[] = {
   Color(255, 255, 0, 0),   // red
   Color(255, 255, 255, 0), //yellow
   Color(255, 0, 0, 255),   // blue
   Color(255, 0, 255, 0)};  // green
   REAL positions[] = {
    0.0f,  
    0.33f,  
    0.66f,
    1.0f}; 
    linGrBrush.SetInterpolationColors(colors, positions,4);
    // 填充指定區(qū)域矩形
    graphics.FillRectangle(&linGrBrush,100,0,100,100);
    graphics.ReleaseHDC(pDrawDC->m_hDC);
    if (pDrawDC != &dc)
    {
     // 將繪圖DC貼到真正的設備DC上
     dc.BitBlt(rtDraw.left,rtDraw.top,rtDraw.Width(),rtDraw.Height(),&CompaDC, 0, 0, SRCCOPY);
     CompaDC.SelectObject(pOldBitmap);
    }
 }
 

    效果圖如下,其中上面的白色區(qū)域為繪圖區(qū)域:
 

 
 
 
 
    現在你怎么改變對話框的大小繪圖區(qū)域也不會產生非雙緩沖繪圖那種閃爍。
 
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/clever101/archive/2010/12/13/6073791.aspx
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/clever101/archive/2010/12/13/6073791.aspx
本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
windows編程——背景圖片和透明特效的使用3
CSplitterWnd技巧
靜態(tài)文本 鏈接控件 背景透明的靜態(tài)文本
轉 使用CSplitterWnd分割窗口
VC超級鏈接的設計與實現
VC程序中樹型控件節(jié)點拖動的完美實現
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服