📄 4_6.cpp
字号:
/*********************************************
* 题4_6源程序 *
* 原理: *
* 建立两个设备上下文,一个作为屏幕副本即缓冲 *
* 另一个保存主框架内容,时钟到来时,先把主框 *
* 架内容拷贝到屏幕副本,然后在屏幕副本上的指 *
* 定位置上画圆,最后刷新屏幕将屏幕副本中的内 *
* 容拷贝到屏幕。 *
*********************************************/
#include "stdafx.h"
#include "resource.h"
#include "math.h"
#include "string.h"
#include "Role.h"
#define MAX_LOADSTRING 100
HINSTANCE hInst;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void Line(HDC &dc,int x1,int y1,int x2,int y2,int Width, COLORREF color);
void DrawFrame(HDC dc);
int r ; //圆半径
int A=150; //正弦波幅值
int WaveLen=450; //波长
HDC mdc,zdc ; //屏幕内存设备副本和主框架设备副本
HBITMAP bitmap,zbitmap; //屏幕位图副本和主框架位图副本
HBRUSH brush; //画刷
HPEN pen; //画笔
CRole Person[2];
bool IsMoving;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HACCEL hAccelTable;
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_MY4_6, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MY4_6);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_MY4_6);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance;
hWnd = CreateWindow(szWindowClass, szTitle, WS_MINIMIZEBOX|WS_SYSMENU,
50, 0, 700,600, NULL, NULL, hInstance, NULL);
if (!hWnd)return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_CREATE:
{
//初始化设备上下文
hdc=GetDC(hWnd);
mdc=CreateCompatibleDC(mdc);
zdc=CreateCompatibleDC(hdc);
bitmap=CreateCompatibleBitmap(hdc,800 ,600 );
zbitmap=CreateCompatibleBitmap(hdc,800 ,600 );
ReleaseDC(hWnd,hdc);
SelectObject(mdc,bitmap);
SelectObject(zdc,zbitmap);
//设置背景色
brush=CreateSolidBrush(RGB(20,50,120));
SelectObject(zdc,brush);
PatBlt(zdc,0,0,800,600,PATCOPY);
//画主框架
DrawFrame(zdc);
//将主框架场景拷贝到内存副本
BitBlt(mdc,0,0,800,600,zdc,0,0,SRCCOPY);
LPTSTR FilePath,pic1,pic2;
FilePath=(LPTSTR)malloc(100);
pic1=(LPTSTR)malloc(100);
pic2=(LPTSTR)malloc(100);
SearchPath(NULL,"girl",".bmp",100,FilePath,NULL);
FilePath[strlen(FilePath)-8]=0;
for(UINT p=0;p<strlen(FilePath);p++)
if( FilePath[p]=='\\')
FilePath[p]='/';
strcpy(pic1,FilePath);
strcpy(pic2,FilePath);
//MessageBox(hWnd,(LPCTSTR)pic1,"",false);
//MessageBox(hWnd,(LPCTSTR)strcat(FilePath,"girl.bmp"),"",false);
//strcat(FilePath,"24.bmp")
Person[1]=CRole(hWnd,mdc);
Person[1].SetRolePic(strcat(pic1,"girl.bmp"));
Person[1].SetDirection(3);
Person[0]=CRole(hWnd,mdc);
Person[0].SetRolePic(strcat(pic2,"27.bmp"));
Person[0].SetDirection(3);
break;
}
case WM_SETFOCUS:
//激活计时器
SetTimer(hWnd,0xffff,10,NULL);
IsMoving=true;
break;
case WM_KILLFOCUS:
//计时器无效
KillTimer(hWnd, 0xffff);
IsMoving=false;
break;
case WM_LBUTTONDOWN:
if(IsMoving==true)
{
KillTimer(hWnd, 0xffff);
IsMoving=false;
}
else
{
SetTimer(hWnd,0xffff,10,NULL);
IsMoving=true;
}
break;
case WM_TIMER:
if(LOWORD(wParam)==0xffff)
{
//将主框架场景拷贝到内存设备上下文副本
BitBlt(mdc,0,0,800,600,zdc,0,0,SRCCOPY);
static float t; //用作时间坐标
static int dt=2; //时间坐标增值(可正可负,控制方向)
int x,y; //圆心位置
//计算圆心位置,原点在(150,300)
x=int(150+t);
y=int(300-A*sin(t*2*3.14/WaveLen));
//变换横坐标
t+=dt;
//当圆运动到两端时反向
if(t>=WaveLen){dt*=-1;}
if(t<=0){dt*=-1;}
DeleteObject(brush);
//if(brush==NULL)MessageBox(NULL,"","",false);
//DeleteObject(brush);
DeleteObject(pen);
//以下计算圆心在各个区域内的半径,并且创建不同的画刷和画笔
//在1/4周期内时
if(t<=WaveLen/4)
{
r=int(A*(0.2+0.4/(WaveLen/4)*t));
pen=CreatePen(PS_SOLID,5,RGB(210,21,150));
SelectObject(mdc,pen);
brush=CreateSolidBrush(RGB(210,21,150));
SelectObject(mdc,brush);
if(dt>0)
Person[1].SetDirection(6);
else
Person[1].SetDirection(2);
}
//在1/4到2/4周期内时
if(t>WaveLen/4&&t<=WaveLen*2/4)
{
r=int(A*(0.2-0.4/(WaveLen/4)*(t-WaveLen/2)));
brush=CreateSolidBrush(RGB(210,0,250));
SelectObject(mdc,brush);
pen=CreatePen(PS_SOLID,5,RGB(210,0,250));
SelectObject(mdc,pen);
if(dt>0)
Person[1].SetDirection(7);
else
Person[1].SetDirection(4);
}
//在2/4到3/4周期内时
if(t>WaveLen*2/4&&t<=WaveLen*3/4)
{
r=int(A*(0.2+0.4/(WaveLen/4)*(t-WaveLen/2)));
brush=CreateSolidBrush(RGB(21,100,250));
SelectObject(mdc,brush);
pen=CreatePen(PS_SOLID,5,RGB(21,100,250));
SelectObject(mdc,pen);
if(dt>0)
Person[1].SetDirection(6);
else
Person[1].SetDirection(2); }
//在3/4到4/4周期内时
if(t>WaveLen*3/4)
{
r=int(A*(0.2-0.4/(WaveLen/4)*(t-WaveLen)));
brush=CreateSolidBrush(RGB(250,250,150));
SelectObject(mdc,brush);
pen=CreatePen(PS_SOLID,5,RGB(250,250,150));
SelectObject(mdc,pen);
if(dt>0)
Person[1].SetDirection(5);
else
Person[1].SetDirection(1);
}
//画圆
Ellipse(mdc,-r+x,-r+y,r+x,r+y);
Person[1].Setxy(x-30,y-30);
Person[1].ReDraw(mdc);
Person[0].Setxy(x-100,100);
Person[0].ReDraw(mdc);
static int time=0;
if(time==3)
{
Person[1].ChangePic();
time=0;
}
time++;
//使区域无效并刷新屏幕(原因是产生了WM_PAINT消息)
InvalidateRect(hWnd,NULL,false);
//SendMessage(hWnd, WM_PAINT, 0, 0 );
break;
}
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
//将场景副本拷贝到屏幕上
LineTo(hdc,0,0);
BitBlt(hdc,0,0,800,600,mdc,0,0,SRCCOPY);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
//释放各对象
DeleteObject(brush);
DeleteObject(pen);
ReleaseDC(hWnd,mdc);
ReleaseDC(hWnd,zdc);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//根据两点坐标,线宽度,和颜色在指定场景上画直线
void Line(HDC &dc,int x1,int y1,int x2,int y2,int Width, COLORREF color)
{
HPEN pen=CreatePen(PS_SOLID,Width,color);
SelectObject(dc,pen);
MoveToEx(dc,x1,y1,NULL);
LineTo(dc,x2,y2);
DeleteObject(pen);
}
//画主框架
void DrawFrame(HDC dc)
{
char *st1="基本绘图程序";
SetBkMode(dc,0); //文字背景透明
SetTextColor(dc,RGB(200,100,200));
TextOut(dc,340,0,st1,strlen(st1));
//画X轴
Line(dc,60,300,650,300,1,RGB(0,0,255));
Line(dc,650,300,630,290,1,RGB(0,0,255));
Line(dc,650,300,630,310,1,RGB(0,0,255));
TextOut(dc,640,320,"X",1);
//画Y轴
Line(dc,150,60,150,500,1,RGB(255,0,0));
Line(dc,150,60,140,80,1,RGB(255,0,0));
Line(dc,150,60,160,80,1,RGB(255,0,0));
TextOut(dc,170,55,"Y",1);
//画正弦曲线
for(float t=0;t<WaveLen;t+=0.1f)
{
int x=int(150+t);
int y=int(300-A*sin(t*2*3.14/WaveLen));
SetPixel(dc,x,y,RGB(200,0,200));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -