那日突然心血来潮。。。想写一个简单的拾色器。
最后出来的东西比较简易,因为感觉这东西也没必要做得怎么好看,实用就行了。源码和程序的下载链接:http://download.csdn.net/source/2402476
刚开始打算做一个MFC对话框程序,通过响应WM_MOUSEMOVE来完成,无果。使用过SetCapture、HOOK等方法均没尝试成功。后来只好退而求其次,使用一个时间超短的定时器来做了这个活儿。使用Win32 API方式,GCC编译。
运行效果如下图(窗口可以无焦点,可以对屏幕上任意点取色):
首先找到一个最简单的典型Win32窗口程序,然后在里面小做修改,就可以得到本程序。
1、为了保证能一直看得到取色结果,要将窗口置顶,故创建窗口时采用CreateWindowEx函数,第一个参数设为WS_EX_TOPMOST来将窗口置顶。
2、窗口的显示信息大致一定,不需要改变窗口大小,故将最大化框去掉,方法为窗口风格参数写法为WS_OVERLAPPEDWINDOW & (~WS_MAXIMIZEBOX)。
3、在WM_CREATE消息中SetTimer(hwnd, 1, 10, NULL),即刷新时间10毫秒。在WM_DESTROY中KillTimer。
4、在WM_TIMER中利用GetCursorPos取得鼠标的屏幕坐标,用屏幕DC为参数来GetPixel获取像素点,然后重绘客户区,在客户区内显示分解出来的黄绿蓝三色。
主要做的工作也就这几点了,上源代码:
ShowWindow (hwnd, iCmdShow) ; //在屏幕上显示窗口
UpdateWindow (hwnd) ; //指示窗口刷新自身
while (GetMessage (&msg, NULL, 0, 0)) //从消息队列中获取消息
{
TranslateMessage (&msg) ; //转换某些键盘消息
DispatchMessage (&msg) ; //将消息发送给窗口过程
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
POINT pt;
COLORREF clr;
HDC h;
switch (message)
{
case WM_CREATE:
SetTimer(hwnd, 1, 10, NULL);
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ; //开始窗口绘制
GetClientRect (hwnd, &rect) ; //获取窗口客户区的尺寸
DrawText (hdc, str, -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; //显示文本串
EndPaint (hwnd, &ps) ; //结束窗口绘制
ReleaseDC(hwnd, hdc);
return 0 ;
case WM_TIMER:
GetCursorPos(&pt);
h=GetWindowDC(GetDesktopWindow());
clr = ::GetPixel(h, pt.x, pt.y);
sprintf(str, "RED:%d,GREEN:%d,BLUE:%d", GetRValue(clr), GetGValue(clr), GetBValue(clr));
GetClientRect (hwnd, &rect) ;
InvalidateRect(hwnd, &rect, true);
ReleaseDC(hwnd, h);
return 0;
case WM_DESTROY:
KillTimer(hwnd, 1);
PostQuitMessage (0) ; //在消息队列中插入一条退出消息
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam);//执行默认的消息处理
}