win32学习笔记(八)

使用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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值