C# 自由截图

Joan_liu 2010-04-13 09:35:55
找到一个看上去不错的截图代码
问下这个截图代码的控件是怎么设置的?
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace QinMi
{
#region api
public class API
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SetWindowsHookEx(int hookid, HookProc pfnhook, IntPtr hinst, int threadid);
public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern int GetCurrentThreadId();
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool UnhookWindowsHookEx(IntPtr hhook);
public enum WindowsHookCodes
{
WH_MSGFILTER = (-1),
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}
}
#endregion
#region 矩形截图类
/// <summary>
/// 矩形截图类
/// zgke@Sina.com
/// qq:116149
/// </summary>
public class CopyScreen
{
/// <summary>
/// 截图
/// </summary>
public CopyScreen()
{
m_ScreenForm = API.GetDesktopWindow();
m_HookMessage = new HookMessage(API.WindowsHookCodes.WH_MOUSE_LL, true);
m_HookMessage.GetHook += new HookMessage.GetHookMessage(m_HookMessage_GetHook);
}
private Size ScreenSize { get { return Screen.PrimaryScreen.Bounds.Size; } }
private Point MousePoint { get { return Cursor.Position; } }
/// <summary>
/// 截图
/// </summary>
public Bitmap ScreenImage
{
get
{
Bitmap m_BackBitmap = new Bitmap(ScreenSize.Width, ScreenSize.Height);
Graphics _Graphics = Graphics.FromImage(m_BackBitmap);
_Graphics.CopyFromScreen(new Point(0, 0), new Point(0, 0), ScreenSize);
_Graphics.Dispose();
return m_BackBitmap;
}
}
private HookMessage m_HookMessage;
private IntPtr m_ScreenForm;
private Bitmap m_Image;
public delegate void GetImage(Image p_Image);
/// <summary>
/// 获取屏幕截图
/// </summary>
public event GetImage GetScreenImage;
/// <summary>
/// 钩子事件
/// </summary>
void m_HookMessage_GetHook(int p_Code, IntPtr p_wParam, IntPtr p_lParam, ref bool p_Send)
{
if (m_StarMouse)
{
switch (p_wParam.ToInt32())
{
case 512: //Move
MouseMove();
break;
case 513: //Down
MouseDown();
p_Send = false;
break;
case 514: //Up
MouseUp();
p_Send = false;
break;
default:
m_StarMouse = false;
break;
}
}
}
/// <summary>
/// 根据矩形 如果Width是正直接返回 如果是负会转换成正的矩形 保证大小位置不变
/// </summary>
/// <param name="p_Rectangle">矩形</param>
/// <returns>正矩形</returns>
public static Rectangle GetUprightRectangle(Rectangle p_Rectangle)
{
Rectangle _Rect = p_Rectangle;
if (_Rect.Width < 0)
{
int _X = _Rect.X;
_Rect.X = _Rect.Width + _Rect.X;
_Rect.Width = _X - _Rect.X;
}
if (_Rect.Height < 0)
{
int _Y = _Rect.Y;
_Rect.Y = _Rect.Height + _Rect.Y;
_Rect.Height = _Y - _Rect.Y;
}
return _Rect;
}
private Rectangle m_MouseRectangle = new Rectangle(0, 0, 0, 0);
private bool m_DrawStar = false;
private void MouseDown()
{
m_MouseRectangle.X = MousePoint.X;
m_MouseRectangle.Y = MousePoint.Y;
m_DrawStar = true;
}
private void MouseMove()
{
if (m_DrawStar)
{
ControlPaint.DrawReversibleFrame(m_MouseRectangle, Color.Transparent, FrameStyle.Dashed);
m_MouseRectangle.Width = MousePoint.X - m_MouseRectangle.X;
m_MouseRectangle.Height = MousePoint.Y - m_MouseRectangle.Y;
ControlPaint.DrawReversibleFrame(m_MouseRectangle, Color.White, FrameStyle.Dashed);
}
}
private void MouseUp()
{
ControlPaint.DrawReversibleFrame(m_MouseRectangle, Color.Transparent, FrameStyle.Dashed);
m_DrawStar = false;
m_StarMouse = false;
Rectangle _ScreenRectangle = GetUprightRectangle(m_MouseRectangle);
m_MouseRectangle.X = 0;
m_MouseRectangle.Y = 0;
m_MouseRectangle.Width = 0;
m_MouseRectangle.Height = 0;
if (GetScreenImage != null)
{
if (_ScreenRectangle.Width != 0 && _ScreenRectangle.Height != 0) GetScreenImage(m_Image.Clone
(_ScreenRectangle, m_Image.PixelFormat));
}
}
private bool m_StarMouse = false;
/// <summary>
/// 获取图形
/// </summary>
public void GerScreenFormRectangle()
{
m_Image = ScreenImage;
m_StarMouse = true;
}
/// <summary>
/// 获取图形
/// </summary>
public void GetScreen()
{
if (GetScreenImage != null) GetScreenImage(ScreenImage);
}
}
#endregion
#region 用钩子获取消息
/// <summary>
/// 用钩子获取消息
/// zgke@Sina.com
/// </summary>
public class HookMessage
{
private IntPtr m_HookEx;
/// <summary>
/// 设置自己进程的钩子
/// </summary>
/// <param name="p_HookCodes">钩子类型</param>
public HookMessage(API.WindowsHookCodes p_HookCodes)
{
m_HookEx = API.SetWindowsHookEx((int)p_HookCodes, new API.HookProc(SetHookProc), IntPtr.Zero,
API.GetCurrentThreadId());
}
/// <summary>
/// 设置进程的钩子
/// </summary>
/// <param name="p_HookCodes">钩子类型</param>
/// <param name="p_Zero">全局钩子</param>
public HookMessage(API.WindowsHookCodes p_HookCodes, bool p_Zero)
{
IntPtr _Value = System.Runtime.InteropServices.Marshal.GetHINSTANCE
(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]);
m_HookEx = API.SetWindowsHookEx((int)p_HookCodes, new API.HookProc(SetHookProc), _Value, 0);
}
/// <summary>
/// 关闭钩子
/// </summary>
public void UnHookMessage()
{
if (API.UnhookWindowsHookEx(m_HookEx))
{
m_HookEx = IntPtr.Zero;
}
}
public delegate void GetHookMessage(int p_Code, IntPtr p_wParam, IntPtr p_lParam, ref bool p_Send);
public event GetHookMessage GetHook;
private IntPtr SetHookProc(int p_Code, IntPtr p_wParam, IntPtr p_lParam)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
bool _SendMessage = true;
if (GetHook != null) GetHook(p_Code, p_wParam, p_lParam, ref _SendMessage);
if (!_SendMessage) return new IntPtr(1);
return IntPtr.Zero;
}
}
#endregion
}


上面是一部分 另外还有个分开的一部分
...全文
524 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
hepeng_8 2010-04-14
  • 打赏
  • 举报
回复
好行很难 明白
doubleu2005 2010-04-14
  • 打赏
  • 举报
回复
是啊用到钩子了
昵称不腻 2010-04-14
  • 打赏
  • 举报
回复
mark
deluxbass 2010-04-14
  • 打赏
  • 举报
回复
在命名空间中加入以入类,就可以运行了
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
Joan_liu 2010-04-14
  • 打赏
  • 举报
回复
饿 我想问的是它的界面和文件设置 怎么能让这段代码跑起来= =
xingyuebuyu 2010-04-13
  • 打赏
  • 举报
回复
这个是利用HOOK MOUSE来截图的.
首先创建实例后,然后QinMi.CopyScreen类里的GetScreenImage 事件绑定cs_GetScreenImage方法,这样一旦事件触发,pictureBox1的图片也会更新成最新截取的图片.

2.调用 cs.GerScreenFormRectangle();方法开始进行HOOK MOUSE,监视鼠标的状态变化,
这样当你按下鼠标左键时,就开始准备截图,当左键放开时,截图区域就确定了
shashengduguzhe 2010-04-13
  • 打赏
  • 举报
回复
呵呵,使用到钩子了。
Joan_liu 2010-04-13
  • 打赏
  • 举报
回复
就是控件界面怎么拖啊
Justin-Liu 2010-04-13
  • 打赏
  • 举报
回复
没明白你要问啥
要是想明白实现 F10跟一下就知道了
Joan_liu 2010-04-13
  • 打赏
  • 举报
回复
---------------------引用上面的项目--------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.IO;
namespace MouseSelectImg
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private QinMi.CopyScreen cs;
private void button1_Click(object sender, EventArgs e)
{
cs.GerScreenFormRectangle();
}
void cs_GetScreenImage(Image _image)
{
pictureBox1.Image = _image;
}
private void Form1_Load(object sender, EventArgs e)
{
cs = new QinMi.CopyScreen();
cs.GetScreenImage += new QinMi.CopyScreen.GetImage(cs_GetScreenImage);
}
//点击保存
private void pictureBox1_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
sfd.ShowHelp = true;
sfd.HelpRequest += new EventHandler(sfd_HelpRequest);
sfd.Filter = "图片文件(*.jpg)|*.jpg|所有文件|*.*";
if (sfd.ShowDialog() == DialogResult.OK)
{
//string path = MapPath("/" + Guid.NewGuid().ToString() + ".jpg").ToString();
string path = sfd.FileName.ToString();
pictureBox1.Image.Save(path, ImageFormat.Jpeg);
}
}
private void sfd_HelpRequest(object sender, EventArgs e)
{
MessageBox.Show("输入文件名,保存到你指定的目录即可!");
}
public static string MapPath(string strPath)
{
if (System.Web.HttpContext.Current != null)
{
return System.Web.HttpContext.Current.Server.MapPath(strPath);
}
else //非web程序引用
{
strPath = strPath.Replace("/", "\\");
if (strPath.StartsWith("\\"))
{
//strPath = strPath.Substring(strPath.IndexOf('\\', 1)).TrimStart('\\');
strPath = strPath.TrimStart('\\');
}
return System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, strPath);
}
}
}
}

110,580

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧