字符雨

转载自:http://blog.csdn.net/x313695373/article/details/11661043


/******************************
字符雨,说实话,没数字雨好看,改自旓旓发的黑客帝国--数字雨!!
编译方法:cl.exe NumberRain.cpp
******************************/
#define UNICODE
#include <Windows.h>
#include <string>
#include <vector>
#include <algorithm>
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "user32.lib")
//以上是为了在控制台下编译不用加额外的参数,否则会链接错误
using namespace std;
#define ID_TIMER 1
#define INTERVAL 13
#define SPEED  17
//要显示的内容加的这里,可以放你媳妇的名字之类的
wchar_t *g_Contents[] = {
	L"一辈子的幸福给你", L"生日快乐", L"还是生日快乐", L"祝生日快乐",
	L"日月轮转永不断", L"情苦真挚长相伴", L"不论你身在天涯海角", L"我将永远记住这一天",
	L"祝生日快乐",
	L"我特别珍视其中的一天", L"祝愿你在这天美梦都能实现",
	L"因为你一向这样聪明可爱", L"又这样叫人牵肠挂肚", L"所以这份祝福非你莫属",
};
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


typedef struct TagCOLUMN{
	wstring Contents;//显示的内容
	wstring::iterator EndIt;//刚刚出现时只显示前面几个字符
	int x, y;//显示的位置
	int StopTimes, MaxStopTimers;//控制下降的速度
}COLUMN;

int WINAPI wWinMain(
	__in HINSTANCE hInstance,
	__in_opt HINSTANCE hPrevInstance,
	__in wchar_t* lpCmdLine,
	__in int nShowCmd
	)
{
	static wchar_t szAppName[] =L"Matrix";
	HWND hwnd;
	MSG msg;
	WNDCLASS wndclass = {0};
	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc = WndProc;
	wndclass.hInstance = hInstance;
	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wndclass.lpszClassName = szAppName;

	if(!RegisterClass(&wndclass)){
		MessageBox(NULL, L"must run under NT", szAppName, MB_ICONERROR);
		return 0;
	}
	hwnd = CreateWindow(
		szAppName, NULL,
		WS_DLGFRAME|WS_THICKFRAME|WS_POPUP,
		0, 0, 
		GetSystemMetrics(SM_CXSCREEN),
		GetSystemMetrics(SM_CYSCREEN),
		NULL, NULL, hInstance, NULL);
	ShowWindow(hwnd, SW_SHOWMAXIMIZED);
	UpdateWindow(hwnd);
	ShowCursor(FALSE);

	srand(GetCurrentTime());
	while(GetMessage(&msg, NULL, 0, 0)){
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	ShowCursor(TRUE);
	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;
	int i, j, tmp;
	static HDC dcMem;
	static HFONT hFont;
	static HBITMAP hBitmap;
	static int cxScreen, cyScreen;
	static int FontWidth = 10, FontHeight = 15;
	static vector<COLUMN> columns;

	switch(message){
	case WM_CREATE:
		cxScreen = GetSystemMetrics(SM_CXSCREEN);
		cyScreen = GetSystemMetrics(SM_CYSCREEN);
		hdc = GetDC(hwnd);
		dcMem = CreateCompatibleDC(hdc);
		hBitmap = CreateCompatibleBitmap(hdc, cxScreen, cyScreen);
		SelectObject(dcMem, hBitmap);
		ReleaseDC(hwnd, hdc);
		hFont = CreateFont(FontHeight, FontWidth, 0, 0, FW_BOLD,
			0, 0, 0,
			DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
			CLIP_DEFAULT_PRECIS,
			DRAFT_QUALITY, FIXED_PITCH|FF_SWISS,
			L"Fixedsys");
		SelectObject(dcMem, hFont);
		SetBkMode(dcMem, TRANSPARENT);
		tmp = cxScreen/(FontWidth*1.5);
		columns.assign(tmp, COLUMN());
		for(i = 0; i < tmp; i++){
			columns[i].Contents = g_Contents[rand()%(sizeof(g_Contents)/sizeof(g_Contents[0]))];
			columns[i].EndIt = columns[i].Contents.begin()+1;
			columns[i].StopTimes = 0;
			columns[i].MaxStopTimers = rand()%SPEED + 1;
			columns[i].x = i*FontWidth*1.5;
			columns[i].y = rand()%(cyScreen/2);
		}
		SetTimer(hwnd, ID_TIMER, INTERVAL, NULL);
		return 0;
	case WM_TIMER:
		hdc = GetDC(hwnd);
		PatBlt(dcMem, 0, 0, cxScreen, cyScreen, BLACKNESS);//draw the background
		//依次画每一列
		for_each(columns.begin(), columns.end(), [](COLUMN& col){
			col.StopTimes++;
			SetTextColor(dcMem, RGB(255,255,255));
			//画第一个字符
			TextOut(dcMem, col.x, col.y, &col.Contents[0], 1);
			int len = col.EndIt - col.Contents.begin();
			//画其它字符
			for(int i = 1; i < len; i++){
				SetTextColor(dcMem, RGB(0, 255-i*255/len, 0));
				TextOut(dcMem, col.x, col.y - i*(FontHeight + 5), &col.Contents[i], 1);
			}
			//用于控制速度,达到阈值则下落
			if(col.StopTimes >= col.MaxStopTimers){
				col.y += FontHeight;
				col.StopTimes = 0;
				if(col.EndIt != col.Contents.end())
					++col.EndIt;
			}
			//全部离开屏幕后从新生成数据
			if(col.y > cyScreen + FontHeight*col.Contents.size()){
				col.Contents = g_Contents[rand()%(sizeof(g_Contents)/sizeof(g_Contents[0]))];
				col.EndIt = col.Contents.begin()+1;
				col.StopTimes = 0;
				col.MaxStopTimers = rand()% SPEED + 1;
				col.y = rand()%3?0:rand()%(cyScreen/2);
			}
		});
		BitBlt(hdc, 0, 0, cxScreen, cyScreen, dcMem, 0, 0, SRCCOPY);
		ReleaseDC(hwnd, hdc);
		return 0;
	case WM_RBUTTONDOWN:
		KillTimer(hwnd, ID_TIMER);
		return 0;
	case WM_RBUTTONUP:
		SetTimer(hwnd, ID_TIMER, INTERVAL, NULL);
		return 0;
	case WM_KEYDOWN:
	case WM_LBUTTONDOWN:
	case WM_DESTROY:
		KillTimer(hwnd, ID_TIMER);
		DeleteObject(dcMem);
		DeleteObject(hBitmap);
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值