经过网络上很多资料的参考,用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);
int _stdcall WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
... {
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)
...{
MessageBox(NULL,"创建窗口出错","error",MB_OK);
return -1;
}
ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd);
MSG umsg;
while (GetMessage(&umsg,NULL,0,0))
...{
TranslateMessage(&umsg);
DispatchMessage(&umsg);
}
return umsg.wParam;
}
//
/**/ //
// 消息代码
#define IDT_CLOCK 1
const int IDM_HELP = 100 ;
const int IDM_TOPMOST = 101 ;
// 实现函数
void SetIsotropic(HDC hdc, int cxClient, int cyClient);
void DrawHand(HDC hdc, int nLength, int nWidth, int nDegrees, COLORREF clrColor);
// 上一次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;
LRESULT CALLBACK wndproc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
... {
switch (uMsg)
...{
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_SIZE:
s_cxClient=LOWORD(lParam);
s_cyClient=HIWORD(lParam);
break;
case WM_PAINT:
...{
HDC hdc;
PAINTSTRUCT ps;
RECT rt;
hdc=BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rt);
// 用户加入话刷
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);
// 1小时走30度,经过1分钟,走0.5度
DrawHand(hdc,200,8,s_nPreHour*30+s_nPreMinute/2,RGB(0,0,0));
// 经过1分钟分针走6度
DrawHand(hdc,400,6,s_nPreMinute*6,RGB(0,0,0));
// 经过1秒钟秒针走了6度
DrawHand(hdc,400,1,s_nPreSecond*6,RGB(0,0,0));
DeleteObject(hBr);
EndPaint(hwnd,&ps);
return 0;
}
break;
case WM_TIMER:
...{
// 判断窗口处于最小化状态什么都不做
if (IsIconic(hwnd))
return 0;
SYSTEMTIME time;
GetLocalTime(&time);
// 建立坐标系
HDC hdc;
hdc=GetDC(hwnd);
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)
...{
// 擦除时针和分针
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(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;
}
case WM_CLOSE:
...{
::KillTimer(hwnd,IDT_CLOCK);
DestroyWindow(hwnd);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_COMMAND:
switch (LOWORD(wParam))
...{
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;
}
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
/**/ //
// 绘制时钟基本框架外观函数DrawClockFace();
bool DrawClockFace(HDC hdc)
... {
CONST int SQUARESIZE=20;
static POINT pt[]=
...{
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
};
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);
}
return 0;
}
/**/ //
// 绘画时钟指针的函数DrawHand;
// nLength 长度 nWidth宽度 nDegrees 相对于0的偏移角度。 clrColor
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)(sin(nRadians)*nLength);
pt[0].y=(int)(cos(nRadians)*nLength);
pt[1].x=-pt[0].x/5;
pt[1].y=-pt[0].y/5;
// 创建笔刷,并放入DC中
HPEN hpen=::CreatePen(PS_SOLID,nWidth,clrColor);
SelectObject(hdc,hpen);
// 画线
MoveToEx(hdc,pt[0].x,pt[0].y,NULL);
LineTo(hdc,pt[1].x,pt[1].y);
DeleteObject(hpen);
}
#include < windows.h >
#include " resource.h "
LRESULT CALLBACK wndproc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
bool DrawClockFace(HDC);
int _stdcall WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
... {
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)
...{
MessageBox(NULL,"创建窗口出错","error",MB_OK);
return -1;
}
ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd);
MSG umsg;
while (GetMessage(&umsg,NULL,0,0))
...{
TranslateMessage(&umsg);
DispatchMessage(&umsg);
}
return umsg.wParam;
}
//
/**/ //
// 消息代码
#define IDT_CLOCK 1
const int IDM_HELP = 100 ;
const int IDM_TOPMOST = 101 ;
// 实现函数
void SetIsotropic(HDC hdc, int cxClient, int cyClient);
void DrawHand(HDC hdc, int nLength, int nWidth, int nDegrees, COLORREF clrColor);
// 上一次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;
LRESULT CALLBACK wndproc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
... {
switch (uMsg)
...{
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_SIZE:
s_cxClient=LOWORD(lParam);
s_cyClient=HIWORD(lParam);
break;
case WM_PAINT:
...{
HDC hdc;
PAINTSTRUCT ps;
RECT rt;
hdc=BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rt);
// 用户加入话刷
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);
// 1小时走30度,经过1分钟,走0.5度
DrawHand(hdc,200,8,s_nPreHour*30+s_nPreMinute/2,RGB(0,0,0));
// 经过1分钟分针走6度
DrawHand(hdc,400,6,s_nPreMinute*6,RGB(0,0,0));
// 经过1秒钟秒针走了6度
DrawHand(hdc,400,1,s_nPreSecond*6,RGB(0,0,0));
DeleteObject(hBr);
EndPaint(hwnd,&ps);
return 0;
}
break;
case WM_TIMER:
...{
// 判断窗口处于最小化状态什么都不做
if (IsIconic(hwnd))
return 0;
SYSTEMTIME time;
GetLocalTime(&time);
// 建立坐标系
HDC hdc;
hdc=GetDC(hwnd);
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)
...{
// 擦除时针和分针
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(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;
}
case WM_CLOSE:
...{
::KillTimer(hwnd,IDT_CLOCK);
DestroyWindow(hwnd);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_COMMAND:
switch (LOWORD(wParam))
...{
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;
}
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
/**/ //
// 绘制时钟基本框架外观函数DrawClockFace();
bool DrawClockFace(HDC hdc)
... {
CONST int SQUARESIZE=20;
static POINT pt[]=
...{
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
};
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);
}
return 0;
}
/**/ //
// 绘画时钟指针的函数DrawHand;
// nLength 长度 nWidth宽度 nDegrees 相对于0的偏移角度。 clrColor
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)(sin(nRadians)*nLength);
pt[0].y=(int)(cos(nRadians)*nLength);
pt[1].x=-pt[0].x/5;
pt[1].y=-pt[0].y/5;
// 创建笔刷,并放入DC中
HPEN hpen=::CreatePen(PS_SOLID,nWidth,clrColor);
SelectObject(hdc,hpen);
// 画线
MoveToEx(hdc,pt[0].x,pt[0].y,NULL);
LineTo(hdc,pt[1].x,pt[1].y);
DeleteObject(hpen);
}
有什么地方不对的。希望大家多多指教!!! 谢谢