利用Windows API实现屏幕取色器

一  效果图

  为了实现这个取色器,在网上查了很多关于取色器的资料,起先是通过winform怎么制作,后来发现大多数资料都调用了windows api,但自己以前从来没有用过这方面的,又从网上下了windows api 来看,经过多次实践终于做出了现在这个效果,先感谢下网上那些提供资料的朋友。

  效果,如下图:

  利用Windows API实现屏幕取色器

二 原理

  为了实现整个屏幕取色

  1.需要获取鼠标当前的位置

  2.获取整个窗口的场景

  3.获取指定点的颜色值

  4.判断按键状态来控制开始结束取色

  需要实现这些功能,就必需要调用windows api来实现。

  在C#中调用windows api的方式如下所示:

 

  
    
[DllImport( " user32.dll " )]
public static extern uint WindowFromPoint( uint x_point, uint y_point);

三 详细代码

 

  关键代码都已经注释,就不解释了。界面代码就不给出了很简单的。

 

代码
   
     
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace GetColor
{
public partial class colorForm : Form
{
private int redValue = 255 ;
private int greenValue = 255 ;
private int blueValue = 255 ;

public colorForm()
{
InitializeComponent();

InitPanelColor();
}

private bool flag = false ;

public struct POINTAPI
{
public uint x;
public uint y;
}

public class WinInfo
{
/// <summary>
/// 返回包含了指定点的窗口的句柄
/// </summary>
/// <param name="x_point"></param>
/// <param name="y_point"></param>
/// <returns></returns>
[DllImport( " user32.dll " )]
public static extern uint WindowFromPoint( uint x_point, uint y_point);

/// <summary>
/// 获取鼠标指针当前位置
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
[DllImport( " user32.dll " )]
public static extern bool GetCursorPos( ref POINTAPI p);

/// <summary>
/// 判断屏幕上一个指定点的客户区坐标
/// </summary>
/// <param name="hwnd"> 一个窗口的句柄,该窗口定义了要使用的客户区坐标系统 </param>
/// <param name="p"></param>
/// <returns></returns>
[DllImport( " user32.dll " )]
public static extern uint ScreenToClient( uint hwnd, ref POINTAPI p);


/// <summary>
/// 获取指定窗口的设备场景
/// </summary>
/// <param name="hwnd"> 将获取其设备场景的窗口的句柄。若为0,则要获取整个屏幕的DC </param>
/// <returns></returns>
[DllImport( " user32.dll " )]
public static extern uint GetDC( uint hwnd);

/// <summary>
/// 在指定的设备场景中取得一个像素的RGB值
/// </summary>
/// <param name="hDC"> 一个设备场景的句柄 </param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
[DllImport( " gdi32.dll " )]
public static extern uint GetPixel( uint hDC, uint x, uint y);

/// <summary>
/// 释放由调用GetDC或GetWindowDC函数获取的指定设备场景。它对类或私有设备场景无效(但这样的调用不会造成损害)
/// </summary>
/// <param name="hwnd"> 要释放的设备场景相关的窗口句柄 </param>
/// <param name="hdc"> 要释放的设备场景句柄 </param>
/// <returns></returns>
[DllImport( " user32.dll " )]
public static extern uint ReleaseDC( uint hwnd, uint hdc);

/// <summary>
/// 获取整个窗口(包括边框、滚动条、标题栏、菜单等)的设备场景
/// </summary>
/// <param name="hwnd"> 将获取其设备场景的窗口 </param>
/// <returns></returns>
[DllImport( " user32.dll " )]
public static extern uint GetWindowDC( uint hwnd);

/// <summary>
/// 模拟一次鼠标事件
/// </summary>
/// <param name="dwFlags"></param>
/// <param name="dx"></param>
/// <param name="dy"></param>
[DllImport( " user32.dll " )]
public static extern void mouse_event( uint dwFlags, uint dx, uint dy);

[DllImport(
" user32.dll " )]
public static extern void keybd_event( byte bVk, byte bScan, long dwFlags, long dwExtraInfo);

/// <summary>
/// 判断指定键盘状态
/// </summary>
/// <param name="nVirtKey"></param>
/// <returns></returns>
[DllImport( " user32.dll " ,CharSet = CharSet.Auto,ExactSpelling = true )]
public static extern short GetKeyState( long nVirtKey);
}

/// <summary>
/// 初始化色板颜色-白色
/// </summary>
private void InitPanelColor()
{
panelColor.BackColor
= Color.FromArgb(Convert.ToInt32(txtRedValue.Text), Convert.ToInt32(txtGreenValue.Text), Convert.ToInt32(txtBlueValue.Text));
}

private void txtRedValue_TextChanged( object sender, EventArgs e)
{
redValue
= Convert.ToInt32(txtRedValue.Text == "" ? " 0 " : txtRedValue.Text);
SetPanelColor();
}

private void txtGreenValue_TextChanged( object sender, EventArgs e)
{
greenValue
= Convert.ToInt32(txtGreenValue.Text == "" ? " 0 " : txtGreenValue.Text);
SetPanelColor();
}

private void txtBlueValue_TextChanged( object sender, EventArgs e)
{
blueValue
= Convert.ToInt32(txtBlueValue.Text == "" ? " 0 " : txtBlueValue.Text);
SetPanelColor();
}

/// <summary>
/// 设置面板颜色
/// </summary>
private void SetPanelColor()
{
panelColor.BackColor
= Color.FromArgb(LimitNum(redValue), LimitNum(greenValue), LimitNum(blueValue));
}

private int LimitNum( int num)
{
if (num > 255 )
{
return 255 ;
}
else if (num < 0 )
{
return 0 ;
}
else
{
return num;
}
}

private void panelColor_MouseClick( object sender, MouseEventArgs e)
{
flag
= true ;
}

private void colorForm_MouseMove( object sender, MouseEventArgs e)
{
isGetColor();
}

/// <summary>
/// 按ESC开始停止取色
/// </summary>
private void isGetColor()
{
if ((( ushort )WinInfo.GetKeyState( 27 ) & 0xffff ) != 0 )
{
flag
= true ;
}
else
{
flag
= false ;
this .Cursor = Cursors.Arrow;
}

if (flag)
{
this .Cursor = Cursors.Hand;
POINTAPI Papi
= new POINTAPI();
WinInfo.GetCursorPos(
ref Papi);
uint v_hwnd = WinInfo.WindowFromPoint(Papi.x, Papi.y);
uint v_DC = WinInfo.GetDC(v_hwnd);
WinInfo.ScreenToClient(v_hwnd,
ref Papi);
WinInfo.mouse_event(
0x0002 , Papi.x, Papi.y);
uint v_Color = WinInfo.GetPixel(v_DC, Papi.x, Papi.y);

uint v_Red, v_Green, v_Blue;
v_Red
= v_Color & 0xff ;
v_Green
= (v_Color & 0xff00 ) / 256 ;
v_Blue
= (v_Color & 0xff0000 ) / 65536 ;

this .txtColorValue.Text = " # " + v_Red.ToString( " x " ).PadLeft( 2 , ' 0 ' ) + v_Green.ToString( " x " ).PadLeft( 2 , ' 0 ' ) + v_Blue.ToString( " x " ).PadLeft( 2 , ' 0 ' );
txtRedValue.Text
= v_Red.ToString( " d " );
txtGreenValue.Text
= v_Green.ToString( " d " );
txtBlueValue.Text
= v_Blue.ToString( " d " );
this .panelColor.BackColor = Color.FromArgb(( int )v_Red, ( int )v_Green, ( int )v_Blue);
WinInfo.ReleaseDC(v_hwnd, v_DC);
}
}

private void txtRedValue_KeyPress( object sender, KeyPressEventArgs e)
{
if (e.KeyChar != 8 && ! char .IsDigit(e.KeyChar))
{
e.Handled
= true ;
}
}

private void txtGreenValue_KeyPress( object sender, KeyPressEventArgs e)
{
if (e.KeyChar != 8 && ! char .IsDigit(e.KeyChar))
{
e.Handled
= true ;
}
}

private void txtBlueValue_KeyPress( object sender, KeyPressEventArgs e)
{
if (e.KeyChar != 8 && ! char .IsDigit(e.KeyChar))
{
e.Handled
= true ;
}
}

private void 关于ToolStripMenuItem_Click( object sender, EventArgs e)
{
MessageBox.Show(
" winform版取色器\r\r版本1.0.0\r\r作者 忧忧夏天 " , " 关于 " , MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}

private void 介绍ToolStripMenuItem_Click( object sender, EventArgs e)
{
MessageBox.Show(
" 在颜色表里面按ESC开取色,要结束再按一次ESC\r\r交流QQ466260359 " , " 介绍 " , MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}

}
}

 

源码下载

你可能感兴趣的:(windows)