kehuadong

字符动态切换效果

#include <Windows.h>

#include <stdlib.h>

#include <vector>
#include <thread>
#include <mutex>
using namespace std;

struct SDisplay {
	int			Width;
	int			Height;
	HDC			OffScreenDC;
	HBITMAP		OffScreenBMP;
	HBRUSH		BlackBrush;
	HBRUSH		WhiteBrush;
	HRGN		CharRgn;
	HFONT		CharFont;
};

struct AnimationChar {
	char Last;
	char Current;
	char Next;
	uint8_t Step;
};

void AnimationCharProc(AnimationChar* AC) {
	if (AC->Step) {
		AC->Step++;
		if (AC->Step == 216) {
			AC->Step = 0;
			AC->Last = AC->Current;
		}
	} else if (AC->Current != AC->Next) {
		AC->Last = AC->Current;
		AC->Current = AC->Next;
		AC->Step = 1;
	}
}


static struct {
	SDisplay	Display;
} _G;

AnimationChar AC[8];

static void _DoPaint() {
	SDisplay& D = _G.Display;
	HDC& hdc = D.OffScreenDC;
	int w = D.Width;
	int h = D.Height;
	// uint8_t 

	
	SelectObject(hdc, D.WhiteBrush);
	Rectangle(hdc, 0, 0, w, h);	

	SelectClipRgn(hdc, D.CharRgn);

	SYSTEMTIME t;
	GetSystemTime(&t);
	char buffer[9];
	snprintf(buffer, 9, "%02d:%02d:%02d", (t.wHour+8)%24, t.wMinute, t.wSecond);

	uint16_t x[] = { 10, 50, 90, 120, 160, 200, 230, 270};

	for (int i = 0; i < 8; i++) {		
		TCHAR last[2] = { AC[i].Last};
		TCHAR current[2] = { AC[i].Current};
		SelectObject(hdc, D.CharFont);

		TextOut(hdc, x[i], 14 - AC[i].Step / 3, last, DT_CENTER);
		TextOut(hdc, x[i], 86 - AC[i].Step / 3, current, DT_CENTER);

		AC[i].Next = buffer[i];
		AnimationCharProc(&AC[i]);
	}
}

static void _OnPaint(HWND hWnd) {
	PAINTSTRUCT ps;
	BeginPaint(hWnd, &ps);

	RECT rc;
	GetClientRect(hWnd, &rc);
	int w = rc.right - rc.left;
	int h = rc.bottom - rc.top;

	SDisplay& d = _G.Display;
	HDC& hdc = d.OffScreenDC;
	HBITMAP& hbmp = d.OffScreenBMP;
	if (d.Width != w || d.Height != h) {
		d.Width = w;
		d.Height = h;
		if (hdc == NULL) {
			hdc = CreateCompatibleDC(ps.hdc);
		}
		HBITMAP newBmp = CreateCompatibleBitmap(hdc, w, h);
		HBITMAP oldBmp = (HBITMAP)SelectObject(hdc, newBmp);
		if (hbmp && hbmp == oldBmp) {
			DeleteObject(hbmp);
		}
		hbmp = newBmp;
	}

	_DoPaint();

	BitBlt(ps.hdc, 0, 0, w, h, hdc, 0, 0, SRCCOPY);
	EndPaint(hWnd, &ps);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	switch (uMsg) {
	case WM_PAINT:
		_OnPaint(hWnd);
		//printf("WM_PAINT\n");		
		InvalidateRect(hWnd, NULL, false);
		break;

	case WM_DESTROY:
		PostQuitMessage(0);
		break;

	default:
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	return 0;
}

static const wchar_t* _GetWindowClassName() {
	return L"SpectrumWindow";
}

static void _InitWindowClass() {
	WNDCLASS wc = { 0 };
	wc.lpfnWndProc = WndProc;
	wc.hInstance = GetModuleHandle(NULL);
	wc.lpszClassName = _GetWindowClassName();
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	RegisterClass(&wc);
}

static void _CreateFont() {
	LOGFONT lf = { 0 };
	lf.lfHeight = 72;
	lf.lfWeight = 900;	
	lf.lfCharSet = DEFAULT_CHARSET;
	lstrcpy(lf.lfFaceName, TEXT("楷体"));
	_G.Display.CharFont = CreateFontIndirect(&lf);
}

int main() {
	_InitWindowClass();

	_G.Display.BlackBrush = CreateSolidBrush(RGB(0, 0, 0));
	_G.Display.WhiteBrush = CreateSolidBrush(RGB(255, 255, 255));
	_G.Display.CharRgn = CreateRectRgn(10, 14, 410, 86);
	_CreateFont();

	HWND hWnd = CreateWindow(_GetWindowClassName(), L"动态数字", WS_OVERLAPPEDWINDOW,
		0, 0, 1024, 600, NULL, NULL, GetModuleHandle(NULL), NULL);
	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);


	MSG msg = { 0 };
	while (GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
}

 

posted on 2023-03-20 20:30  kehuadong  阅读(10)  评论(0编辑  收藏  举报

导航