c++win32的 仿真 无控件 纯手打 仅供参考@TOC
c++win32的 仿真 无控件 纯手打 仅供参考
//c++win32的 仿真 无控件 纯手打 仅供参考
#include<windows.h>
#include<tchar.h>
#include<math.h>
#include<stdlib.h>
BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
constexpr auto pi = 3.14159;
static int cx, cy, cr;
//画圆类申明CreateCircle
class creaCircle//画圆函数
{
public:
//画圆 (句柄 圆心坐标 半径)
int CreateCircle(HDC hDC, int cenX1, int cenY1, int cenR1)
{
cenLLeft = cenX1 - cenR1;
cenTTop = cenY1 - cenR1;
cenRRight = cenX1 + cenR1;
cenBButom = cenY1 + cenR1;
Ellipse(hDC, cenLLeft, cenTTop, cenRRight, cenBButom);
return 0;
}
private:
int cenLLeft, cenTTop, cenRRight, cenBButom;
};
//画天空半圆、地平线、刻度和俯仰调度数CreateCHord->CreateHorizon->CreatePscale
class creaChord
{
public:
//地平线中点坐标(调用后可使用)
double x_, y_;
//画天空半圆(句柄、圆心坐标、半径、滚转角、俯仰角)
int CreateCHord(HDC hDC, int cenX1, int cenY1, int cenR1, float rollangle, float pitchangle)
{
roll = rollangle;
pitch = pitchangle;
cx = cenX1;
cy = cenY1;
cr = cenR1;
cenLLeft = cx - cr;
cenTTop = cy - cr;
cenRRight = cx + cr;
cenBButom = cy + cr;
x1 = cx + cr * sin((roll / 180)*pi + acos(pitch / 45));//右边点坐标
y1 = cy + cr * cos((roll / 180)*pi + acos(pitch / 45));//右边点坐标
x2 = cx - cr * sin(acos(pitch / 45) - (roll / 180)*pi);//左边点坐标
y2 = cy + cr * cos(acos(pitch / 45) - (roll / 180)*pi);//左边点坐标
x_ = (x1 + x2) / 2; //地平线中点坐标
y_ = (y1 + y2) / 2; //地平线中点坐标
Chord(hDC, cenLLeft, cenTTop, cenRRight, cenBButom, x1, y1, x2, y2);
return 0;
}
//画地平线(句柄)
int CreateHorizon(HDC hDC)
{
MoveToEx(hDC, x1, y1, NULL); //为指定的设备场景指定一个新的当前画笔位置
LineTo(hDC, x2, y2);//用当前画笔画一条线,从当前位置连到一个指定的点
return 0;
}
//画俯仰刻度线和数字(句柄)字体已定义
int CreatePscale(HDC hDC)
{
//刻度和数字
//初始化字体和模式
HFONT myFont = CreateFont( //创建一个自定义字体
20, //字体的高度(字体大小)
0, //由系统根据高宽比选取字体最佳宽度值
((int)10 * roll), //文本的倾斜度为0,表示水平
0, //字体的倾斜度为0
FW_NORMAL, //字体的粗度,FW_NORMAL为正常 FW_HEAVY为最粗
0, //非斜体字
0, //有下划线
0, //无删除线
GB2312_CHARSET, //表示所用的字符集为ANSI_CHARSET
OUT_DEFAULT_PRECIS, //输出精度为缺省精度
CLIP_DEFAULT_PRECIS, //剪裁精度为缺省精度
DEFAULT_QUALITY, //输出质量为缺省值
DEFAULT_PITCH | FF_DONTCARE,//字间距和字体系列使用缺省值
L"Arial" //字体名称
);
SetTextColor(hDC, RGB(255, 255, 255)); //设置文本颜色为白色
SetBkMode(hDC, TRANSPARENT); //设置背景颜色为透明色
SelectObject(hDC, myFont); //将自定义字体选入设备环境
//选择刻度线
HPEN hPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255)); //设置画笔(画笔的设定参照上面画线的说明)
SelectObject(hDC, hPen); //选择画笔
//画上半部俯仰刻度和标示数字
for (int i = 1; i < 20; i++)
{
xt = x_ - (200 / 9*i) * sin((roll / 180)*pi);
yt = y_ - (200 / 9*i )* cos((roll / 180)*pi);
x3 = xt - 40 * (((i + 1) % 2) + 1)*cos((roll / 180)*pi);
y3 = yt + 40 * (((i + 1) % 2) + 1)*sin((roll / 180)*pi);
x4 = 2 * xt - x3;
y4 = 2 * yt - y3;
if ((i + 1) % 2) {
int x = i * 5;
TCHAR p[64] = { 0 }; //定义并申请输入缓冲区空间
wsprintf(p, _T("%d"), x); //应用
TextOutW(hDC, (x4 - 20 * cos(roll / 180)), (y4 + 20 * sin(roll / 180)), p, wcslen(p)); //使用当前字体输出文本
TextOutW(hDC, (x3), (y3), p, wcslen(p)); //使用当前字体输出文本
};
MoveToEx(hDC, x3, y3, NULL); //为指定的设备场景指定一个新的当前画笔位置
LineTo(hDC, x4, y4);//用当前画笔画一条线,从当前位置连到一个指定的点
};
//画下半部俯仰刻度和标示数字
for (int i = 1; i < 20; i++)
{
xt = x_ + (200 / 9 * i) * sin((roll / 180)*pi);
yt = y_ + (200 / 9 * i) * cos((roll / 180)*pi);
x3 = xt - 40 * (((i + 1) % 2) + 1)*cos((roll / 180)*pi);
y3 = yt + 40 * (((i + 1) % 2) + 1)*sin((roll / 180)*pi);
x4 = 2 * xt - x3;
y4 = 2 * yt - y3;
MoveToEx(hDC, x3, y3, NULL); //为指定的设备场景指定一个新的当前画笔位置
LineTo(hDC, x4, y4);//用当前画笔画一条线,从当前位置连到一个指定的点
if ((i + 1) % 2) {
int x = i * 5;
TCHAR p[64] = { 0 };//定义并申请输入缓冲区空间
wsprintf(p, _T("%d"), x);//应用
TextOutW(hDC, (x4 - 20 * cos(roll / 180)), (y4 + 20 * sin(roll / 180)), p, wcslen(p));//使用当前字体输出文本
TextOutW(hDC, (x3), (y3), p, wcslen(p));
};
};
return 0;
}
private:
int cenLLeft, cenTTop, cenRRight, cenBButom, cx, cy, cr;
double x1, y1, x2, y2, xt, yt, x3, x4, y3, y4;
float roll, pitch;
};
//画滚转刻度和箭头 CreatesRscale->CreatesRnum->CreateHfuselage
class createRoll
{
public:
//画滚转刻度线(句柄,圆心,半径,滚转角)
int CreatesRscale(HDC hDC, int cenX1, int cenY1, int cenR1, float rollangle)
{
cx = cenX1;
cy = cenY1;
cr = cenR1;
roll = rollangle;
for (int i = 0; i < 59; i++)
{
double u = i;
xt = cx + (cr + 20) * sin((10 * u) / 180*pi);
yt = cy - (cr + 20) * cos((10 * u) / 180*pi);
x1 = xt - (10 * (((i + 1) % 2) + 1)) * sin((10 * u) / 180*pi);
y1 = yt + (10 * (((i + 1) % 2) + 1)) * cos((10 * u) / 180*pi);
MoveToEx(hDC, xt, yt, NULL); //为指定的设备场景指定一个新的当前画笔位置
LineTo(hDC, x1, y1);//用当前画笔画一条线,从当前位置连到一个指定的点
};
return 0;
}
//指向三角,旁边的数值字体已定义
int CreatesRnum(HDC hDC)
{
HFONT myFont = CreateFont( //创建一个自定义字体
20, //字体的高度(字体大小)
0, //由系统根据高宽比选取字体最佳宽度值
((int)10 * roll), //文本的倾斜度为0,表示水平
0, //字体的倾斜度为0
FW_NORMAL, //字体的粗度,FW_NORMAL为正常 FW_HEAVY为最粗
0, //非斜体字
0, //有下划线
0, //无删除线
GB2312_CHARSET, //表示所用的字符集为ANSI_CHARSET
OUT_DEFAULT_PRECIS, //输出精度为缺省精度
CLIP_DEFAULT_PRECIS, //剪裁精度为缺省精度
DEFAULT_QUALITY, //输出质量为缺省值
DEFAULT_PITCH | FF_DONTCARE,//字间距和字体系列使用缺省值
L"Arial" //字体名称
);
SetTextColor(hDC, RGB(255, 255, 255)); //设置文本颜色为白色
SetBkMode(hDC, TRANSPARENT); //设置背景颜色为透明色
SelectObject(hDC, myFont); //将自定义字体选入设备环境
POINT myPoint[3]; //三角点存储
myPoint[0].x = cx - (cr + 20) * sin((roll / 180)*pi); //顶点
myPoint[0].y = cy - (cr + 20) * cos((roll / 180)*pi);
xt = cx - (cr + 40) * sin((roll / 180)*pi); //底边中点
yt = cy - (cr + 40) * cos((roll / 180)*pi);
myPoint[2].x = xt - 15 * cos((roll / 180)*pi); //左边点
myPoint[2].y = yt + 15 * sin((roll / 180)*pi);
myPoint[1].x = 2 * xt - myPoint[2].x; //右边点
myPoint[1].y = 2 * yt - myPoint[2].y;
TCHAR p[64] = { 0 }; //定义并申请输入缓冲区空间
wsprintf(p, _T("%d"), int(roll)); //应用
TextOutW(hDC, myPoint[1].x, myPoint[1].y, p, wcslen(p));//画出数值
Polygon(hDC, myPoint, 3); //画出三角形
return 0;
}
//画机身水平线
int CreateHfuselage(HDC hDC)
{
POINT myPointL[3];
POINT myPointR[3];
if (((roll<90) && (roll>-90)))
{
SetBkMode(hDC, TRANSPARENT); //设置背景颜色为透明色
HBRUSH hBrush = (HBRUSH)GetStockObject(NULL_BRUSH);
HPEN hPen = CreatePen(PS_SOLID, 4, RGB(255, 255, 0)); //设置画笔(画笔的设定参照上面画线的说明)
SelectObject(hDC, hPen); //选择画笔
myPointL[0].x = 650;
myPointL[0].y = 400;
myPointL[1].x = 700;
myPointL[1].y = 400;
myPointL[2].x = 700;
myPointL[2].y = 408;
myPointR[0].x = 950;
myPointR[0].y = 400;
myPointR[1].x = 900;
myPointR[1].y = 400;
myPointR[2].x = 900;
myPointR[2].y = 408;
MoveToEx(hDC, myPointL[0].x, myPointL[0].y, NULL);
LineTo(hDC, myPointL[1].x, myPointL[1].y);
LineTo(hDC, myPointL[2].x, myPointL[2].y);
MoveToEx(hDC, myPointR[0].x, myPointR[0].y, NULL);
LineTo(hDC, myPointR[1].x, myPointR[1].y);
LineTo(hDC, myPointR[2].x, myPointR[2].y);
}
else
{
//SetBkMode(hDC, TRANSPARENT); //设置背景颜色为透明色
//HBRUSH hBrush = (HBRUSH)GetStockObject(NULL_BRUSH);//设置透明刷
HPEN hPen = CreatePen(PS_DOT, 4, RGB(255, 255, 0)); //设置画笔(画笔的设定参照上面画线的说明)
SelectObject(hDC, hPen); //选择画笔
myPointL[2].y = 392;
myPointR[2].y = 392;
myPointL[0].x = 650;
myPointL[0].y = 400;
myPointL[1].x = 700;
myPointL[1].y = 400;
myPointL[2].x = 700;
//myPointL[2].y = 408;
myPointR[0].x = 950;
myPointR[0].y = 400;
myPointR[1].x = 900;
myPointR[1].y = 400;
myPointR[2].x = 900;
//myPointR[2].y = 408;
MoveToEx(hDC, myPointL[0].x, myPointL[0].y, NULL);
LineTo(hDC, myPointL[1].x, myPointL[1].y);
LineTo(hDC, myPointL[2].x, myPointL[2].y);
MoveToEx(hDC, myPointR[0].x, myPointR[0].y, NULL);
LineTo(hDC, myPointR[1].x, myPointR[1].y);
LineTo(hDC, myPointR[2].x, myPointR[2].y);
}
/*Polyline(hDC, myPointL, 3);
Polyline(hDC, myPointR, 3);*/
return 0;
}
private:
double x1, y1, x2, y2, xt, yt;
int cx, cy, cr;
float roll;
};
float roll, pitch;
int gCnt=0;
//绘图函数
int myDraw(HDC hDC) {
LPCWSTR String1 = L"MFD模拟"; //创建一个变量存储要输出的字符串
cx = 800;
cy = 400;
cr = 200;
creaCircle yrR;
creaChord yrC;
createRoll yrRoll;
//棕色地面圆
HPEN hPen = CreatePen(PS_SOLID, 2, RGB(128, 42, 42)); //设置画笔(画笔的设定参照上面画线的说明)
SelectObject(hDC, hPen); //选择画笔
HBRUSH hBrush = CreateSolidBrush(RGB(128, 42, 42)); //设置一个单色填充画刷(只有唯一的一个设置颜色的参数)
SelectObject(hDC, hBrush); //选择画刷
yrR.CreateCircle(hDC, cx, cy, cr);
//蓝色天空半圆
hPen = CreatePen(PS_SOLID, 2, RGB(255, 255, 255)); //设置画笔(画笔的设定参照上面画线的说明)
SelectObject(hDC, hPen); //选择画笔
hBrush = CreateSolidBrush(RGB(0, 0, 155)); //设置一个单色填充画刷(只有唯一的一个设置颜色的参数)
SelectObject(hDC, hBrush); //选择画刷
yrC.CreateCHord(hDC, 800, 400, 200, roll, pitch);
//画地平线
hPen = CreatePen(PS_SOLID, 3, RGB(255, 255, 0)); //设置画笔(画笔的设定参照上面画线的说明)
SelectObject(hDC, hPen); //选择画笔
yrC.CreateHorizon(hDC);
//画俯仰刻度和数字
yrC.CreatePscale(hDC);
//中心红点
hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 00)); //设置画笔(画笔的设定参照上面画线的说明)
SelectObject(hDC, hPen); //选择画笔
hBrush = CreateSolidBrush(RGB(255, 0, 0)); //设置一个单色填充画刷(只有唯一的一个设置颜色的参数)
SelectObject(hDC, hBrush); //选择画刷
yrR.CreateCircle(hDC, cx, cy, 2);
//透明圆遮罩
hPen = CreatePen(PS_SOLID, 400, RGB(0, 0, 0)); //设置画笔(画笔的设定参照上面画线的说明)
SelectObject(hDC, hPen); //选择画笔
hBrush = (HBRUSH)GetStockObject(NULL_BRUSH);// 设置透明
SelectObject(hDC, hBrush); //选择画刷
yrR.CreateCircle(hDC, cx, cy, 400);
//表轮廓
hPen = CreatePen(PS_SOLID, 2, RGB(255, 255, 255)); //设置画笔(画笔的设定参照上面画线的说明)
SelectObject(hDC, hPen); //选择画笔
yrR.CreateCircle(hDC, cx, cy, 220);
yrR.CreateCircle(hDC, cx, cy, 200);
//滚转刻度
hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0)); //设置画笔(画笔的设定参照上面画线的说明)
SelectObject(hDC, hPen); //选择画笔
yrRoll.CreatesRscale(hDC, cx, cy, cr, roll);
//指向三角
hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0)); //设置画笔(画笔的设定参照上面画线的说明)
SelectObject(hDC, hPen); //选择画笔
hBrush = CreateSolidBrush(RGB(255, 0, 0)); //设置一个单色填充画刷(只有唯一的一个设置颜色的参数)
SelectObject(hDC, hBrush); //选择画刷
yrRoll.CreatesRnum(hDC);
//机身水平线
yrRoll.CreateHfuselage(hDC);
//打字
HFONT myFont = CreateFont( //创建一个自定义字体
40, //字体的高度(字体大小)
0, //由系统根据高宽比选取字体最佳宽度值
0, //文本的倾斜度为0,表示水平
0, //字体的倾斜度为0
FW_NORMAL, //字体的粗度,FW_NORMAL为正常 FW_HEAVY为最粗
0, //非斜体字
0, //无下划线
0, //无删除线
GB2312_CHARSET, //表示所用的字符集为ANSI_CHARSET
OUT_DEFAULT_PRECIS, //输出精度为缺省精度
CLIP_DEFAULT_PRECIS, //剪裁精度为缺省精度
DEFAULT_QUALITY, //输出质量为缺省值
DEFAULT_PITCH | FF_DONTCARE,//字间距和字体系列使用缺省值
L"微软雅黑" //字体名称
);
SetTextColor(hDC, RGB(255, 0, 0)); //设置文本颜色为蓝色
SetBkColor(hDC, RGB(150, 50, 50)); //设置背景颜色
SelectObject(hDC, myFont); //将自定义字体选入设备环境
TextOutW(hDC, 400, 390, String1, wcslen(String1));//使用当前字体输出文本
DeleteObject(myFont); //删除自定义字体,释放内存
return 0;
}
//主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Message;
if (!InitWindowClass(hInstance, nCmdShow))
{
MessageBox(NULL, _T("创建窗口失败!"), _T("创建窗口"), NULL);
return 1;
}
while (GetMessage(&Message, 0, 0, 0)) //消息循环
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
//消息处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam)
{
//static POINT myPoint[3]; //定义多边形的坐标.
//static POINT cenPoint[1]; //定义多边形的坐标.
//static long i = 0;
//long x[3] = { 20,50,60 }; //定义多边形各点的X和Y坐标
//long y[3] = { 40,20,30 };
HDC hDC; //定义指向设备上下文的句柄
PAINTSTRUCT PtStr; //定义指向包含绘图信息的结构体变量
HBRUSH hBrush; //定义指向画刷的句柄
HPEN hPen; //定义指向画笔的句柄
HFONT myFont; //定义字体句柄
switch (iMessage) //处理消息
{
case WM_CREATE: //设置计时器
SetTimer(hWnd, 5000, 500, NULL); //刷新率60
break;
case WM_TIMER:
{
InvalidateRect(hWnd, NULL, 0); //重绘窗口
}
case WM_PAINT: //处理绘图消息
hDC = BeginPaint(hWnd, &PtStr);
SetMapMode(hDC, MM_TEXT); //设置映像模式
gCnt++;
if (gCnt >= 60)
gCnt = 0;
roll = 30 * sin(gCnt*pi / 300);
pitch = 30 * cos(gCnt*pi / 450);
/*roll = 10;
pitch = 30;*/
myDraw(hDC);//防闪烁
//例行结束
EndPaint(hWnd, &PtStr); //结束绘图
return 0;
case WM_DESTROY: //结束应用程序
PostQuitMessage(0);
return 0;
default: //其他消息处理程序
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
break;
}
return 0;
}
BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow) //定义窗口类
{
WNDCLASSEX wcex;
HWND hWnd;
TCHAR *szWindowClass = (TCHAR *)_T("zjuyr");
TCHAR *szTitle = (TCHAR *)_T("zjuyr");
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = 0; //窗口类型为缺省类型
wcex.lpfnWndProc = WndProc; //窗口处理函数为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(BLACK_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, //窗口左上角的X坐标
0, //窗口左上角的Y坐标
1600, //窗口宽度(请根据需要调整)
800, //窗口高度(请根据需要调整)
NULL,
NULL,
hInstance,
NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow); //显示窗口
UpdateWindow(hWnd);
return TRUE;
}
参考
https://www.bilibili.com/video/BV1cx411Z7Xc
https://mkblog.cn/189/
https://blog.csdn.net/qithon/article/details/104121578
https://blog.csdn.net/u014660247/article/details/52840702
https://www.cnblogs.com/shenchao/archive/2013/06/03/3115684.html
https://www.cnblogs.com/wb-DarkHorse/archive/2013/06/25/3154387.html