首页 > Windows SDK > Win32写的屏幕取色工具

Win32写的屏幕取色工具

本文介绍如何通过Windows SDK编程实现鼠标屏幕取色功能,可以将技术迁移到VC/MFC等。几个关键实现:

  • 屏幕取色通过WM_TIMER来实现,而不是WM_MOUSEMOVE,因为后者只能捕获客户区的消息,根本达不到目的。
  • 无标题窗口风格是在CreateWindow的时候设置WS_POPUP风格。
  • 窗口置顶通过SetWindowPos的HWND_TOPMOST来实现。
  • 屏幕取色原理:获取桌面DC,然后GetPixel获取RGB颜色,然后通过GetRValue, GetGValue, GetBValue来获取颜色分量
  • 自定义PointInRect来实现鼠标移到窗体后窗体自动移开。

效果截图如下:

取色效果截图

代码如下:

/**************************************************************
 * Copyright (C), 2008-2010, Www.ProgramLife.Net Tech. Co., Ltd.
 * FileName: WHATCLR.c
 * Author: 代码疯子
 * Version: V1.0
 * Date: 2010-10-15
 * Description: Win32 API屏幕取色实现
 * Version: V1.0
 * Reference: Windows程序设计
 * 代码疯子 2010/10/15 1.0 build this moudle
 *************************************************************/
#include <windows.h>

#define ID_TIMER 1

BOOL PointInRect(POINT pt, RECT rc);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine,
				   int nShowCmd)
{
	static TCHAR szAppName[] = TEXT("WHATCLR");
	HWND		hwnd;
	MSG			msg;
	WNDCLASS	wndclass;

	//窗口类设计
	wndclass.hInstance		= hInstance;
	wndclass.lpfnWndProc	= WndProc;
	wndclass.cbClsExtra		= 0;
	wndclass.cbWndExtra		= 0;
	wndclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndclass.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wndclass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	wndclass.lpszClassName	= szAppName;
	wndclass.lpszMenuName	= NULL;
	wndclass.style			= CS_HREDRAW | CS_VREDRAW;

	//注册窗口类
	if(!RegisterClass(&wndclass))
	{
		MessageBox(NULL, TEXT("This application requires Windows NT !"),
					TEXT("Error"), MB_ICONERROR);
		return 0;
	}

	//创建窗口
	hwnd = CreateWindow(szAppName,
						TEXT("What Color"),
						WS_POPUP,				//无标题栏窗体
						0,
						0,
						80,
						30,
						NULL,
						NULL,
						hInstance,
						NULL);

	//显示窗口
	ShowWindow(hwnd, SW_SHOWNORMAL);

	//更新窗口
	UpdateWindow(hwnd);

	//消息循环
	while(GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

BOOL PointInRect(POINT pt, RECT rc)
{
	if(pt.x >= rc.left && pt.x <= rc.right && pt.y >= rc.top && pt.y <= rc.bottom)
	{
		return TRUE;
	}
	return FALSE;
}

//回调函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static COLORREF	cr, crLast;
	static HDC		hdcScreen;
	HDC				hdc;
	PAINTSTRUCT		ps;
	POINT			pt;
	RECT			rc;
	TCHAR			szBuffer[16];
	static int		nPos;

	switch(message)
	{
	case WM_CREATE:
		hdcScreen = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
		SetTimer(hwnd, ID_TIMER, 100, NULL);
		nPos = 1;	//左边
		//窗口置顶放置
		SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
		return 0;

	case WM_TIMER:
		GetCursorPos(&pt);
		GetWindowRect(hwnd, &rc);
		cr = GetPixel(hdcScreen, pt.x, pt.y);
		//SetPixel(hdcScreen, pt.x, pt.y, 0);

		if(PointInRect(pt, rc))
		{
			switch(nPos)
			{
			case 1:
				nPos = 2;
				MoveWindow(hwnd, GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left), 0, 
					rc.right - rc.left, rc.bottom - rc.top, TRUE);
				break;

			case 2:
				nPos = 1;
				MoveWindow(hwnd, 0, 0,
					rc.right - rc.left, rc.bottom - rc.top, TRUE);
				break;
			}
		}

		if(cr != crLast)
		{
			crLast = cr;
			InvalidateRect(hwnd, NULL, TRUE);
		}
		return 0;

	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);
		
		GetClientRect(hwnd, &rc);
		wsprintf(szBuffer, TEXT("%02X %02X %02X"), 
			GetRValue(cr), GetGValue(cr), GetBValue(cr));
		DrawText(hdc, szBuffer, -1, &rc,
			DT_SINGLELINE | DT_CENTER | DT_VCENTER);

		EndPaint(hwnd, &ps);
		return 0;

	case WM_DESTROY:
		DeleteDC(hdcScreen);
		KillTimer(hwnd, ID_TIMER);
		PostQuitMessage(0);
		return 0;

	default:
		break;
	}

	return DefWindowProc(hwnd, message, wParam, lParam);
}

 


觉得文章还不错?点击此处对作者进行打赏!


本文地址: 程序人生 >> Win32写的屏幕取色工具
作者:代码疯子(Wins0n) 本站内容如无声明均属原创,转载请保留作者信息与原文链接,谢谢!


更多



  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.