您的位置:首页 > 编程语言 > C语言/C++

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

2017-12-14 08:41 369 查看
#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;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐