程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> C# 調用SetROP2實現橡皮線效果

C# 調用SetROP2實現橡皮線效果

編輯:.NET實例教程
  郭勝濤 [email protected]

 DotNet Framework的GDI+較GDI添加了新的功能並對現有的功能進行了優化,
但是Graphics類中沒有提供實現類似GDI中SetROP2函數來更改繪圖模式的功能。
在計算機圖形應用程序開發過程中經常用到反色模式來實現用戶交互活動線,
我們可以在.Net 開發環境調用非托管的Win32 API 來實現上述的功能。

   先來看實例代碼:



using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace Win32APIDraw
...{
    /**//// <summary>
    /// 封裝交互線效果的類
    /// </summary>
    public class Win32XORPenDrawer : IDisposable
    ...{
        聲明Win32 api#region 聲明Win32 api
        struct POINTAPI
        ...{
            public int x;
      public int y;
        }   
        
        [DllImport("user32.dll")]
        private static extern IntPtr GetDC(IntPtr hwnd);
        [DllImport("user32.dll")]
        private static extern IntPtr ReleaseDC(IntPtr hwnd, IntPtr hdc);

        [DllImport("gdi32.dll")]
        private static extern bool MoveToEx(IntPtr hDC,
                          IntPtr x,
                          IntPtr y,
                          ref POINTAPI lpPoint);

        [DllImport("gdi32.dll")]
        private static extern IntPtr LineTo(IntPtr hdc, IntPtr x, IntPtr y);
        [DllImport("gdi32.dll")]
        private static extern IntPtr SetROP2(IntPtr hdc, IntPtr fnDrawMode);

        #endregion

        構造函數#region 構造函數
        /**//// <summary>
        /// 傳入創建DC的句柄和繪圖模式
        /// </summary>
   /// <param name="hWnd"></param>
        /// <param name="drawMode"></param>
        public Win32XORPenDrawer(int hWnd, int drawMode)
        ...{
            //GetDC by hwnd
            this.hWnd = hWnd;
            IntPtr res = GetDC(new IntPtr(hWnd));
            hDc = res.ToInt32();
            SetROP2(res, new IntPtr(drawMode));
        }


        ~Win32XORPenDrawer()
        ...{
            Dispose(false);
        }

        #endregion

        私有成員#region 私有成員
        private int hDc;

        private int hWnd;       

        private&nbsp;bool disposed = false;

        private void Dispose(bool disposing)
        ...{
            if (!this.disposed)
            ...{
                //ReleaseDC
                ReleaseDC(new IntPtr(hWnd), new IntPtr(hDc));
            }
            disposed = true;
        }
        #endregion

        公共接口#region 公共接口
        IDisposable 成員#region IDisposable 成員

        public void Dispose()
    ...{
            Dispose(true);
        }

        #endregion

        /**//// <summary>
        /// 從x1, y1向x2, y2畫線
        /// </summary>
        /// <param name="x1"></param>
        /// <param name="y1"></param>
        /// <param name="x2"></param>
        /// <param name="y2"></param>
        public void DrawLine(int x1, int y1, int x2, int y2)
        ...{
            POINTAPI lpOld = new POINTAPI();
            MoveToEx(new IntPtr(hDc), new IntPtr(x1), new IntPtr(y1), ref lpOld);
            LineTo(new IntPtr(hDc), new IntPtr(x2), new IntPtr(y2));
        }

        public void MoveTo(int x, int y)
     ...{
            POINTAPI lpOld = new POINTAPI();
            MoveToEx(new IntPtr(hDc), new IntPtr(x), new IntPtr(y), ref lpOld);
        }

        public void LineTo(int x, int y)
        ...{
            LineTo(new IntPtr(hDc), new IntPtr(x), new IntPtr(y));
        }
        #endregion
    }
}

 代碼分析:
  1 首先聲明用到的Win32 API 函數.
  主要用到GetDC, ReleaseDC, SetROP2, LineTo, MoveToEx幾個函數,如果需要擴充其他交互效果
 (如畫弧)還要增加相應的API函數聲明。
  我們使用SetROP2函數來設置畫筆的反色效果。

  2 這個類的構造函數中傳入圖形設備的句柄和繪圖模式,可以是窗體或打印機, 也可以是承載其他畫圖效果控件
的。當繪圖模式參數傳入值是6時,就是反色效果。因為在構造函數中我們調用了SetROP2函數。
  這和在VC++中的實現方法是一致的。
 
  3 聲明相應的畫線方法,調用Win32API畫線。

  最後要注意的是,在c#環境下必須注意釋放通過win32API中創建的非托管資源,因此,我們使這個類實現
IDisposable接口。
       

運行效果:

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved