很简陋的一共桌面画图工具。
在桌面画图主要需要用到GetDC这个API,该函数检索一指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄,以后可以在GDI函数中使用该句柄来在设备上下文环境中绘图。
通过该函数是为了获取桌面的绘图图面。然后用钩子勾住鼠标全局事件,进行画线。效果很差,其他Paint消息会将自己画的线重绘掉。
看了一些方案说是需要创建一共全屏窗体,然后重绘桌面背景到窗体。再窗体下方响应鼠标事件。难度较大,后续会尝试下。
效果如下:
主要代码如下:
class DeskTopDraw
{
private static DeskTopDraw dtd = null;
private static readonly object locker = new object();
public static DeskTopDraw GetInstance()
{
lock (locker)
{
if (dtd == null)
dtd = new DeskTopDraw();
}
return dtd;
}
/// <summary>
/// 该函数检索一指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄,
/// 以后可以在GDI函数中使用该句柄来在设备上下文环境中绘图。
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("User32.dll")]
private extern static IntPtr GetDC(System.IntPtr hWnd);
/// <summary>
/// 画笔
/// </summary>
public Pen p = new Pen(Brushes.Red, 5);
Point start = new Point();
Point end = new Point();
MouseHook mouseHook = new MouseHook();
private DeskTopDraw()
{ }
public bool Init()
{
//设置笔的属性,避免出现“毛刺”
p.StartCap = LineCap.Round;
p.EndCap = LineCap.Round;
p.LineJoin = LineJoin.Round;
mouseHook.MouseMove += new MouseEventHandler(mouseHook_MouseMove);
mouseHook.MouseDown += new MouseEventHandler(mouseHook_MouseDown);
mouseHook.MouseUp += new MouseEventHandler(mouseHook_MouseUp);
mouseHook.Start();
return mouseHook.IsStarted;
}
public void Uinit()
{
mouseHook.Stop();
}
/// <summary>
/// 是否开始绘制
/// </summary>
bool isDraw = false;
List<Point> ls = new List<Point>();
void mouseHook_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//鼠标左键点下 则开始绘制
isDraw = true;
start = e.Location;//记录开始位置
}
}
void mouseHook_MouseMove(object sender, MouseEventArgs e)
{
if (isDraw)
{
end = e.Location;//记录结束位置
IntPtr DesktopHandle = GetDC(IntPtr.Zero);//获取桌面上下文句柄
Graphics g = System.Drawing.Graphics.FromHdc(DesktopHandle);//创建画板
g.SmoothingMode = SmoothingMode.AntiAlias;
g.DrawLine(p, start, end);//画线
start = end;//将结束位置再次作为开始位置
g.ReleaseHdc(DesktopHandle);//释放上下文
g.Dispose();
}
}
void mouseHook_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDraw = false;
}
}
}
窗体代码如下:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
DeskTopDraw dt = DeskTopDraw.GetInstance();
if (!dt.Init())
MessageBox.Show("初始化失败");
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
//不释放也可以,其内部绑定了Application_ApplicationExit事件
DeskTopDraw dt = DeskTopDraw.GetInstance();
dt.Uinit();
}
private void button2_Click(object sender, EventArgs e)
{
DeskTopDraw dt = DeskTopDraw.GetInstance();
dt.Uinit();
}
}
钩子类请参考
http://blog.csdn.net/q317379184/article/details/47979309