这个工具是我前一篇文章的产物,特地发出来,作为前文的补充。
前文地址:http://www.cnblogs.com/tufeigd/archive/2009/02/14/1390391.html
今天发现有个小bug,在挂接事件那里没有判断tag是否为空,已经更新了文件,请重新下载
思路
由于不想用到win32的api函数,而又要实现实时取色,则必须用一个timer控件,进行如下步骤
1、屏幕取图为img
2、取得当前鼠标位置x,y
3、利用img的GetPixel函数获取x,y坐标处的颜色
4、这个过程中,如果按下热键则保存当前颜色和坐标
程序截图
先来看看截图,对接下来的代码说明也好有个印象

代码说明
1、截取全屏
//截全屏
Bitmap img = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(img);
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), Screen.PrimaryScreen.Bounds.Size);
2、获取当前坐标
//获取当前坐标
int x = Control.MousePosition.X;
int y=Control.MousePosition.Y;
3、取色
这里我定义了一个结构来保存当前的坐标信息以及颜色

/**//// <summary>
/// 定义一个结构用于保存信息
/// </summary>
private struct PointColorInfo

{
public int x;
public int y;
public Color color;
}
定义了一个PointColorInfo类型的变量

/**//// <summary>
/// 当前鼠标所指信息,包括坐标和颜色
/// </summary>
private PointColorInfo currentColorInfo;
保存信息
//取色
Color current = img.GetPixel(x, y);

currentColorInfo.x = x;
currentColorInfo.y = y;
currentColorInfo.color = current;
4、显示相关取色信息

/**//// <summary>
/// 设置
/// </summary>
/// <param name="currentPoint"></param>
private void SetControlStatus(PointColorInfo currentPoint)

{
//坐标
tbX.Text = currentPoint.x.ToString();
tbY.Text = currentPoint.y.ToString();

lblCurrentColor.BackColor = currentPoint.color;

//颜色转换
tbHTML.Text = ColorTranslator.ToHtml(currentPoint.color);
tbWin32.Text = ColorTranslator.ToWin32(currentPoint.color).ToString();
tbRGB.Text = string.Format("{0},{1},{2}", currentPoint.color.R.ToString(),
currentPoint.color.G.ToString(), currentPoint.color.B.ToString());
}
5、热键相关
这里提供一个热键类,也是网上找回来的,作者不知道是谁

Code
class HotKey

{
//如果函数执行成功,返回值不为0。
//如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。
[DllImport("user32.dll", SetLastError = true)]
public static extern bool RegisterHotKey(
IntPtr hWnd, //要定义热键的窗口的句柄
int id, //定义热键ID(不能与其它ID重复)
uint fsModifiers, //标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效
Keys vk //定义热键的内容
);

[DllImport("user32.dll", SetLastError = true)]
public static extern bool UnregisterHotKey(
IntPtr hWnd, //要取消热键的窗口的句柄
int id //要取消热键的ID
);

//定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值)
[Flags()]
public enum KeyModifiers

{
None = 0,
Alt = 1,
Ctrl = 2,
Shift = 4,
WindowsKey = 8
}
}
热键注册以及注销

/**//// <summary>
/// 取图按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnGetColor_Click(object sender, EventArgs e)

{
Button current = sender as Button;
if (current.Text=="取色")

{
tmerGetColor.Enabled = true;
current.Text = "停止";

uint hotKey = (uint)(HotKey.KeyModifiers.Ctrl);
HotKey.RegisterHotKey(Handle, 100, hotKey, Keys.G);//这时热键为CTRL+G
}
else

{
tmerGetColor.Enabled = false;
current.Text = "取色";

HotKey.UnregisterHotKey(Handle, 100);//卸载第1个快捷键
}
}
响应热键,在按下热键时,将信息保存到相应的控件中,这里的indexCurrent初始值为1,窗体上的已取颜色的控件名从lblColor1-lblColor7

/**//// <summary>
/// 重写WndProc()方法,通过监视系统消息,来调用过程
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)//监视Windows消息

{
const int WM_HOTKEY = 0x0312;//如果m.Msg的值为0x0312那么表示用户按下了热键
switch (m.Msg)

{
case WM_HOTKEY:
ProcessHotkey();//按下热键时调用ProcessHotkey()函数
break;
}
base.WndProc(ref m); //将系统消息传递自父类的WndProc
}

/**//// <summary>
/// 点击热键后
/// </summary>
private void ProcessHotkey()

{
Label currentLabel = ((Label) (this.Controls.Find("lblColor" + indexCurrent.ToString(), true)[0]));
currentLabel.BackColor = currentColorInfo.color;
currentLabel.Tag = currentColorInfo;

indexCurrent = indexCurrent + 1;
if (indexCurrent == 8)
indexCurrent = 1;
}
6、点击已取颜色,显示相关信息
将已取颜色的点击事件全部挂接到如下事件:

/**//// <summary>
/// 点击已取颜色,显示结果
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lblColor_Click(object sender, EventArgs e)

{
Label current = sender as Label;

if (current.Tag!=null)

{
PointColorInfo saveInfo = (PointColorInfo)current.Tag;
SetControlStatus(saveInfo);
}
}
至此,大功告成,下面提供源码和执行文件的下载。
源码:/Files/tufeigd/屏幕取图--工程文件.rar
执行文件:/Files/tufeigd/屏幕取图.rar