经过网络上很多资料的参考,用SDK写出了一个时钟小程序。 还有很多细节的地方很时不理解。为什么要那样?找同学搞了一本<Windows程序设计>。好好研究一下SDK 。
时钟程序还有很多细节的地方不是很理解,及一些API。很多地方都是根据网络上的资料比猫画虎的。
时钟程序代码如下:
#include
<
math.h
>
#include
<
windows.h
>
#include
"
resource.h
"
LRESULT CALLBACK wndproc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
bool
DrawClockFace(HDC);
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
_stdcall WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int
nShowCmd )
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
WNDCLASS wndclass;
char classname[]="simplewindows";
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hbrBackground=(HBRUSH)(COLOR_3DFACE + 1);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon=LoadIcon(hInstance,(LPSTR)IDI_ICON2);
wndclass.hInstance=hInstance;
wndclass.lpfnWndProc=wndproc;
wndclass.lpszClassName=classname;
wndclass.lpszMenuName=(LPSTR)IDR_MENU1;
wndclass.style=CS_HREDRAW|CS_VREDRAW;
RegisterClass(&wndclass);
HWND hwnd;
hwnd=CreateWindow(
classname,
"一个简单的窗口",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
if (hwnd==NULL)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
MessageBox(NULL,"创建窗口出错","error",MB_OK);
return -1;
}
ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd);
MSG umsg;
while (GetMessage(&umsg,NULL,0,0))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
TranslateMessage(&umsg);
DispatchMessage(&umsg);
}
return umsg.wParam;
}
//
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
//
//
消息代码
#define
IDT_CLOCK 1
const
int
IDM_HELP
=
100
;
const
int
IDM_TOPMOST
=
101
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
实现函数
void
SetIsotropic(HDC hdc,
int
cxClient,
int
cyClient);
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
DrawHand(HDC hdc,
int
nLength,
int
nWidth,
int
nDegrees, COLORREF clrColor);
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
上一次Windows通知时的时间
static
int
s_nPreHour;
//
小时
static
int
s_nPreMinute;
//
分钟
static
int
s_nPreSecond;
//
秒
//
窗口客户区的大小
static
int
s_cxClient;
static
int
s_cyClient;
//
是否位于最顶层
static
BOOL s_bTopMost;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
LRESULT CALLBACK wndproc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
switch (uMsg)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
case WM_CREATE:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
SYSTEMTIME time;
// 设置时间
GetLocalTime(&time);
s_nPreHour=time.wHour%12;
s_nPreMinute=time.wMinute;
s_nPreSecond=time.wSecond;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 创建定时器
SetTimer(hwnd,IDT_CLOCK,1000,NULL);
return 0;
}
case WM_SIZE:
s_cxClient=LOWORD(lParam);
s_cyClient=HIWORD(lParam);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
break;
case WM_PAINT:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
HDC hdc;
PAINTSTRUCT ps;
RECT rt;
hdc=BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rt);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 用户加入话刷
HBRUSH hBr;
hBr=(HBRUSH)GetStockObject(BLACK_BRUSH);
SelectObject(hdc,hBr);
// 设置坐标系。
SetMapMode(hdc,MM_ISOTROPIC);
SetWindowExtEx(hdc,1000,1000,NULL);
SetViewportExtEx(hdc,s_cxClient,-s_cyClient,NULL);
SetViewportOrgEx(hdc,s_cxClient/2,s_cyClient/2,NULL);
// 绘制时钟的外观。
DrawClockFace(hdc);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 1小时走30度,经过1分钟,走0.5度
DrawHand(hdc,200,8,s_nPreHour*30+s_nPreMinute/2,RGB(0,0,0));
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 经过1分钟分针走6度
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
DrawHand(hdc,400,6,s_nPreMinute*6,RGB(0,0,0));
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 经过1秒钟秒针走了6度
DrawHand(hdc,400,1,s_nPreSecond*6,RGB(0,0,0));
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
DeleteObject(hBr);
EndPaint(hwnd,&ps);
return 0;
}
break;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
case WM_TIMER:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// 判断窗口处于最小化状态什么都不做
if (IsIconic(hwnd))
return 0;
SYSTEMTIME time;
GetLocalTime(&time);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 建立坐标系
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
HDC hdc;
hdc=GetDC(hwnd);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
SetMapMode(hdc,MM_ISOTROPIC);
SetWindowExtEx(hdc,1000,1000,NULL);
SetViewportExtEx(hdc,s_cxClient,-s_cyClient,NULL);
SetViewportOrgEx(hdc,s_cxClient/2,s_cyClient/2,NULL);
Ellipse(hdc,-20,20,20,-20);
//
// 以COLOR_3DFACE为背景色就可以擦除指针了(因为窗口的背景色也是COLOR_3DFACE)
COLORREF crfColor = ::GetSysColor(COLOR_3DFACE );
// 如果分钟改变的话就擦除时针和分针
if(time.wMinute != s_nPreMinute)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// 擦除时针和分针
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)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// 擦除秒针
DrawHand(hdc, 400, 1, s_nPreSecond*6, crfColor);
// 重画所有指针
DrawHand(hdc, 400, 1, time.wSecond*6, RGB(0, 0, 0));
DrawHand(hdc, 200, 8, time.wHour*30 + time.wMinute/2, RGB(0, 0, 0));
DrawHand(hdc, 400, 6, time.wMinute*6, RGB(0, 0, 0));
s_nPreSecond = time.wSecond;
}
return 0;
ReleaseDC(hwnd,hdc);
break;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
case WM_CLOSE:
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
::KillTimer(hwnd,IDT_CLOCK);
DestroyWindow(hwnd);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
case WM_COMMAND:
switch (LOWORD(wParam))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
case IDF_EIXT:
SendMessage(hwnd,WM_CLOSE,0,0);
break;
case IDF_ABOUT:
MessageBox(NULL,"thorwein's clock V1.0.........Thorwein@hotmail.com","About!!!",MB_OK);
break;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
//
//
绘制时钟基本框架外观函数DrawClockFace();
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
bool
DrawClockFace(HDC hdc)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
CONST int SQUARESIZE=20;
static POINT pt[]=
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
0, 450, // 12点
225, 390, // 1点
390, 225, // 2点
450, 0, // 3点
390, -225, // 下面的坐标是上面的点的对称点(以X轴、Y轴或原点对称)
225, -390,
0, -450,
-225, -390,
-390, -225,
-450, 0,
-390, 225,
-225, 390
};
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
for (int i=0;i<12;i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
Ellipse(hdc,pt[i].x-SQUARESIZE,pt[i].y+SQUARESIZE,pt[i].x + SQUARESIZE, pt[i].y - SQUARESIZE);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
//
//
绘画时钟指针的函数DrawHand;
//
nLength 长度 nWidth宽度 nDegrees 相对于0的偏移角度。 clrColor
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
DrawHand(HDC hdc,
int
nLength,
int
nWidth,
int
nDegrees, COLORREF clrColor)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
double nRadians=(double)nDegrees*0.0174533;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 计算坐标
POINT pt[2];
pt[0].x=(int)(sin(nRadians)*nLength);
pt[0].y=(int)(cos(nRadians)*nLength);
pt[1].x=-pt[0].x/5;
pt[1].y=-pt[0].y/5;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 创建笔刷,并放入DC中
HPEN hpen=::CreatePen(PS_SOLID,nWidth,clrColor);
SelectObject(hdc,hpen);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 画线
MoveToEx(hdc,pt[0].x,pt[0].y,NULL);
LineTo(hdc,pt[1].x,pt[1].y);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
DeleteObject(hpen);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
有什么地方不对的。希望大家多多指教!!! 谢谢