<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    基于對話框的簡單雙緩沖繪圖框架

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

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


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


        

    [cpp] view plaincopy
    1. #include <vector>  
    2. //@brief 直線結構體  
    3. struct stLine  
    4. {  
    5.     stLine(CPoint &Begin,CPoint &End)  
    6.     {  
    7.         m_Begin = Begin;  
    8.         m_End = End;  
    9.     }  
    10.     //@brief 起點  
    11.     CPoint m_Begin;  
    12.     //@brief 終點  
    13.     CPoint m_End;  
    14. };  
    15. class CDoubleBufDrawDlg : public CDialog  
    16. {  
    17.     DECLARE_DYNAMIC(CDoubleBufDrawDlg)  
    18. public:  
    19.     CDoubleBufDrawDlg(CWnd* pParent = NULL);   // 標準構造函數  
    20.     virtual ~CDoubleBufDrawDlg();  
    21. // 對話框數據  
    22.     enum { IDD = IDD_DIALOG_GDIPLUS };  
    23. protected:  
    24.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持  
    25.     DECLARE_MESSAGE_MAP()  
    26. public:  
    27.     virtual BOOL OnInitDialog();  
    28.     afx_msg void OnBnClickedDrawPoint();  
    29.     afx_msg void OnBnClickedDrawLine();  
    30.     afx_msg void OnSize(UINT nType, int cx, int cy);  
    31.     void AdjustControls();  
    32.     afx_msg void OnPaint();  
    33. protected:  
    34.     //   
    35.     void InitDrawPara();  
    36. protected:  
    37.     //@brief 上一個點  
    38.     CPoint m_PrePt;  
    39.     //@brief 鼠標按下點  
    40.     CPoint m_DownPt;  
    41.     //@brief 直線結構體數組  
    42.     std::vector<stLine> m_Lines;  
    43. public:  
    44.     afx_msg void OnLButtonDown(UINT nFlags, CPoint point);  
    45.     afx_msg void OnMouseMove(UINT nFlags, CPoint point);  
    46.     afx_msg void OnLButtonUp(UINT nFlags, CPoint point);  
    47. };   

     



        Cpp文件源碼(這里只列出主要函數):


       

    [cpp] view plaincopy
    1. //@brief 初始化繪圖參數  
    2. void CDoubleBufDrawDlg::InitDrawPara()  
    3. {  
    4.     m_PrePt = CPoint(-1,-1);  
    5.     m_DownPt = CPoint(-1,-1);  
    6. }  
    7. CDoubleBufDrawDlg::CDoubleBufDrawDlg(CWnd* pParent /*=NULL*/)  
    8. : CDialog(CDoubleBufDrawDlg::IDD, pParent)  
    9. {  
    10.     InitDrawPara();  
    11. }  
    12. void CDoubleBufDrawDlg::OnLButtonDown(UINT nFlags, CPoint point)  
    13. {  
    14.     // TODO: 在此添加消息處理程序代碼和/或調用默認值  
    15.     // 記錄鼠標按下點  
    16.     m_DownPt = point;  
    17.     CDialog::OnLButtonDown(nFlags, point);  
    18. }  
    19. void CDoubleBufDrawDlg::OnMouseMove(UINT nFlags, CPoint point)  
    20. {  
    21.     // TODO: 在此添加消息處理程序代碼和/或調用默認值  
    22.     // 假如在移動鼠標的同時按下左鍵  
    23.     if (MK_LBUTTON&nFlags)  
    24.     {  
    25.         CDC *pDC = GetDC();  
    26.         pDC->SetROP2(R2_NOTXORPEN);  
    27.     // 將繪圖區域限制在對話框的客戶區上面的/4區域  
    28. CRect rtDraw(rtClient.top,rtClient.left,rtClient.Width(),3*(rtClient.Height()/4));  
    29.     CRgn DrawRgn;  
    30.     DrawRgn.CreateRectRgn(rtDraw.left,rtDraw.top,rtDraw.right,rtDraw.bottom);  
    31.     pDC->SelectClipRgn(&DrawRgn);  
    32.         if (m_PrePt.x!=-1)  
    33.         {  
    34.             // 擦除上一條線  
    35.             pDC->MoveTo(m_DownPt);  
    36.             pDC->LineTo(m_PrePt);  
    37.         }  
    38.         // 畫線  
    39.         pDC->MoveTo(m_DownPt);  
    40.         pDC->LineTo(point);  
    41.         ReleaseDC(pDC);  
    42.         m_PrePt = point;  
    43.     }  
    44.     CDialog::OnMouseMove(nFlags, point);  
    45. }  
    46. void CDoubleBufDrawDlg::OnLButtonUp(UINT nFlags, CPoint point)  
    47. {  
    48.     // TODO: 在此添加消息處理程序代碼和/或調用默認值  
    49.     // 將繪制的直線加入到直線數組  
    50.     m_Lines.push_back(stLine(m_DownPt,point));  
    51.     // 初始化繪圖參數  
    52.     InitDrawPara();  
    53.     CDialog::OnLButtonUp(nFlags, point);  
    54. }  
    55. void CDoubleBufDrawDlg::OnPaint()  
    56. {  
    57.     // 最小時繪制菜單圖標,因為我是在一個單文檔程序中彈出該對話框的,故不需要繪制圖標  
    58.     // 如果是基于對話框的程序則需要繪制圖標  
    59.     if (IsIconic())  
    60.     {  
    61.         CPaintDC dc(this); // device context for painting  
    62.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);  
    63.         // Center icon in client rectangle  
    64.         //int cxIcon = GetSystemMetrics(SM_CXICON);  
    65.         //int cyIcon = GetSystemMetrics(SM_CYICON);  
    66.         //CRect rect;  
    67.         //GetClientRect(&rect);  
    68.         //int x = (rect.Width() - cxIcon + 1) / 2;  
    69.         //int y = (rect.Height() - cyIcon + 1) / 2;  
    70.         //// Draw the icon  
    71.         //dc.DrawIcon(x, y, m_hIcon);  
    72.     }  
    73.     else  
    74.     {  
    75.         CPaintDC dc(this);  
    76.         // 定義一個兼容DC  
    77.         CDC CompaDC;  
    78.         // 初始化繪圖DC指針  
    79.         CDC* pDrawDC = &dc;  
    80.         CBitmap bitmap;  
    81.         CBitmap* pOldBitmap = 0;  
    82.         CRect rtClient;  
    83.         GetClientRect(&rtClient);  
    84.         // 將對話框的客戶區上面的/4區域設為繪圖區域  
    85.         CRect rtDraw(rtClient.top,rtClient.left,rtClient.Width(),3*(rtClient.Height()/4));  
    86.         // 假如不是打印機DC  
    87.         if (!dc.IsPrinting())  
    88.         {  
    89.             // 創建兼容DC,創建兼容位圖,將兼容位圖選進兼容DC  
    90.             if (CompaDC.CreateCompatibleDC(&dc))  
    91.             {  
    92.                 if (bitmap.CreateCompatibleBitmap(&dc,rtDraw.Width(),rtDraw.Height()))  
    93.                 {  
    94.                     pDrawDC = &CompaDC;  
    95.                     pOldBitmap = CompaDC.SelectObject(&bitmap);  
    96.                 }  
    97.             }  
    98.         }  
    99.         // 定義一個白色畫刷,將背景色設為白色  
    100.         CBrush brush;  
    101.         if (!brush.CreateSolidBrush(RGB(255,255,255)))  
    102.             return;  
    103.         brush.UnrealizeObject();  
    104.         pDrawDC->FillRect(rtDraw,&brush);  
    105.         // 繪制直線  
    106.         for (size_t i = 0;i<m_Lines.size();i++)  
    107.         {  
    108.             pDrawDC->MoveTo(m_Lines[i].m_Begin);  
    109.             pDrawDC->LineTo(m_Lines[i].m_End);  
    110.         }  
    111.         // 使用GDI+繪制一個線性漸變畫刷  
    112.         Gdiplus::Graphics graphics(pDrawDC->m_hDC);  
    113.         LinearGradientBrush linGrBrush(Point(100,0),Point(100,100),Color(255,255,0,0),Color(255,0,255,0));  
    114.         Color colors[] = {  
    115.             Color(255, 255, 0, 0),   // red  
    116.             Color(255, 255, 255, 0), //yellow  
    117.             Color(255, 0, 0, 255),   // blue  
    118.             Color(255, 0, 255, 0)};  // green  
    119.             REAL positions[] = {  
    120.                 0.0f,     
    121.                 0.33f,     
    122.                 0.66f,  
    123.                 1.0f};    
    124.                 linGrBrush.SetInterpolationColors(colors, positions,4);  
    125.                 // 填充指定區域矩形  
    126.                 graphics.FillRectangle(&linGrBrush,100,0,100,100);  
    127.                 graphics.ReleaseHDC(pDrawDC->m_hDC);  
    128.                 if (pDrawDC != &dc)  
    129.                 {  
    130.                     // 將繪圖DC貼到真正的設備DC上  
    131.                     dc.BitBlt(rtDraw.left,rtDraw.top,rtDraw.Width(),rtDraw.Height(),&CompaDC, 0, 0, SRCCOPY);  
    132.                     CompaDC.SelectObject(pOldBitmap);  
    133.                 }  
    134.     }  
    135. }   

     


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


    Dlg Double Buf



        現在你怎么改變對話框的大小繪圖區域也不會產生非雙緩沖繪圖那種閃爍。

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全