在Window上有一些軟體可以在電腦螢幕上畫圖,這是怎麼做的呢?我查了一些相關的資料,發現,實際上在Window系統上跟本就不可能直接向電腦的顯示器螢幕輸出自己所繪的圖,那些在DOS時代用系統中斷的做法在Window上不行了!!!那麼那些軟體是怎麼畫的呢,實際上有很多軟體採用了我在這裡的一個做法.如果有興趣可以試試喲:)
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace BitBltScreen
{
/// <summary>
/// ShowScreen 的摘要說明。
/// </summary>
public class ShowScreen : System.Windows.Forms.Form
{
private const int SRCCOPY = 0xCC0020;
[System.Runtime.InteropServices.DllImportAttribute("User32.dll")]
private static extern IntPtr GetDesktopWindow();
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern long BitBlt (IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
[System.Runtime.InteropServices.DllImportAttribute("User32.dll")]
private static extern IntPtr GetDC(IntPtr hWnd);
[System.Runtime.InteropServices.DllImportAttribute("User32.dll")]
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
private Bitmap m_Image;//臨時用的位元影像
private Point m_SPoint;//畫線的起始點
private Point m_EPoint;//畫線的結束點
private Graphics m_Graphics;//畫線用的繪圖物件
private Color m_LineColor;
private System.Windows.Forms.ContextMenu contextMenu1;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem menuItem2;
/// <summary>
/// 必需的設計器變數。
/// </summary>
private System.ComponentModel.Container components = null;
public ShowScreen()
{
//
// Windows 表單設計器支援所必需的
//
InitializeComponent();
this.Location = new Point(0,0);
this.Size = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
m_LineColor = Color.FromArgb(255,0,0);//初始化的紅色
}
#region Windows 表單設計器產生的程式碼
/// <summary>
/// 清理所有正在使用的資源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
/// <summary>
/// 設計器支援所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內容。
/// </summary>
private void InitializeComponent()
{
this.contextMenu1 = new System.Windows.Forms.ContextMenu();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
//
// contextMenu1
//
this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem1,
this.menuItem2});
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.Text = "CopyScreen(&C)";
this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
//
// menuItem2
//
this.menuItem2.Index = 1;
this.menuItem2.Text = "Exit(&E)";
this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
//
// ShowScreen
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(292, 270);
this.ContextMenu = this.contextMenu1;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "ShowScreen";
}
#endregion
private void menuItem1_Click(object sender, System.EventArgs e)
{
LoadScreen();
}
private void menuItem2_Click(object sender, System.EventArgs e)
{
this.Close();
}
public void LoadScreen()
{
IntPtr desk = GetDesktopWindow();//得到電腦的最上層視窗
IntPtr screenDC = GetDC(desk);//得到視窗的畫圖裝置控制代碼
//產生一個和螢幕大小一樣的位元影像
m_Image = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(m_Image);//從這個位元影像建立一個畫圖對象
IntPtr theDC = g.GetHdc();//得到這位元影像的畫圖對象裝置控制代碼
//把最上層視窗的拷貝放到位元影像裡面,以備重畫時使用
long tmpLong = BitBlt(theDC, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, screenDC, 0, 0, SRCCOPY);
g.ReleaseHdc(theDC);//刪除位元圖畫圖裝置控制代碼
ReleaseDC(this.Handle, screenDC);//刪除最上層視窗畫圖裝置控制代碼
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint (e);
//視窗重畫時繪製位元影像
if (m_Image != null)
{
e.Graphics.DrawImage(m_Image,0,0);
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown (e);
//滑鼠按下的時候記下畫線起點
m_SPoint = new Point(e.X, e.Y);
//建立畫圖用的對象
if (m_Graphics == null)
{
m_Graphics = this.CreateGraphics();
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove (e);
if (e.Button == MouseButtons.Left)
{
//如果滑鼠左鍵按下就畫圖,這裡是一條紅色的直線
m_Graphics.DrawImage(m_Image,0,0);//這裡這麼調用就是為了清除原來的線,我不知道怎麼做更好,所以...
Point tmpPoint = new Point(e.X, e.Y);
m_Graphics.DrawLine(new Pen(m_LineColor), m_SPoint, tmpPoint);//畫一條新的線.
m_EPoint = tmpPoint;//記下新的點
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp (e);
//在滑鼠鍵抬起時到到位元影像上記下來
Graphics tmpGraphics = Graphics.FromImage(m_Image);
tmpGraphics.DrawLine(new Pen(m_LineColor), m_SPoint, m_EPoint);
}
}
}
這時就可以把代碼複製下來試試嘍,哈~哈~
不過在使用時,要先把螢幕取下來喲,要不就沒有效果了:)
private void button1_Click(object sender, System.EventArgs e)
{
ShowScreen ss = new ShowScreen();
ss.LoadScreen();
ss.Show();
}