那日突然心血来潮。。。想写一个简单的拾色器。
最后出来的东西比较简易,因为感觉这东西也没必要做得怎么好看,实用就行了。源码和程序的下载链接: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获取像素点,然后重绘客户区,在客户区内显示分解出来的黄绿蓝三色。
主要做的工作也就这几点了,上源代码:
[cpp] view plaincopy
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
char str[50];
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Simple Color Picker") ;
HWND hwnd ; //窗口句柄
MSG msg ; //消息结构
WNDCLASS wndclass ; //窗口类结构
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;//加载图标供程序使用
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; //加载鼠标指针供程序使用
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;//获取一个图形对象,在这个例子中,是获取绘制窗口背景的刷子
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))//为程序窗口注册窗口类
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
//根据窗口类创建一个窗口
hwnd = CreateWindowEx (WS_EX_TOPMOST,
szAppName, // window class name
TEXT ("Simple Color Picker"), // window caption
WS_OVERLAPPEDWINDOW & (~WS_MAXIMIZEBOX), // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
250, // initial x size
60, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
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);//执行默认的消息处理
}
--转自