46模拟时钟程序

模拟时钟:

/*---------------------------------------------------------
	s046.c---a daily practice
	046.c	WIN32 API 每日一练
	第46个例子:模拟时钟
	RotatePoint 函数顺时针旋转
	SetIsotropic 函数---设置视窗参数
	DrwaClock 函数---画时钟
	DrawHands函数---画指针
	 2023 7.8
-----------------------------------------------------------*/

#include<Windows.h>
#include<math.h>

#define ID_TIMER 1
#define TWOPI (2*3.14159)

LRESULT  CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
	PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[] = TEXT("Clock");//移植你更改的地方
	HWND hwnd;
	MSG msg;
	WNDCLASS wndclass;

	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc = WndProc;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = hinstance;
	wndclass.hIcon = NULL;
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = szAppName;

	if (!RegisterClass(&wndclass))
	{
		MessageBox(NULL, TEXT("this program requires Windows NT!"),
			szAppName, MB_ICONERROR);
		return 0;
	}

	hwnd = CreateWindow(szAppName, TEXT("Analog Clock"),//更新
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, NULL, hinstance, NULL);

	ShowWindow(hwnd, iCmdShow);
	UpdateWindow(hwnd);

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

//设置视窗参数
void SetIsotropic(HDC hdc, int cxClient, int cyClient)
{
	SetMapMode(hdc, MM_ISOTROPIC);								//映射模式等比例缩放
	SetWindowExtEx(hdc, 1000, 1000, NULL);						//指定的值设置窗口设备上下文的水平和垂直范围
	SetViewportExtEx(hdc, cxClient / 2, -cyClient / 2, NULL);	//使用指定的值设置为视口设倍
	SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);	//设置视口原点
}


//顺时针旋转		公式:	x=x*cos(a)+y*sin(a);y=y*cos(a)-x*sin(a);
void RotatePoint(POINT pt[], int iNum, int iAngle)
{
	int i;
	POINT ptTemp;

	for (i = 0; i < iNum; i++)
	{
		ptTemp.x = (int)(pt[i].x * cos(TWOPI * iAngle / 360) + 
			pt[i].y * sin(TWOPI * iAngle / 360));

		ptTemp.y = (int)(pt[i].y * cos(TWOPI * iAngle / 360) - 
			pt[i].x * sin(TWOPI * iAngle / 360));

		pt[i] = ptTemp;
	}
}

//画时钟的刻度
void DrawClock(HDC hdc)
{
	int iAngle;
	POINT pt[3];

	for (iAngle = 0; iAngle < 360; iAngle += 6)
	{
		pt[0].x = 0;
		pt[0].y = 900;
		RotatePoint(pt, 1, iAngle);

		pt[2].x = pt[2].y = iAngle % 5 ? 33 : 100;//圆的大小(直径)

		//Ellipse左上角的矩形坐标点
		pt[0].x -= pt[2].x / 2;
		pt[0].y -= pt[2].y / 2;

		//Ellipse右下角的矩形坐标点
		pt[1].x = pt[0].x + pt[2].x;
		pt[1].y = pt[0].y + pt[2].y;

		//选黑色画刷
		SelectObject(hdc, GetStockObject(BLACK_BRUSH));

		//绘制椭圆
		Ellipse(hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);
	}
}


//画指针
void DrawHands(HDC hdc, SYSTEMTIME* pst, BOOL fChang)
{
	static POINT pt[3][5] = {
		0,	-150,	100,	0,	0,	600,	-100,	0,	0,	-150,//时针
		0,	-200,	50,		0,	0,	800,	-50,	0,	0,	-200,//分针
		0,	0,		0,		0,	0,	0,		0,		0,	0,	800//秒针
	};

	int i, iAngle[3];
	POINT ptTemp[3][5];

	iAngle[0] = (pst->wHour * 30) % 360 + pst->wMinute / 2;//时针每小时30度
	iAngle[1] = pst->wMinute * 6;//每分钟,分钟走6度。
	iAngle[2] = pst->wSecond * 6;//每分,秒针走6度。

	memcpy(ptTemp, pt, sizeof(pt));
	//判断是否只画秒针0-1-2或者2
	for (i = fChang ? 0 : 2; i < 3; i++)
	{
		RotatePoint(ptTemp[i], 5, iAngle[i]);

		Polyline(hdc, ptTemp[i], 5);
	}
}
LRESULT  CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static int cxClient, cyClient;
	static SYSTEMTIME stPrevious;
	BOOL fChange;
	HDC hdc;
	PAINTSTRUCT ps;
	SYSTEMTIME st;

	switch (message)
	{
	case WM_CREATE:
		SetTimer(hwnd, ID_TIMER, 1000, NULL);
		GetLocalTime(&st);
		stPrevious = st;
		return 0;

	case WM_SIZE:
		cxClient = LOWORD(lParam);
		cyClient = HIWORD(lParam);
		
		return 0; 

	case WM_TIMER:
		GetLocalTime(&st);
		fChange =	st.wHour != stPrevious.wHour || 
					st.wMinute != stPrevious.wMinute;

		hdc = GetDC(hwnd);
		//设置窗口参数
		SetIsotropic(hdc, cxClient, cyClient);
		//选入白色画刷
		SelectObject(hdc, GetStockObject(WHITE_PEN));
		DrawHands(hdc, &stPrevious, fChange);//画指针--擦除指针
		//选入黑色画刷
		SelectObject(hdc, GetStockObject(BLACK_PEN));
		DrawHands(hdc, &st, TRUE);//画指针--重绘

		ReleaseDC(hwnd, hdc);

		stPrevious = st;

		return 0;

	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);
		//设置窗口参数
		SetIsotropic(hdc, cxClient, cyClient);
		DrawClock(hdc);//画刻度原点
		DrawHands(hdc, &stPrevious, TRUE);//画时针,分针,秒针

		EndPaint(hwnd, &ps);
		return 0;

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

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




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值