在计算机屏幕上画图

类别:.NET开发 点击:0 评论:0 推荐:

在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();
  }

本文地址:http://com.8s8s.com/it/it42472.htm