实验题目;编写一个程序,在屏幕上出现一个圆心沿正弦曲线轨迹移动的实心圆,且每隔四分之一周期,圆的填充色和圆的周边颜色都发生变化,同时圆的半径在四分之一周期之内由正弦曲线幅值的0.2倍至0.6倍线性增长。
源代码:
1 // 该程序使用vs2010建立工程。部分代码采用vs2010中Win32模板代码 2 // 正弦动态圆.cpp : 定义应用程序的入口点。 3 4 //实现功能: 5 //1:能够实现基本实验功能; 6 //2:能够通过方向键控制圆滚动速度,通过空格键暂停圆滚动; 7 //3:能够自动判断窗口尺寸,调整正弦图形; 8 //作者 :软件sy1201 陈亚辉 9 #include "stdafx.h" 10 #include "正弦动态圆.h" 11 #include "math.h" 12 #define MAX_LOADSTRING 100 13 #define Pi 3.141592653589 14 POINT lpSin[100]; 15 int speed=100; 16 // 全局变量: 17 HINSTANCE hInst; // 当前实例 18 TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本 19 TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名 20 21 // 此代码模块中包含的函数的前向声明: 22 ATOM MyRegisterClass(HINSTANCE hInstance); 23 BOOL InitInstance(HINSTANCE, int); 24 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 25 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 26 27 int APIENTRY _tWinMain(HINSTANCE hInstance, 28 HINSTANCE hPrevInstance, 29 LPTSTR lpCmdLine, 30 int nCmdShow) 31 { 32 UNREFERENCED_PARAMETER(hPrevInstance); 33 UNREFERENCED_PARAMETER(lpCmdLine); 34 35 // TODO: 在此放置代码。 36 MSG msg; 37 HACCEL hAccelTable; 38 39 // 初始化全局字符串 40 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 41 LoadString(hInstance, IDC_MY, szWindowClass, MAX_LOADSTRING); 42 MyRegisterClass(hInstance); 43 44 // 执行应用程序初始化: 45 if (!InitInstance (hInstance, nCmdShow)) 46 { 47 return FALSE; 48 } 49 50 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MY)); 51 52 // 主消息循环: 53 while (GetMessage(&msg, NULL, 0, 0)) 54 { 55 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 56 { 57 TranslateMessage(&msg); 58 DispatchMessage(&msg); 59 } 60 } 61 62 return (int) msg.wParam; 63 } 64 65 66 67 // 68 // 函数: MyRegisterClass() 69 // 70 // 目的: 注册窗口类。 71 // 72 // 注释: 73 // 74 // 仅当希望 75 // 此代码与添加到 Windows 95 中的“RegisterClassEx” 76 // 函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要, 77 // 这样应用程序就可以获得关联的 78 // “格式正确的”小图标。 79 // 80 ATOM MyRegisterClass(HINSTANCE hInstance) 81 { 82 WNDCLASSEX wcex; 83 84 wcex.cbSize = sizeof(WNDCLASSEX); 85 86 wcex.style = CS_HREDRAW | CS_VREDRAW; 87 wcex.lpfnWndProc = WndProc; 88 wcex.cbClsExtra = 0; 89 wcex.cbWndExtra = 0; 90 wcex.hInstance = hInstance; 91 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY)); 92 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 93 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 94 wcex.lpszMenuName = NULL;//MAKEINTRESOURCE(IDC_MY); 95 wcex.lpszClassName = szWindowClass; 96 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); 97 98 return RegisterClassEx(&wcex); 99 }100 101 //102 // 函数: InitInstance(HINSTANCE, int)103 //104 // 目的: 保存实例句柄并创建主窗口105 //106 // 注释:107 //108 // 在此函数中,我们在全局变量中保存实例句柄并109 // 创建和显示主程序窗口。110 //111 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)112 {113 HWND hWnd;114 115 hInst = hInstance; // 将实例句柄存储在全局变量中116 117 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,118 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);119 120 if (!hWnd)121 {122 return FALSE;123 }124 125 ShowWindow(hWnd, nCmdShow);126 UpdateWindow(hWnd);127 128 return TRUE;129 }130 131 //132 // 函数: WndProc(HWND, UINT, WPARAM, LPARAM)133 //134 // 目的: 处理主窗口的消息。135 //136 // WM_COMMAND - 处理应用程序菜单137 // WM_PAINT - 绘制主窗口138 // WM_DESTROY - 发送退出消息并返回139 //140 //141 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)142 {143 int i,xOrg,yOrg,width,height,Radius,X1,Y1,X2,Y2;144 int wmId, wmEvent;145 static int j,pause=0;146 PAINTSTRUCT ps;147 HDC hdc;148 HPEN hPen;149 HBRUSH hBrush;150 RECT clientRect;151 switch (message)152 {153 case WM_COMMAND:154 wmId = LOWORD(wParam);155 wmEvent = HIWORD(wParam);156 // 分析菜单选择:157 switch (wmId)158 {159 case IDM_ABOUT:160 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);161 break;162 case IDM_EXIT:163 DestroyWindow(hWnd);164 break;165 default:166 return DefWindowProc(hWnd, message, wParam, lParam);167 }168 break;169 case WM_CREATE:170 SetTimer(hWnd,9999,speed,NULL);//设置定时器,ID为9999,时间间隔为0.1秒171 break;172 case WM_KEYDOWN:173 switch(wParam)174 {175 case VK_UP:176 case VK_RIGHT://按上键或者右键加速177 if(speed<=10)178 MessageBox(NULL,_T("已经是最快速度了"),_T("加速"),0);179 else180 {181 speed=speed-10;182 KillTimer(hWnd,9999);183 SetTimer(hWnd,9999,speed,NULL);184 }185 break;186 case VK_DOWN:187 case VK_LEFT://按下键或者左键加速188 if(speed>=300)189 MessageBox(NULL,_T("已经是最慢速度了"),_T("减速"),0);190 else191 {192 speed=speed+10;193 KillTimer(hWnd,9999);194 SetTimer(hWnd,9999,speed,NULL);195 }196 break;197 case VK_SPACE:198 if(pause==0)//用pause控制199 pause=1;200 else201 pause=0;202 break;203 }204 break;205 206 case WM_PAINT:207 208 209 hdc = BeginPaint(hWnd, &ps);210 GetClientRect(hWnd,&clientRect);211 width=clientRect.right-clientRect.left;212 height=clientRect.bottom-clientRect.top;213 xOrg=(clientRect.left+clientRect.right)/2;214 yOrg=(clientRect.bottom+clientRect.top)/2;215 216 for(i=0;i<100;i++)217 {218 lpSin[i].x=(long)(width*i/100);//使得横坐标和纵坐标刚好填充窗口的宽和高219 lpSin[i].y=(long)(height/2*sin(2*Pi*i/100));220 }221 hPen=(HPEN)GetStockObject(BLACK_PEN);222 223 SelectObject(hdc,hPen);224 SetViewportOrgEx(hdc,0,yOrg,NULL);//以窗口宽的中点为原点,使得横坐标刚好填充窗口225 Polyline(hdc,lpSin,100);//绘制正弦曲线226 if(j<25)//在不同的区间,为圆挑选不同的颜色227 {228 Radius=(0.2+0.4*j/25)*height/2;//计算出此时圆的半径229 hPen=CreatePen(PS_SOLID,2,RGB(255,0,0));230 SelectObject(hdc,hPen);231 hBrush=CreateSolidBrush(RGB(255,0,0));232 SelectObject(hdc,hBrush);233 }234 else if(j<50)235 {236 Radius=(0.6-(j-25)*0.4/25)*height/2;237 hPen=CreatePen(PS_SOLID,2,RGB(0,255,0));238 SelectObject(hdc,hPen);239 hBrush=CreateSolidBrush(RGB(0,255,0));240 SelectObject(hdc,hBrush);241 }242 else if(j<75)243 {244 Radius=(0.2+0.4*(j-50)/25)*height/2;245 hPen=CreatePen(PS_SOLID,2,RGB(0,0,255));246 SelectObject(hdc,hPen);247 hBrush=CreateSolidBrush(RGB(0,0,255));248 SelectObject(hdc,hBrush);249 }250 else if(j<100)251 {252 Radius=(0.6-(j-75)*0.4/25)*height/2;253 hPen=CreatePen(PS_SOLID,2,RGB(255,255,0));254 SelectObject(hdc,hPen);255 hBrush=CreateSolidBrush(RGB(255,255,0));256 SelectObject(hdc,hBrush);257 }258 X1=lpSin[j].x-Radius;259 Y1=lpSin[j].y-Radius;260 X2=lpSin[j].x+Radius;261 Y2=lpSin[j].y+Radius;262 Ellipse(hdc,X1,Y1,X2,Y2);//画圆263 if(j<99)264 j++;265 else266 j=0;//如果圆滚动到头,则从头开始267 EndPaint(hWnd, &ps);268 break;269 case WM_TIMER:270 if(wParam=9999)271 if(pause==0)//用pause变量控制是否要触发WM_PAINT272 InvalidateRect(hWnd,NULL,true);273 break;274 case WM_SIZE:275 InvalidateRect(hWnd,NULL,true);276 break;277 case WM_DESTROY:278 PostQuitMessage(0);279 break;280 default:281 return DefWindowProc(hWnd, message, wParam, lParam);282 }283 return 0;284 }285 286 // “关于”框的消息处理程序。287 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)288 {289 UNREFERENCED_PARAMETER(lParam);290 switch (message)291 {292 case WM_INITDIALOG:293 return (INT_PTR)TRUE;294 295 case WM_COMMAND:296 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)297 {298 EndDialog(hDlg, LOWORD(wParam));299 return (INT_PTR)TRUE;300 }301 break;302 }303 return (INT_PTR)FALSE;304 }