使用Win32API制作了一个时钟程序
代码如下:
// win32appdemo.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include <string>
#include <math.h>
#define IDT_CLOCK 1
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 MainWndProc(HWND,UINT,WPARAM,LPARAM);
void SetIsotropic(HDC,int,int);
void DrawClockFace(HDC);
void DrawClockHand(HDC,int,int,int,COLORREF);
const int IDM_HELP =100;
const int IDM_TOPMOST=101;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
char szClassName[]="MainWClass";
WNDCLASSEX wndclass;
//初始化WNDCLASSEX结构
wndclass.cbSize=sizeof(wndclass);//结构大小
wndclass.style=CS_HREDRAW|CS_VREDRAW;//指定大小如果改变就重画
wndclass.lpfnWndProc=MainWndProc;//窗口函数指针
wndclass.cbClsExtra=0;//没有额外的类内存
wndclass.cbWndExtra=0;//没有额外的窗口内存
wndclass.hInstance=hInstance;//实例句柄
wndclass.hIcon=::LoadIcon(NULL,IDI_APPLICATION);//使用预定义图标
wndclass.hCursor=::LoadCursor(NULL,IDC_ARROW);//使用预定义光标
wndclass.hbrBackground=CreateSolidBrush(::GetSysColor(COLOR_3DFACE));//使用背景画刷
wndclass.lpszMenuName=NULL;//不指定菜单
wndclass.lpszClassName=szClassName;//窗口类名称
wndclass.hIconSm=NULL;//没有类的小图标
//注册这个窗口类
::RegisterClassEx(&wndclass);
//创建主窗口
HWND hwnd=::CreateWindowEx(
0,
szClassName,
"CLOCK",
WS_POPUP|WS_SYSMENU|WS_SIZEBOX,
150,
150,
200,
200,
NULL,
NULL,
hInstance,
NULL);
if(hwnd==NULL)
{
::MessageBox(NULL,NULL,"error",MB_OK);
return -1;
}
//显示窗口,刷新窗口客户区
::ShowWindow(hwnd,nCmdShow);
::UpdateWindow(hwnd);
//从消息队列中取出消息,交给窗口函数处理,直到GetMessage返回0,结束循环
MSG msg;
while(::GetMessage(&msg,NULL,0,0))
{
//转化键盘消息
::TranslateMessage(&msg);
//将消息发送到消息处理函数
::DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK MainWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
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);
HMENU hSysMenu;
hSysMenu=::GetSystemMenu(hwnd,FALSE);
::AppendMenu(hSysMenu,MF_SEPARATOR,0,NULL);
::AppendMenu(hSysMenu,MF_STRING,IDM_TOPMOST,"TOP MOST");
::AppendMenu(hSysMenu,MF_STRING,IDM_HELP,"HELP");
return 0;
}
case WM_CLOSE:
{
::KillTimer(hwnd,IDT_CLOCK);
::DestroyWindow(hwnd);
return 0;
}
case WM_PAINT://客户区需要重画时
{
HDC hdc;
PAINTSTRUCT ps;
//使无效的客户区变得有效,并取得设备环境句柄
hdc=::BeginPaint(hwnd,&ps);
RECT rt;
::GetClientRect(hwnd,&rt);
SetIsotropic(hdc,rt.right-rt.left,rt.bottom-rt.top);
DrawClockFace(hdc);
DrawClockHand(hdc,200,8,s_nPreHour*30+s_nPreMinute/2+s_nPreSecond/120,RGB(0,0,0));
DrawClockHand(hdc,400,5,s_nPreMinute*6+s_nPreSecond/10,RGB(0,0,0));
DrawClockHand(hdc,450,2,s_nPreSecond*6,RGB(0,0,0));
::EndPaint(hwnd,&ps);
return 0;
}
case WM_DESTROY://正在销毁窗口
{
//向消息队列传递一个WM_QUIT消息,使GetMessage函数返回0,结束消息循环
::PostQuitMessage(0);
return 0;
}
case WM_SIZE:
{
s_cxClient=LOWORD(lParam);
s_cyClient=HIWORD(lParam);
return 0;
}
case WM_TIMER:
{
if(::IsIconic(hwnd))
return 0;
SYSTEMTIME time;
::GetLocalTime(&time);
HDC hdc=::GetDC(hwnd);
SetIsotropic(hdc,s_cxClient,s_cyClient);
COLORREF crf=::GetSysColor(COLOR_3DFACE);
if(time.wHour!=s_nPreHour)
{
DrawClockHand(hdc,200,8,s_nPreHour*30+s_nPreMinute/2+s_nPreSecond/120,crf);
DrawClockHand(hdc,200,8,(time.wHour%12)*30+time.wMinute/2+time.wSecond/120,RGB(0,0,0));
}
if(time.wMinute!=s_nPreMinute)
{
DrawClockHand(hdc,400,5,s_nPreMinute*6+s_nPreSecond/10,crf);
DrawClockHand(hdc,400,5,time.wMinute*6+time.wSecond/10,RGB(0,0,0));
}
if(time.wSecond!=s_nPreSecond)
{
DrawClockHand(hdc,450,2,s_nPreSecond*6,crf);
DrawClockHand(hdc,450,2,time.wSecond*6,RGB(0,0,0));
}
s_nPreHour=time.wHour;
s_nPreMinute=time.wMinute;
s_nPreSecond=time.wSecond;
return 0;
}
case WM_NCHITTEST:
{
UINT nhist;
nhist=::DefWindowProc(hwnd,message,wParam,lParam);
if(nhist==HTCLIENT&&::GetAsyncKeyState(MK_LBUTTON)<0)
nhist=HTCAPTION;
return nhist;
}
case WM_CONTEXTMENU:
{
POINT pt;
pt.x=LOWORD(lParam);
pt.y=HIWORD(lParam);
HMENU hSysMenu=::GetSystemMenu(hwnd,FALSE);
int nID=::TrackPopupMenu(hSysMenu,TPM_LEFTALIGN|TPM_RETURNCMD,pt.x,pt.y,0,hwnd,NULL);
if(nID>0)
::SendMessage(hwnd,WM_SYSCOMMAND,nID,0);
return 0;
}
case WM_SYSCOMMAND:
{
int nID=wParam;
if(nID==IDM_HELP)
{
::MessageBox(hwnd,"A Clock","Clock",0);
}
else if(nID==IDM_TOPMOST)
{
HMENU hSysMenu=::GetSystemMenu(hwnd,FALSE);
if(s_bTopMost)
{
::CheckMenuItem(hSysMenu,IDM_TOPMOST,MF_UNCHECKED);
::SetWindowPos(hwnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOREDRAW|SWP_NOSIZE);
s_bTopMost=FALSE;
}
else
{
::CheckMenuItem(hSysMenu,IDM_TOPMOST,MF_UNCHECKED);
::SetWindowPos(hwnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOREDRAW|SWP_NOSIZE);
s_bTopMost=TRUE;
}
}
return ::DefWindowProc(hwnd,message,wParam,lParam);
}
}
return ::DefWindowProc(hwnd,message,wParam,lParam);
}
void SetIsotropic(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,
-390,-225,
-225,-390,
-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);
}
}
void DrawClockHand(HDC hdc,int nLength,int nWidth,int nDegrees,COLORREF clr)
{
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;
HPEN hPen=::CreatePen(PS_SOLID,nWidth,clr);
HPEN hOldPen=(HPEN)::SelectObject(hdc,hPen);
::MoveToEx(hdc,pt[0].x,pt[0].y,NULL);
::LineTo(hdc,pt[1].x,pt[1].y);
::SelectObject(hdc,hOldPen);
::DeleteObject(hPen);
}