这个工具是用来取屏幕中某一点的颜色,也就是得到这一点颜色的具体的RGB的值。类似的屏幕取色器其实挺多的,这个带源码,大家可以学习下。
因为需要hook鼠标move的消息,而且是全屏,所以需要使用全局钩子,也就是要将钩子功能写成动态链接库dll,
另外,因为我们需要得到某一点的颜色的值,所以很多时候我们得使用放大镜这个功能,而且MFC提供了CColorDialog功能类,这样我们就可以方便的提供调色板功能。很多截图软件所使用的也是同样的原理。
当时看了一点动态获取版本号的东西,所有这里面还有动态获取版本号的接口函数,就不细说了。
本工具纯属个人以前写着玩的,可能存在这样或那样的不足,欢迎交流原理性的东西,不欢迎纯问问题或编程风格类的交流。
开发环境:Win7 + VS2010(MFC)
废话少说,先上图,在上代码。



第一张是主界面,第二张是调色板界面,第三张是取色界面
主要代码马上就要列出来了,先说一下,代码中有很多注释,所以贴代码就不讲代码了
主界面的相关代码如下:
[cpp] view plaincopy
// 颜色按钮
void CRGBDlg::OnButtonCustomColor()
{
// TODO: Add your control notification handler code here
// CColorDialog colorDlg; // 调色板
COLORREF color;
if (m_pColorDlg != NULL && IDOK == m_pColorDlg->DoModal()) // 启动调色板
{
color = m_pColorDlg->GetColor(); // 获得选取的颜色
m_colorR.Format("%d", GetRValue(color)); // 格式化输出
m_colorG.Format("%d", GetGValue(color));
m_colorB.Format("%d", GetBValue(color));
DrawRGB();
UpdateData(FALSE);
}
}
// 取色按钮
void CRGBDlg::OnButtonGetColor()
{
ShowWindow(SW_HIDE); // 隐藏本窗口
m_pMagnifierDlg->StartHook(); // 启动hook
m_pMagnifierDlg->ShowWindow(SW_NORMAL); // 显示放大镜窗口
}
// hook 完成时的回调函数
LRESULT CRGBDlg::OnHookFinished(WPARAM wParam, LPARAM lParam)
{
if(lParam == TRUE)
{
// 从参数中读取RGB的值并且显示
m_colorR.Format("%d", GetRValue(wParam));
m_colorG.Format("%d", GetGValue(wParam));
m_colorB.Format("%d", GetBValue(wParam));
UpdateData(FALSE);
// if(m_pColorDlg != NULL)
// {
// COLORREF* pCustomColor = m_pColorDlg->GetSavedCustomColors();
// }
}
m_pMagnifierDlg->StopHook();
m_pMagnifierDlg->ShowWindow(SW_HIDE); // 显示放大镜窗口
// 画RGB所设置的颜色
DrawRGB();
ShowWindow(SW_NORMAL); // 正常显示窗口
::SetWindowPos(GetSafeHwnd(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
::SetWindowPos(GetSafeHwnd(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
return TRUE;
}
放大镜启动mouse hook的代码
[cpp] view plaincopy
// 启动钩子
void CMagnifierDlg::StartHook()
{
SetWindowPos(0, 0, 0, MAGNIFIER_DEST_RANGE, MAGNIFIER_DEST_RANGE, SWP_NOZORDER | SWP_NOMOVE);
// 以下主要用于修正范围
GetClientRect(m_currClientRange);
INT offset = MAGNIFIER_DEST_RANGE - m_currClientRange.Width();
SetWindowPos(0, 0, 0, MAGNIFIER_DEST_RANGE + offset, MAGNIFIER_DEST_RANGE + offset, SWP_NOZORDER | SWP_NOMOVE);
m_isEnter = FALSE;
if(m_hook.StartHook(GetSafeHwnd(), WM_HOOK_MESSAGE)) // 如果启动钩子成功
{
GetClientRect(m_currClientRange); // 获得当前客户区,主要是ChangeDisplayPos里面需要用到客户区尺寸
m_isTopLeft = TRUE;
ChangeDisplayPos(); // 设置客户区位置,避免客户区在中间
SetTimer(ACTIVE_WINDOWS_TIMER, 250, NULL); // 启动自动激活的timer,避免客户区被别的程序覆盖
SetTimer(GET_RGB_VALUE_TIMER, 500, NULL);
}
else
{
PostMessage(WM_CLOSE);
}
}
放大镜放大部分代码
[cpp] view plaincopy
// 显示客户区域
void CMagnifierDlg::ShowClientArea()
{
HDC hDc = ::GetDC(NULL); // 获取屏幕DC
CDC *dc = GetDC();
//定义一个内存设备描述表对象(即后备缓冲区)
CDC memDc;
//定义一个位图对象
CBitmap memBitmap;
//建立与屏幕设备描述表(前端缓冲区)兼容的内存设备描述表句柄(后备缓冲区)
memDc.CreateCompatibleDC(NULL);
//这时还不能绘图,因为没有位图的设备描述表是不能绘图的
//下面建立一个与屏幕设备描述表(或者内存设备描述表)兼容的位图
memBitmap.CreateCompatibleBitmap(dc, m_currClientRange.Width(), m_currClientRange.Height());
//将位图选入到内存设备描述表
//只有选入了位图的设备描述表才有地方绘图,画到指定的位图上
CBitmap *pOldBit = memDc.SelectObject(&memBitmap);
//先用背景色将位图清除干净
memDc.FillSolidRect(0, 0,
m_currClientRange.Width(), m_currClientRange.Height(), BG_COLOR);
::StretchBlt(memDc.GetSafeHdc(),
0, 0,
m_currClientRange.Width(), m_currClientRange.Height(),
hDc,
m_currSourceRange.left,m_currSourceRange.top,
m_currSourceRange.Width(), m_currSourceRange.Height(),
SRCCOPY);
memDc.SetBkMode(TRANSPARENT);
memDc.SetTextColor(RGB(255,0,255));
if(!(memDc.DrawText(m_mousePosString, &m_mousePosStringRect, DT_LEFT | DT_VCENTER)
&& memDc.DrawText(m_rateString, &m_rateStringRect, DT_RIGHT | DT_VCENTER)
&& memDc.DrawText(m_mouseColorString, &m_mouseColorStringRect, DT_LEFT | DT_VCENTER)))
{
TRACE("DrawKeyText error %d /n", GetLastError());
}
if(m_isShowHelp)
{
if(m_helpInfo1 != "" && !memDc.DrawText(m_helpInfo1, &m_helpInfo1Rect, DT_RIGHT | DT_VCENTER))
TRACE("DrawHelpText error %d /n", GetLastError());
if(m_helpInfo2 != "" && !memDc.DrawText(m_helpInfo2, &m_helpInfo2Rect, DT_RIGHT | DT_VCENTER))
TRACE("DrawHelpText2 error %d /n", GetLastError());
}
else
{
ShowChildClientArea(hDc, &memDc);
}
// 画线
LONG hafelinewidth = (LONG)(m_rate / 2);
LONG linewidth = hafelinewidth * 2;
// 下面的x、y、cx、cy仅仅用作临时变量,并非真实的x、y
INT x = 0, y = MAGNIFIER_DEST_RANGE / 2 - hafelinewidth;
INT y2 = MAGNIFIER_DEST_RANGE / 2 + hafelinewidth + CURR_POS_RANGE;
INT cx = linewidth, cy = MAGNIFIER_DEST_RANGE / 2 - hafelinewidth - CURR_POS_RANGE;
// 画竖直线
// memDc.FillSolidRect(y, x, cx ,cy, LINE_COLOR);
// memDc.FillSolidRect(y, y2, cx ,cy, LINE_COLOR);
DrawLineRect(&memDc, y, x, cx ,cy);
DrawLineRect(&memDc, y, y2, cx ,cy);
// 画水平线
DrawLineRect(&memDc, x, y, cy ,cx);
DrawLineRect(&memDc, y2, y, cy ,cx);
// memDc.FillSolidRect(x, y, cy ,cx, LINE_COLOR);
// memDc.FillSolidRect(y2, y, cy ,cx, LINE_COLOR);
#if 0
// 画个圆
memDc.Ellipse(CRect(MAGNIFIER_DEST_RANGE / 2 - CURR_POS_RANGE, MAGNIFIER_DEST_RANGE / 2 - CURR_POS_RANGE,
MAGNIFIER_DEST_RANGE / 2 + CURR_POS_RANGE, MAGNIFIER_DEST_RANGE / 2 + CURR_POS_RANGE));
#endif
//将后备缓冲区中的图形拷贝到前端缓冲区
dc->BitBlt(0, 0, m_currClientRange.Width(), m_currClientRange.Height(), &memDc, 0, 0, SRCCOPY);
//绘图完成后的清理
memBitmap.DeleteObject();
memDc.DeleteDC();
/*::ReleaseDC(GetSafeHwnd(), dc); // 释放当前客户区dc*/
ReleaseDC(dc);
if (m_currWarningRange.PtInRect(m_mousePos)) // 如果当前点在触发切换区域内,则触发切换
{
ChangeDisplayPos();
}
::ReleaseDC(0, hDc); // 释放屏幕dc
}
还有个子放大区域的代码,和整个差不多,就不整了
鼠标hook的关键代码
[cpp] view plaincopy
LRESULT WINAPI MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LPMOUSEHOOKSTRUCT pMouseHook=(MOUSEHOOKSTRUCT FAR *)lParam;
if (gHwnd != NULL)
{
PostMessage(gHwnd, gMessageId, wParam, POINTTOPOINTS(pMouseHook->pt));
TRACE("debug info isBlock = %d/n", gIsBlock);
if(gIsBlock)
{
return TRUE;
}
}
return CallNextHookEx(glhHook,nCode,wParam,lParam);
//继续传递消息
}
以上的代码就是此工具的关键点,涉及到钩子的安防,放大镜的实现。






















大小: 8KB

大小: 304.3M
终端仿真器 SecureCRTv7.1.1.264 最新版
串口调试小助手1.3 免费版
WinHex 十六进制编辑器v20.2 SR-5 绿色中文注册版
小旋风ASP服务器安装版
16进制转换工具V1.0 中文绿色版
Adobe AIRV33.1.1.932 官方最新版
github离线安装包64位版V2.9.11官方最新版(github desktop)
mysql数据库.net开发驱动(mysql connector net )8.0.11 官方最新版
MSDN Library Visual Studio 6.0(VC、VB、VF、VJ)中文版win32开发人员必备
版本控制软件(SourceTree)v3.4.6 官方最新版
Memory Analyzer (MAT)V1.01 免费绿色版
Delphi Distillerv1.85绿色版
IBM内存检测工具(IBM Thread and Monitor Dump Analyzer for Java)V4.3.3 绿色版
.NETv3.0 可再发行组件包
一键安装JSP环境安装版
slave4j(基于eclipse插件的java代码生成器)V1.0.0 正式版
Auto DebugProfessional 5.6.5.18 中文绿色版
Understand For C++V1.4.319英文安装版