///////////////////////////////////////////////////////////////
// SineWave.cpp文件
#include <windows.h>
#include <math.h>
#include <stdio.h>
LRESULT __stdcall WndProc(HWND, UINT, WPARAM, LPARAM);
//void OnPaint(HWND hwnd);
void DrawHand(HDC hdc,int nLength,int nWidth,int nDegrees,COLORREF clrColor);
void SetIsotropic(HWND hwnd,HDC hdc,int s_cxClient,int s_cyClient);
void DrawClockFace(HDC hdc);
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
char szWindowClass[] = "SineWave";
// 注册窗口类
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = NULL;
::RegisterClassEx(&wcex);
// 创建并线程主窗口
HWND hWnd = ::CreateWindowEx(
WS_EX_CLIENTEDGE, // 扩展样式
szWindowClass, // 类名
"电子钟", // 标题
WS_OVERLAPPEDWINDOW, // 窗口样式
CW_USEDEFAULT, // 初始 X 坐标
CW_USEDEFAULT, // 初始 X 坐标
CW_USEDEFAULT, // 宽度
CW_USEDEFAULT, // 高度
NULL, // 父窗口句柄
NULL, // 菜单句柄
hInstance, // 程序实例句柄
NULL);
::ShowWindow(hWnd, nShowCmd);
::UpdateWindow(hWnd);
// 进入消息循环
MSG msg;
while(::GetMessage(&msg, NULL, 0, 0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return 1;
}
// 消息处理函数 // 03SineWave工程下
LRESULT __stdcall WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
#define IDT_CLOCK 1
static int s_nPreHour;
static int s_nPreMinute;
static int s_nPreSecond;
static int s_cxClient;
static int s_cyClient;
switch(message)
{
case WM_CREATE:
{
SYSTEMTIME time;
//设置时间
::GetLocalTime(&time);
s_nPreHour=time.wHour%12;
s_nPreMinute=time.wMinute;
s_nPreSecond=time.wSecond;
//创建定时器
::SetTimer(hwnd,IDT_CLOCK,1000,NULL);
return 0;
}
case WM_CLOSE:
{
::KillTimer(hwnd,IDT_CLOCK);
::DestroyWindow(hwnd);
return 0;
}
case WM_SIZE:
{
s_cxClient=LOWORD(lParam);
s_cyClient=HIWORD(lParam);
return 0;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc=::BeginPaint(hwnd,&ps);
//设置坐标系
SetIsotropic(hwnd,hdc,s_cxClient,s_cyClient);
//绘制时钟外观
DrawClockFace(hdc);
//绘制指针
//经过一个小时时针走30度(360/12),经过一分钟时针走0.5度(30/60)
DrawHand(hdc,200,8,s_nPreHour*30+s_nPreMinute/2,RGB(0,0,0));
DrawHand(hdc,400,6,s_nPreMinute*6,RGB(0,0,255));
DrawHand(hdc,400,1,s_nPreSecond*6,RGB(255,0,0));
SYSTEMTIME time;
//设置时间
::GetLocalTime(&time);
//int szchar=time.wYear;
::TextOut(hdc,0,100,"2009",strlen("2009"));
::EndPaint(hwnd,&ps);
break;
}
case WM_TIMER:
{
if(::IsIconic(hwnd))
{
return 0;
}
//取得系统时间
SYSTEMTIME time;
::GetLocalTime(&time);
//建立坐标系
HDC hdc=::GetDC(hwnd);
SetIsotropic(hwnd,hdc,s_cxClient,s_cyClient);
COLORREF crfColor=::GetSysColor(COLOR_3DFACE);
if(time.wMinute!=s_nPreMinute)
{
DrawHand(hdc,200,8,s_nPreHour*30+s_nPreMinute/2,crfColor);
DrawHand(hdc,400,6,s_nPreMinute*6,crfColor);
s_nPreHour=time.wHour;
s_nPreMinute=time.wMinute;
}
if(time.wSecond!=s_nPreSecond)
{
DrawHand(hdc,400,1,s_nPreSecond*6,crfColor);
//重画所有指针
DrawHand(hdc,400,1,time.wSecond*6,RGB(255,0,0));
DrawHand(hdc,200,8,time.wHour*30+time.wMinute/2,RGB(0,255,0));
DrawHand(hdc,400,6,time.wMinute*6,RGB(0,0,255));
s_nPreSecond=time.wSecond;
}
break;
}
}
return::DefWindowProc(hwnd, message, wParam, lParam);
}
void DrawHand(HDC hdc,int nLength,int nWidth,int nDegrees,COLORREF clrColor)
{
double nRadians=(double)nDegrees*0.0174533;//将角度转化为弧度
POINT pt[2];//计算坐标
pt[0].x=(int)(nLength*sin(nRadians));
pt[0].y=(int)(nLength*cos(nRadians));
pt[1].x=-pt[0].x/5;
pt[1].y=-pt[0].y/5;
//创建画笔,并加到DC结构中
HPEN hPen=::CreatePen(PS_SOLID,nWidth,clrColor);
HPEN oldHpen=(HPEN)::SelectObject(hdc,hPen);
::MoveToEx(hdc,pt[0].x,pt[0].y,NULL);
::LineTo(hdc,pt[1].x,pt[1].y);
::SelectObject(hdc,oldHpen);
::DeleteObject(hPen);
}
void SetIsotropic(HWND hwnd,HDC hdc,int cx,int cy)
{
::SetMapMode(hdc,MM_ISOTROPIC);
::SetWindowExtEx(hdc,1000,1000,NULL);
::SetViewportExtEx(hdc,cx,-cy,NULL);
::SetViewportOrgEx(hdc,cx/2,cy/2,NULL);
}
void DrawClockFace(HDC hdc)
{
const int SQUARESIZE=20;
static POINT pt[]=
{
0,450,
225,390,
390,225,
450,0,
390,-225,
225,-390,
0,-450,
-225,-390,
-390,-225,
-450,0,
-390,225,
-225,390
};
//选择一个黑色画刷
::SelectObject(hdc,::GetStockObject(BLACK_BRUSH));
//画十二个圆
for (int i=0;i<12;i++)
{
::Ellipse(hdc,pt[i].x-SQUARESIZE,pt[i].y+SQUARESIZE,
pt[i].x+SQUARESIZE,pt[i].y-SQUARESIZE);
}
}