QQ抓屏(可以修改为屏幕颜色拾取器)

最近工作的需要,写了一个类似QQ抓屏的东西,以前园子里的人好像写过。因为我们现在做的是商业代码,所以处理的比较完美,也不方便发出来,就借用以前仁兄的部分代码,加上我的代码发出来:) 哈哈~ 不用API。因为商业代码不能轻易外传,所以只能发这样的,兄弟们见谅。
感谢那位仁兄,我在园子里搜索了半天没有搜索到。
希望能给一些人带来点帮助。
如果可能的话,过一些时间应该会把那些代码放出来。哈哈哈~ 因为过段时间就没有什么商业价值了。
先看个贴图:

贴上一些代码:
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;

namespace QQCaptureScreen
{
    
/// <summary>
    
/// 用于截图窗体
    
/// <remarks>首先窗体全屏,然后以屏幕为窗体背景,在窗体上截图</remarks>
    
/// </summary>
    public partial class CaptureScreenForm : Form
    {
        
/// <summary>
        
/// 声明一个矩形区域
        
/// </summary>
        private Rectangle rectangle = Rectangle.Empty;
        
/// <summary>
        
/// 用来保存抓取得图像
        
/// </summary>
        private Bitmap image = null;
        
/// <summary>
        
/// 用于记录背景图像
        
/// </summary>
        private Bitmap backimage = null;
        
/// <summary>
        
/// 用于记录绘制出的矩形边界上的点的序号
        
/// </summary>
        private int index = -1;
        
/// <summary>
        
/// 用于记录鼠标坐标
        
/// </summary>
        private Point point1 = Point.Empty;
        
/// <summary>
        
/// 没有选择时候显示的文字
        
/// </summary>
        private static string noselectString = "\n\n\n当前像素RGB({0},{1},{2})\n.按下鼠标左键不放选择截取范围\n.按'ESC'键或鼠标右键退出";
        
/// <summary>
        
/// 正在选择时候显示的文字
        
/// </summary>
        private static string selectingString = "\n\n\n.松开鼠标左键确定选择范围\n.不松开鼠标左键按'ESC'重选";
        
/// <summary>
        
/// 选择以后显示的文字
        
/// </summary>
        private static string selectedString = "\n\n\n.用鼠标左键调整选择范围的大小和位置\n.双击鼠标左键保存图像 \n.点鼠标右键重新选择 \n.按'ESC'退出";

        
/// <summary>
        
/// 构造函数
        
/// </summary>
        public CaptureScreenForm()
        {
            InitializeComponent();
        }

        
/// <summary>
        
/// 窗体初始化
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>
        private void CaptureScreenForm_Load(object sender, EventArgs e)
        {
            
// 窗体全屏显示
            this.Bounds = Screen.PrimaryScreen.Bounds;
            
// 取得窗体的背景
            backimage = GetFullScreen();
            
// 设置窗体背景
            this.BackgroundImage = backimage;

            
// 设置标签的初始位置
            label1.Location = new Point(8-183);

            Timer timer 
= new Timer();
            timer.Interval 
= 1;
            timer.Tick 
+= delegate
            {
                label1.Top
++;
                
if (label1.Top == 8)
                {
                    timer.Enabled 
= false;
                }
            };
            timer.Enabled 
= true;
            label1.Text 
= string.Format(noselectString, 255255255);
        }

        
/// <summary>
        
/// 取得全屏的截图
        
/// </summary>
        
/// <returns>全屏截图</returns>
        
/// <remarks>根据屏幕大小取得</remarks>
        private Bitmap GetFullScreen()
        {
            
// 取得屏幕宽
            int nWidth = Screen.PrimaryScreen.Bounds.Width;
            
// 取得屏幕高
            int nHeight = Screen.PrimaryScreen.Bounds.Height;
            
// 创建位图对象
            Bitmap bitmap = new Bitmap(nWidth, nHeight, PixelFormat.Format32bppArgb);
            
// 创建Graphics对象
            Graphics graphics = Graphics.FromImage(bitmap);
            
// 将屏幕拷贝至bitmap
            graphics.CopyFromScreen(0000new Size(nWidth, nHeight));
            
// 返回bitmap
            return bitmap;
        }

        
/// <summary>
        
/// 重载OnPaint
        
/// </summary>
        
/// <param name="e">Paint事件</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            
// 执行父类OnPaint方法
            base.OnPaint(e);
            
// 绘制矩形
            e.Graphics.DrawRectangle(new Pen(Color.DarkSeaGreen), rectangle);

            
// 在矩形上绘制8个点(小矩形),并记录8个点的序号
            for (int i = 1; i < 9; i++)
            {
                
// 填充矩形上各点的小矩形
                e.Graphics.FillRectangle(new SolidBrush(Color.DarkSeaGreen), GetHandleRactangle(i));
            }
        }

        
/// <summary>
        
/// 取得矩形上每个点所对应的矩形
        
/// </summary>
        
/// <param name="i">点序号</param>
        
/// <returns>序号对应的矩形</returns>
        private Rectangle GetHandleRactangle(int i)
        {
            
// 取得序号i对应的点的矩形坐标
            Point point = GetHandle(i);
            
// 返回矩形
            return new Rectangle(point.X - 3, point.Y - 366);
        }

        
/// <summary>
        
/// 取得序号i对应的点的矩形坐标
        
/// </summary>
        
/// <param name="i">点序号</param>
        
/// <returns>坐标</returns>
        private Point GetHandle(int i)
        {
            
// 大矩形中心横坐标
            int nCenterX = rectangle.X + rectangle.Width / 2;
            
// 大矩形中心纵坐标
            int nCenterY = rectangle.Y + rectangle.Height / 2;

            
// 矩形的形状
            /*----------------------------------------------
             * 1-------2-------3
             * |               |
             * |               |
             * 8               4
             * |               |
             * |               |
             * 7-------6-------5
             * -------------------------------------------
*/
            
int[,] arrPoints = {{ rectangle.X,      rectangle.Y         }, 
                                { nCenterX,         rectangle.Y         },
                                { rectangle.Right,  rectangle.Y         },
                                { rectangle.Right,  nCenterY            },
                                { rectangle.Right,  rectangle.Bottom    },
                                { nCenterX,         rectangle.Bottom    },
                                { rectangle.X,      rectangle.Bottom    },
                                { rectangle.X,      nCenterY            }
                               };
            
// 返回坐标
            return new Point(arrPoints[i - 10], arrPoints[i - 11]);
        }

        
/// <summary>
        
/// 重载鼠标按下方法
        
/// </summary>
        
/// <param name="e">鼠标事件</param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            
// 执行父类鼠标按下方法
            base.OnMouseDown(e);

            
// 如果是鼠标左键按下,以及矩形区域为NULL
            if (object.Equals(Rectangle.Empty, rectangle) && object.Equals(MouseButtons.Left, e.Button))
            {
                
// 显示正在选择文字
                label1.Text = selectingString;
                
// 设置举行位置
                rectangle.Location = new Point(e.X, e.Y);
            }

            
// 记录鼠标位置
            point1 = new Point(e.X, e.Y);
            index 
= GetSelectedHandle(point1);
            SetCursor();
        }

        
/// <summary>
        
/// 设置当前鼠标样式
        
/// </summary>
        private void SetCursor()
        {
            
// 如果非8个点及矩形外部
            if (index < 0 || index > 8)
            {
                
// 设置当前鼠标样式
                Cursor.Current = Cursors.Default;
                
// 弹出
                return;
            }

            
// 8个点及矩形内部的不同鼠标形状
            Cursor[] arrCursors =   {   Cursors.SizeAll, // 中心位置
                                        Cursors.SizeNWSE, 
                                        Cursors.SizeNS, 
                                        Cursors.SizeNESW, 
                                        Cursors.SizeWE, 
                                        Cursors.SizeNWSE, 
                                        Cursors.SizeNS, 
                                        Cursors.SizeNESW, 
                                        Cursors.SizeWE 
                                    };
            
// 设置当前鼠标样式
            Cursor.Current = arrCursors[index];
        }

        
/// <summary>
        
/// 取得选择区域的不同点的index值
        
/// </summary>
        
/// <param name="point">坐标</param>
        
/// <returns>点对应的index值</returns>
        private int GetSelectedHandle(Point point)
        {
            
// 返回值
            int index = -1;
            
// 判断坐标是否为矩形上8个点的坐标
            for (int i = 1; i < 9; i++)
            {
                
// 如果坐标是8个点的坐标部分
                if (GetHandleRactangle(i).Contains(point))
                {
                    index 
= i;
                    
break;
                }
            }
            
// 如果坐标在矩形内部
            if (rectangle.Contains(point))
            {
                index 
= 0;
            }
            
// 返回index值
            return index; 
        }

        
/// <summary>
        
/// 重载鼠标松开方法
        
/// </summary>
        
/// <param name="e">鼠标事件</param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            
// 执行父类鼠标松开方法
            base.OnMouseUp(e);
            
// 矩形左边缘X坐标
            int nLeft = rectangle.Left;
            
// 矩形上边缘Y坐标
            int nTop = rectangle.Top;
            
// 矩形右边缘X坐标
            int nRight = rectangle.Right;
            
// 矩形下边缘Y坐标
            int nBottom = rectangle.Bottom;
            
// 取得两X坐标的最小值作为矩形的左边缘位置
            rectangle.X = Math.Min(nLeft, nRight);
            
// 取得两Y坐标的最小值作为矩形的上边缘位置
            rectangle.Y = Math.Min(nTop, nBottom);
            
// 设置矩形的宽度
            rectangle.Width = Math.Abs(nLeft - nRight);
            
// 设置矩形的高度
            rectangle.Height = Math.Abs(nTop - nBottom);
            
// 显示文字文已经选择矩形区域
            label1.Text = selectedString;

            
// 如果按下鼠标右键
            if (object.Equals(MouseButtons.Right, e.Button))
            {
                
// 如果所选矩形为空
                if (object.Equals(Rectangle.Empty, rectangle))
                {
                    
// 关闭窗体
                    this.Close();
                }
                
else
                {
                    
// 设置矩形为空
                    rectangle = Rectangle.Empty;
                    
// 使矩形区域无效
                    this.Invalidate();
                }
            }
            
// 设置index值
            index = this.GetSelectedHandle(new Point(e.X, e.Y));
            
// 设置鼠标样式
            SetCursor();
        }

        
/// <summary>
        
/// 重载鼠标移动方法
        
/// </summary>
        
/// <param name="e">鼠标事件</param>
        protected override void OnMouseMove(MouseEventArgs e)
        {
            
// 执行父类鼠标移动方法
            base.OnMouseMove(e);
            
// 如果窗体已捕获鼠标
            if (this.Capture)
            {
                
// 移动所选区域
                MoveHandleTo(new Point(e.X, e.Y));
                
// 使原矩形区域无效
                this.Invalidate();
            }
            
else
            {
                
// 设置index值
                index = GetSelectedHandle(new Point(e.X, e.Y));
                
// 设置鼠标样式
                SetCursor();
                label1.Text 
= label1.Text = string.Format(noselectString, backimage.GetPixel(e.X, e.Y).R, backimage.GetPixel(e.X, e.Y).G, backimage.GetPixel(e.X, e.Y).B);
            }
        }

        
/// <summary>
        
/// 移动所选区域
        
/// </summary>
        
/// <param name="point">鼠标现在位置坐标</param>
        private void MoveHandleTo(Point point)
        {
            
// 取得左边缘X坐标
            int nLeft = rectangle.Left;
            
// 取得上边缘Y坐标
            int nTop = rectangle.Top;
            
// 取得右边缘X坐标
            int nRight = rectangle.Right;
            
// 取得下边缘Y坐标
            int nBottom = rectangle.Bottom;

            
// 判断index值
            if (int.Equals(0, index))
            {
                rectangle.X 
+= point.X - point1.X;
                rectangle.Y 
+= point.Y - point1.Y;
                point1 
= point;
                
return;
            }
            
// 针对矩形上不同点的序号记录矩形位置
            
// 坐标分别为左、上、右、下
            int[,] arrHandles = {   { point.X,          point.Y,        rectangle.Right,    rectangle.Bottom }, 
                                    { rectangle.Left,   point.Y,        rectangle.Right,    rectangle.Bottom }, 
                                    { rectangle.Left,   point.Y,        point.X,            rectangle.Bottom }, 
                                    { rectangle.Left,   rectangle.Top,  point.X,            rectangle.Bottom }, 
                                    { rectangle.Left,   rectangle.Top,  point.X,            point.Y }, 
                                    { rectangle.Left,   rectangle.Top,  rectangle.Right,    point.Y }, 
                                    { point.X,          rectangle.Top,  rectangle.Right,    point.Y }, 
                                    { point.X,          rectangle.Top,  rectangle.Right,    rectangle.Bottom } 
                                };
            
// 记录鼠标坐标
            point1 = point;
            
// 矩形左边缘横坐标
            rectangle.X = arrHandles[index - 10];
            
// 矩形上边缘纵坐标
            rectangle.Y = arrHandles[index - 11];
            
// 矩形宽度
            rectangle.Width = arrHandles[index - 12- arrHandles[index - 10];
            
// 矩形高度
            rectangle.Height = arrHandles[index - 13- arrHandles[index - 11];
        }

        
/// <summary>
        
/// 双击窗体
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>
        
/// <remarks>如果双击选中区域,则保存图片</remarks>
        private void CaptureScreenForm_DoubleClick(object sender, EventArgs e)
        {
            Bitmap bm 
= new Bitmap(this.BackgroundImage);
            
// 保存图片
            image = bm.Clone(rectangle, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            MainForm.image 
= image;
            MainForm.ActiveForm.Invalidate();
            
this.Close();
        }

        
/// <summary>
        
/// 键盘按下事件
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>
        
/// <remarks>如果按下ESC键同时鼠标左键按住,则释放矩形区域,如果只按ESC键,关闭窗体</remarks>
        private void CaptureScreenForm_KeyDown(object sender, KeyEventArgs e)
        {
            
if (e.KeyData == Keys.Escape && System.Windows.Forms.Button.MouseButtons == MouseButtons.Left)
            {
                rectangle 
= Rectangle.Empty;
                
this.Invalidate();
                label1.Text 
= noselectString;
            }
            
else if (e.KeyData == Keys.Escape)
            { 
                
this.Close(); 
            }
        }

        
/// <summary>
        
/// 标签鼠标经过时间
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>
        private void label1_MouseMove(object sender, MouseEventArgs e)
        {
            
if (label1.Location.X == 8 && label1.Location.Y == 8)
            {
                Point formloc 
= new Point((Screen.PrimaryScreen.Bounds.Width - 174), 8);
                label1.Location 
= formloc;
            }
            
else
            {
                label1.Location 
= new Point(88);
            }

        }
    }
}
最后是示例下载:)
/Files/luoboqingcai/QQCaptureScreen.rar

posted on 2006-06-25 12:43  萝卜青菜  阅读(1349)  评论(4编辑  收藏  举报

导航