当前位置:C++技术网 > 精选软件 > VIP咨询问题解答:用Win32绘制三角函数sin曲线

VIP咨询问题解答:用Win32绘制三角函数sin曲线

更新时间:2018-11-10 10:36:39浏览次数:1+次

    网站推出VIP会员咨询服务后,一些同学真的需要,就加入了。对此非常感谢信任和支持。
    一VIP会员在研究Win32画图的问题,因为这个比较复杂,也牵扯到代码,所以需要用文章来分析。虽然会员费不多,但是我们本来就是象征性的收取一点。我们依然会认真的解答会员每一个问题,而且在这个过程中,我们自己研究学习也是有很大的收获。予人玫瑰,手有余香,这个就是了。
    对于绘制数学上的各种曲线,本文的代码都是可以实现的。你只需要在其中计算坐标点的位置,改变计算的函数即可。解决问题不是关键,让你真正吸收领会学到才是关键。我们更多的是在学习,以我们更多的经验和基础带着初学者们学习,少走弯路。
    那么正题就是用C++使用Win32的API函数绘制曲线,标注坐标和刻度值。这个很多人都想尝试,可能各种原因没做出来或者也没有时间去研究,所以,也很有必要分析发布出来。算是解答VIP会员后大家沾的一点福利吧。哈哈哈。
    那么下面是程序运行的截图:
  VIP咨询问题解答:用Win32绘制三角函数sin曲线
    下面是实现的代码:
#include <windows.h>
#include <math.h>// - 数学函数
#include  <sstream>// - C++格式化字符串需要
using namespace std;
LRESULT CALLBACK MywndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstacne,HINSTANCE hPreview,PSTR CmdLine,int CmdShow)
{
	WNDCLASS wndcls;
	wndcls.cbClsExtra = 0;
	wndcls.cbWndExtra = 0;
	wndcls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndcls.hCursor = LoadCursor(NULL,IDC_ARROW);
	wndcls.hIcon = LoadIcon(NULL,IDI_APPLICATION);
	wndcls.hInstance = hInstacne;
	wndcls.lpfnWndProc = MywndProc;
    wndcls.lpszClassName = TEXT("bear");
	wndcls.lpszMenuName = NULL;
	wndcls.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

	if(!RegisterClass(&wndcls))
	{
		MessageBox(NULL,TEXT("此程序需要Windows NT系统的支持!"),TEXT("小熊提示"),MB_ICONERROR);
		return 0;
	}
	HWND hwnd = CreateWindow(TEXT("bear"),TEXT("小熊"), WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX,
		100,100,500,600,NULL,NULL,hInstacne,NULL);
    ShowWindow(hwnd,CmdShow);
	UpdateWindow(hwnd);

	MSG msg;
	while(GetMessage(&msg,NULL,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

LRESULT CALLBACK MywndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	static int cxClient,cyClient;
	double y = 0;
	PAINTSTRUCT ps;
	double pa=3.1415;
    switch(uMsg)
	{
	case WM_SIZE:// - 窗口大小改变时的消息
		cxClient = LOWORD(lParam);// - 存储窗口的宽度
		cyClient = HIWORD(lParam);// - 存储窗口的高度
		return 0;
	case WM_PAINT:// - 窗口绘画消息
		hdc = BeginPaint(hwnd,&ps);// - 获取绘画DC
		SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL);// - 将坐标点设置到窗口的中央
		SetMapMode(hdc,MM_LOENGLISH);//设置映射模式,让坐标正负方向与数学的xy轴一致
		TextOut(hdc,-150,170,"C++技术网 VIP会员解答",strlen("C++技术网 VIP会员解答"));
		TextOut(hdc,-150,150,"算法代码程序效果图",strlen("算法代码程序效果图"));
		// - 画坐标
		// - 从左到右
		MoveToEx(hdc,-cxClient/2,0,NULL);
		LineTo(hdc,cxClient/2,0);
		// - 从下到上
		MoveToEx(hdc,0,-cyClient/2,NULL);
		LineTo(hdc,0,cyClient/2);
		// - 水平刻度线
		for (float i=-cxClient;i<=cxClient;i+=3.14/4)
		{
			// - C++格式化字符串
			ostringstream ostr;
			ostr << i/100;
			string str = ostr.str();
			// - 隔一定距离画水平刻度线
			if((int)i%50==0)
			{
				// - 画水平刻度线
				MoveToEx(hdc,i,0,NULL);
				LineTo(hdc,i,5);
			}
		}
		// - 垂直刻度线和刻度值
		for (float i=-cyClient;i<=cyClient;i++)
		{
			ostringstream ostr;
			ostr << i/100;
			string str = ostr.str();
			if((int)i%50==0)
			{
				TextOut(hdc,5,i,str.c_str(),str.length());
				MoveToEx(hdc,0,i,NULL);
				LineTo(hdc,5,i);
			}
		}
		EndPaint(hwnd,&ps);
		return 0;
    case WM_LBUTTONDOWN:
		hdc = GetDC(hwnd);// - 获取窗口绘制的DC
		// - 因为这个DC和WM_PAINT消息的DC不是同一个DC,所以还要设置原点坐标和坐标轴方向
		SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL);//设置坐标原点
		SetMapMode(hdc,MM_LOENGLISH);//设置映射模式,让坐标正负方向与数学的xy轴一致
		MoveToEx(hdc,-cxClient/2,0,NULL);// - 移动原点到x轴最左边
		TextOut(hdc,-150,130,"三角函数sin曲线图",strlen("三角函数sin曲线图"));// - 输出函数说明信息
		// - 计算坐标值和绘图
		for (double x=-cxClient/2;x<=cxClient/2;x+=0.01)
		{
			// - 通过公式来计算x,y的值,形成坐标点
			//y = x*x*x;
			//y = tan(x);
			y = sin(x);
			//y = x;
			//y = cos(x);
			// - 划线,因为间隔很小,所以看上去曲线比较光滑
			LineTo(hdc,x*15,y*100);// - 放大坐标的倍数,是让曲线扩展下,让曲线看起来更舒服
		}
		ReleaseDC(hwnd,hdc);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd,uMsg,wParam,lParam);
}

代码说明:
1.如果你对数学函数不清楚,不知道有哪些数学函数,请参考《C语言库函数功能分类简述列表之标准C语言数学函数》。
2.Win32的代码就不在这里说明了,在《Windows零基础入门教程》的前面章节,已经你有很多介绍了。
3.我们这里使用了C++的方法格式化了字符串,而不是使用C语言的方法,请参考《C++如何格式化字符串,超简单实现C++格式化字符串功能
4.因为代码注释很详细了,有明确的思路流程了。
5.VIP群里有完整项目文件,不过你可以直接将代码完整复制放在自己建立的win32项目里即可。