共有回帖数 0 个
-
指针式的时钟,表盘为椭圆形,大小可以可变。
花了一些时间设计程序,花了更多的时间研究椭圆与直线交点、根据时间获取指针位置(用到三角函数)等数学问题。
总算完成了,但表盘上12个数字的显示还不是很完善。
源代码:http://hi.baidu.com/masterray/blog/item/5ac05660955a5641eaf8f830.html
#include math.h
#include windows.h
#define ID_TIMER 1000
#define PI 3.14159265359
#define FONT_HEIGHT 18
#define FONT_WIDTH 9
const char *g_szCaption = "时钟(指针式)"; //标题
const char *g_szClassName = "MasterRay"; //类名
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HDC hDC;
static HPEN hBlackPen = CreatePen(PS_SOLID, 5, RGB(0,0,0)),
hRedPen = CreatePen(PS_SOLID, 5, RGB(255,0,0)),
hGreenPen = CreatePen(PS_SOLID, 3, RGB(0,255,0)),
hBluePen = CreatePen(PS_SOLID, 2, RGB(0,0,255));
static LOGFONTA LogFont={FONT_HEIGHT, FONT_WIDTH, 0, 0, 1000, 0, 0, 0, 0, 0, 0, 0, 0, "宋体"};
static HFONT hFont = CreateFontIndirectA(&LogFont);
static PAINTSTRUCT ps;
static RECT rect;
static int long_axis, short_axis, //椭圆长、短半轴的长度
x, y;
static SYSTEMTIME systemtime;
switch (msg)
{
case WM_TIMER:
InvalidateRect(hWnd, &rect, FALSE);
return 0;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
//获取本地时间
GetLocalTime(&systemtime);
if (systemtime.wHour 12)
systemtime.wHour -= 12;
x = (rect.right-rect.left) / 2;
y = (rect.bottom-rect.top) / 2;
//表盘
SelectObject(hDC, hBlackPen);
Ellipse(hDC, 10, 10, rect.right - 10, rect.bottom - 10);
//1~12
{
double k[] = {sqrt(3.), 0.5, 0, -0.5, -sqrt(3.)};
char numbers[] = "5 4 3 2 1 7 8 9 1011";
for (int i=0; i=4; ++i)
{
SelectObject(hDC, hFont);
TextOutA(hDC, x+1./sqrt(1./(x*x)+k*k/(y*y)) - FONT_WIDTH * 1.5,
y+k/sqrt(1./(x*x)+k*k/(y*y)) - FONT_HEIGHT/2,
&numbers[i*2], 1);
TextOutA(hDC, x-1./sqrt(1./(x*x)+k*k/(y*y)) + FONT_WIDTH/2,
y-k/sqrt(1./(x*x)+k*k/(y*y)) - FONT_HEIGHT/2,
&numbers[(9-i)*2], i2?2:1);
}
TextOutA(hDC, x - FONT_WIDTH * 1.5, 10 - FONT_HEIGHT * 0.5,
"12", 2);
TextOutA(hDC, x - FONT_WIDTH * 1.5, rect.bottom - FONT_HEIGHT * 0.75,
"6", 1);
}
//指针
SelectObject(hDC, hRedPen);
MoveToEx(hDC, x, y, NULL);
LineTo(hDC, x+(short_axis*0.5)*sin((systemtime.wHour+systemtime.wMinute/60.)*PI/6.),
y-(short_axis*0.5)*cos((systemtime.wHour+systemtime.wMinute/60.)*PI/6.));
SelectObject(hDC, hGreenPen);
MoveToEx(hDC, x, y, NULL);
LineTo(hDC, x+(short_axis*0.7)*sin((systemtime.wMinute+systemtime.wSecond/60.)*PI/30.),
y-(short_axis*0.7)*cos((systemtime.wMinute+systemtime.wSecond/60.)*PI/30.));
SelectObject(hDC, hBluePen);
MoveToEx(hDC, x, y, NULL);
LineTo(hDC, x+(short_axis*0.9)*sin(systemtime.wSecond*PI/30.),
y-(short_axis*0.9)*cos(systemtime.wSecond*PI/30.));
EndPaint(hWnd, &ps);
return 0;
case WM_SIZE:
GetClientRect(hWnd, &rect);
if (rect.right-rect.left rect.bottom-rect.top)
{
long_axis = (rect.bottom-rect.top) / 2;
short_axis = (rect.right-rect.left) / 2;
}
else
{
short_axis = (rect.bottom-rect.top) / 2;
long_axis = (rect.right-rect.left) / 2;
}
InvalidateRect(hWnd, &rect, FALSE);
return 0;
case WM_CREATE:
SelectObject(hDC, hFont);
return 0;
case WM_DESTROY:
DeleteObject(hBlackPen);
DeleteObject(hRedPen);
DeleteObject(hGreenPen);
DeleteObject(hBluePen);
DeleteObject(hFont);
PostQuitMessage(0);
return 0;
}
return DefWindowProcA(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSA wc;
HWND hWnd;
MSG msg;
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
if (!RegisterClassA(&wc))
return 0;
hWnd = CreateWindowA(g_szClassName, g_szCaption, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, NULL, NULL, hInstance, NULL);
if (hWnd == NULL)
return 0;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
SetTimer(hWnd, ID_TIMER, 500, NULL);
while (GetMessageA(&msg, NULL, 0, 0) 0)
{
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
return msg.wParam;
}
楼主 2016-01-15 16:38 回复
Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号
意见反馈 |
关于直线 |
版权声明 |
会员须知