windows 图片验证码制作

版权声明:本文为博主原创文章,未经博主同意不可随意转载。 https://blog.csdn.net/hellokandy/article/details/82692070

在一些网站填写资料时,经常需要填写验证码,对于验证码的实现,其实C++也可以很方便:

1、首先,随机字符串的生成

2、验证码的显示,或者写入文件再加载显示

关键代码如下:

1、生成随机验证码

#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <atlimage.h>
using namespace std;

char *rand_str(char *str, const int len)
{
	srand(time(NULL));
	int i;
	for(i=0; i<len; ++i)
	{
		switch((rand()%3))
		{
		case 1:
			str[i]='A'+rand()%26;
			break;
		case 2:
			str[i]='a'+rand()%26;
			break;
		default:
			str[i]='0'+rand()%10;
			break;
		}
	}
	str[++i]='\0';
	return str;
}

//s2ws
wstring s2ws(const char* pStr, int len, unsigned int CodePage = CP_ACP)
{
	wstring buf;
	if(pStr == NULL || (len < 0 && len != -1))
	{
		return buf;
	}

	// figure out how many wide characters we are going to get 
	int nChars = MultiByteToWideChar( CodePage, 0, pStr, len, NULL, 0 ); 
	if ( len == -1 )
		--nChars; 
	if ( nChars == 0 )
		return L"";

	// convert the narrow string to a wide string 
	// nb: slightly naughty to write directly into the string like this
	buf.resize( nChars ); 
	MultiByteToWideChar( CodePage, 0, pStr, len, const_cast<wchar_t*>(buf.c_str()), nChars ); 

	return buf;
}

HBITMAP NewBitmap(HDC hdc, wchar_t *pszText, int iWidth, int iHeight)
{
	if (pszText == NULL)
		return NULL;

	//创建要返回的位图句柄,此处的hdc参数必须是与实际窗口绑定的DC,如果是内存DC则图片没有颜色只有灰度
	HBITMAP hBmp = CreateCompatibleBitmap(hdc, iWidth, iHeight);
	//创建与显示设备相关的内存设备上下文
	HDC hMemDC = CreateCompatibleDC(hdc);
	SelectObject(hMemDC, hBmp);

	//在位图上写字
	SetBkMode(hMemDC, TRANSPARENT);
	RECT rc = {0, 0, iWidth, iHeight};
	HBRUSH hb = ::CreateSolidBrush(RGB(0, 0, 0));//设置笔刷颜色
	FillRect(hMemDC, &rc, hb);//填充矩形

	HFONT hf;
	LOGFONT lf;//创建字体结构体
	lf.lfHeight = 30;
	lf.lfWidth = 10;
	lf.lfEscapement = 0;
	lf.lfOrientation = 0;
	lf.lfItalic = false;
	lf.lfUnderline = false;
	lf.lfStrikeOut = false;
	lf.lfCharSet = DEFAULT_CHARSET;
	lf.lfOutPrecision = 0;
	lf.lfWeight = 200;  //0-1000,1000加到最粗
	lf.lfClipPrecision = 0;
	lf.lfQuality = 0;
	lf.lfPitchAndFamily = 0;
	wcscpy_s(lf.lfFaceName, L"微软雅黑");//此处不能用strcpy
	hf = CreateFontIndirect(&lf);
	SelectObject(hMemDC, hf);
	SetTextColor(hMemDC, RGB(0,255,0));//设置字体颜色
	DrawText(hMemDC, pszText, -1, &rc, DT_CENTER|DT_VCENTER);//居中

	//释放资源
	DeleteDC(hMemDC);
	DeleteObject(hb);

	return hBmp; //返回创建好的位图
}

2、显示验证码,或者把验证码图片保存至本地

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// 分析菜单选择:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: 在此添加任意绘图代码...
		{
			char name[10] = {};
			rand_str(name, 8);
			int len = strlen(name);
			wstring wszStr = s2ws(name, len);

			int iWidth = 150, iHeight = 35;  
			HBITMAP hBmp = NewBitmap(hdc, const_cast<wchar_t*>(wszStr.c_str()), iWidth, iHeight);
			HDC hMemDC = CreateCompatibleDC(hdc);
			SelectObject(hMemDC, hBmp);
			BitBlt(hdc, 0, 0, iWidth, iHeight, hMemDC, 0, 0, SRCCOPY);
			DeleteDC(hMemDC);

			//保存图片
			CImage image;
			image.Attach(hBmp);//将位图转化为一般图像
			image.Save(L"testimg.bmp");//保存图像
			image.Detach();//结束绑定
		}

		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/hellokandy/article/details/82692070