字符雨

时间:2025-03-03 07:55:00
/******************************
字符雨,说实话,没数字雨好看,改自旓旓发的黑客帝国--数字雨!!
编译方法: 
******************************/
#define UNICODE
#include <>
#include <string>
#include <vector>
#include <algorithm>
#pragma comment(lib, "")
#pragma comment(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};
	 = CS_HREDRAW | CS_VREDRAW;
	 = WndProc;
	 = hInstance;
	 = LoadIcon(NULL, IDI_APPLICATION);
	 = LoadCursor(NULL, IDC_ARROW);
	 = (HBRUSH)GetStockObject(BLACK_BRUSH);
	 = 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 ;
}

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);
		(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].()+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((), (), [](COLUMN& col){
			++;
			SetTextColor(dcMem, RGB(255,255,255));
			//画第一个字符
			TextOut(dcMem, , , &[0], 1);
			int len =  - ();
			//画其它字符
			for(int i = 1; i < len; i++){
				SetTextColor(dcMem, RGB(0, 255-i*255/len, 0));
				TextOut(dcMem, ,  - i*(FontHeight + 5), &[i], 1);
			}
			//用于控制速度,达到阈值则下落
			if( >= ){
				 += FontHeight;
				 = 0;
				if( != ())
					++;
			}
			//全部离开屏幕后从新生成数据
			if( > cyScreen + FontHeight*()){
				 = g_Contents[rand()%(sizeof(g_Contents)/sizeof(g_Contents[0]))];
				 = ()+1;
				 = 0;
				 = rand()% SPEED + 1;
				 = 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);
}