MOOC清华《VC++面向对象与可视化程序设计》第3章补例:诗文扇面

#include <windows.h>
#include <tchar.h>
#include <math.h>
#define PI 3.141592653
BOOLEAN InitWindowClass(HINSTANCE hInstance,int nCmdShow);
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HFONT CreateMyFont(TCHAR * fontName,int height,int lean);//创建自定义字体,
//三个参数分别是字体名称,字体大小,字体的倾斜度,倾斜度以/10为一个逻辑单位
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
    MSG msg;
	if(!InitWindowClass(hInstance,nCmdShow)){
	    MessageBox(NULL,L"创建窗口失败!",_T("创建窗口"),NULL);
		return 1;
	}
	while(GetMessage(&msg,NULL,0,0)){
	    TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam){
    HDC hDC;
	PAINTSTRUCT ps;
	HFONT font;
	HPEN hPen;
	LPCWSTR title=L"长征 毛泽东",poem[8]={L"红军不怕远征难",L"万水千山只等闲",
		L"五岭逶迤腾细浪",L"乌蒙磅礴走泥丸",L"金沙水拍云崖暖",L"大渡桥横铁索寒",
		L"更喜岷山千里雪",L"三军过后尽开颜"};
	int r,r0,i,j=-1,fontSize,fontSize0,color;
	RECT clientDimension;//存放客户区的尺寸
	POINT begin,end,org;//保存点的信息,org表示圆心坐标
	double sita;//表示文字倾斜及画图时的角度
	switch(message){
	case WM_SIZE:
		InvalidateRect(hWnd,NULL,true);
		break;
	case WM_PAINT:
		hDC=BeginPaint(hWnd,&ps);
		hPen=CreatePen(PS_DASH,1,RGB(127,127,127));
		SelectObject(hDC,hPen);
		GetClientRect(hWnd,&clientDimension);//获取客户区的尺寸
		if((clientDimension.right-clientDimension.left)<400||
			(clientDimension.bottom-clientDimension.top)<300){//判断屏幕尺寸
		    MessageBox(hWnd,L"屏幕尺寸太小,无法绘图!",L"错误信息",0);
			break;
		}
	    r=(clientDimension.bottom-clientDimension.top)*8/10;//用屏幕高度的4/5作为扇形的半径
		org.x=(clientDimension.right-clientDimension.left)/2;
		org.y=(clientDimension.bottom-clientDimension.top)*9/10;//将圆心坐标定在屏幕中间下方的9/10处
		Arc(hDC,org.x-r,org.y-r,org.x+r,org.y+r,org.x+(int)(r*sin(PI/3)),
			org.y-(int)(r*cos(PI/3)),org.x-(int)(r*sin(PI/3)),
			org.y-(int)(r*cos(PI/3)));//画外围圆弧
		for(sita=PI/6;sita<=PI*5/6;sita+=PI*2/27){
		    begin.x=org.x+(int)(r*cos(sita));
			begin.y=org.y-(int)(r*sin(sita));
			MoveToEx(hDC,begin.x,begin.y,NULL);
			end.x=org.x;
			end.y=org.y;
			LineTo(hDC,end.x,end.y);
		}//画折线
		r0=r*2/5;//用外围圆弧半径的2/5作为内围圆弧半径
		Arc(hDC,org.x-r0,org.y-r0,org.x+r0,org.y+r0,org.x+(int)(r0*sin(PI/3)),
			org.y-(int)(r0*cos(PI/3)),org.x-(int)(r0*sin(PI/3)),
			org.y-(int)(r0*cos(PI/3)));//画内侧圆弧
		sita=PI/6+PI*4/15/5;//右侧第一列角度,这个角度是粗略计算加上反复调试试出来的
		fontSize0=fontSize=(r-r0)/7;//字体的大小
		r0=r-20;//半径逐步减小
		for(i=0;i<6;i++){
		    LPCWSTR outInfo=&title[i];//逐步取诗的标题字
			fontSize-=3;
			font=CreateMyFont(L"楷体_GB2312",fontSize-5,(int)(-(sita+PI/15)*1800/PI));//创建字体
			SelectObject(hDC,font);//将创建的字体句柄选入设备环境
			begin.x=org.x+(int)(r0*cos(sita));
			begin.y=org.y-(int)(r0*sin(sita));//计算输出文字的坐标
			TextOut(hDC,begin.x,begin.y,outInfo,1);//输出文字
			r0-=fontSize;//文字位置由外向内移动
			DeleteObject(font);
		}
		for(sita=PI/6+PI*4/27-PI/40;sita<PI*5/6;sita+=PI*2/27){
			//角度从右向左,角度与以下计算位置及字体倾斜相配合
			fontSize=fontSize0;
			r0=r-20;
			j++;
			color=0;
			for(i=0;i<7;i++){
				color+=255/7;
				SetTextColor(hDC,RGB(255-color,0,color));
				LPCWSTR outInfo=&poem[j][i];
				fontSize-=3;
				font=CreateMyFont(L"华文行楷",fontSize,(int)(((sita-PI/2)*1800/PI))%3600);
				SelectObject(hDC,font);
				begin.x=org.x+(int)(r0*cos(sita));
				begin.y=org.y-(int)(r0*sin(sita));
				TextOut(hDC,begin.x,begin.y,outInfo,1);
				r0-=fontSize;
				DeleteObject(font);
				Sleep(50);//输出一个文字暂停0.1秒
			}
		}
		EndPaint(hWnd,&ps);//结束绘图
		break;
	case WM_DESTROY:
		PostQuitMessage(0);//调用PostQuitMessage发出WM_QUIT消息
		break;
	default:
		return DefWindowProc(hWnd,message,wParam,lParam);//默认时采用系统消息默认处理函数
		break;
	}
	return 0;
}
HFONT CreateMyFont(TCHAR * fontName,int height,int lean){
    return CreateFont(
		height,
		0,
		lean,
		0,
		FW_HEAVY,
		0,
		0,
		0,
		GB2312_CHARSET,
		OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY,
		DEFAULT_PITCH|FF_DONTCARE,
		fontName
		);
}
BOOLEAN InitWindowClass(HINSTANCE hInstance,int nCmdShow){
    WNDCLASSEX wcex;
	HWND hWnd;
	TCHAR szWindowClass[]=L"窗口示例";
	TCHAR szTitle[]=L"字体及位置示例";
	wcex.cbSize=sizeof(WNDCLASSEX);
	wcex.style=0;
	wcex.lpfnWndProc=WndProc;
	wcex.cbClsExtra=0;
	wcex.cbWndExtra=0;
	wcex.hInstance=hInstance;
	wcex.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_APPLICATION));
	wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
	wcex.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
	wcex.lpszMenuName=NULL;
	wcex.lpszClassName=szWindowClass;
	wcex.hIconSm=LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_APPLICATION));
	if(!RegisterClassEx(&wcex))
		return FALSE;
	hWnd=CreateWindow(
		szWindowClass,
		szTitle,
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,CW_USEDEFAULT,
		CW_USEDEFAULT,CW_USEDEFAULT,
		NULL,
		NULL,
		hInstance,
		NULL
		);
	if(!hWnd)
		return FALSE;
	ShowWindow(hWnd,nCmdShow);
	UpdateWindow(hWnd);
	return TRUE;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值