当前位置:文档之家› vc++编程技术600个大型项目源码《特别编》

vc++编程技术600个大型项目源码《特别编》

vc++编程技术600个大型项目源码《特别编》
vc++编程技术600个大型项目源码《特别编》

VC如何得到文件夹的路径

一、

经常需要用到“选择文件夹”对话框,相应的API已经很好用,但稍嫌麻烦,所以我专门将其封装了一下,力求一步到位。

函数封装如下:

CString GetPath()

{

CString strPath = "";

BROWSEINFO bInfo;

ZeroMemory(&bInfo, sizeof(bInfo));

bInfo.hwndOwner = m_hWnd;

bInfo.lpszTitle = _T("请选择路径: ");

bInfo.ulFlags = BIF_RETURNONLYFSDIRS;

LPITEMIDLIST lpDlist; //用来保存返回信息的IDList

lpDlist = SHBrowseForFolder(&bInfo) ; //显示选择对话框

if(lpDlist != NULL) //用户按了确定按钮

{

TCHAR chPath[255]; //用来存储路径的字符串

SHGetPathFromIDList(lpDlist, chPath);//把项目标识列表转化成字符串

strPath = chPath; //将TCHAR类型的字符串转换为CString类型的字符串

}

return strPath;

}

调用时只需要用到以下代码:

CString strPath = GetPath();

则strPath为用户选择的文件夹路径。如果用户点击了对话框的取消键,则strPath为空字符串("");

本文来自CSDN博客,转载请标明出处:https://www.doczj.com/doc/c64474684.html,/zztxl/archive/2009/04/17/4088092.aspx

二、

本程序的功能为:在对话框中的一个命令按钮的事件中,打开一个浏览文件夹对话框,让用户选择文件夹的路径,并把路径的名称显示在标题栏中。

函数代码如下:

void CEyesDectectDlg::OnButtonGetDir()

{

CString strDir;

BROWSEINFO lpbi;

TCHAR lpDir[MAX_PATH];

CString path("");

lpbi.hwndOwner = this->m_hWnd;

lpbi.pidlRoot = NULL; // 默认路径

lpbi.pszDisplayName = lpDir;

lpbi.lpszTitle = _T("请选择文件夹:");

lpbi.ulFlags = BIF_RETURNONLYFSDIRS ;

lpbi.lpfn = NULL;

lpbi.lParam = NULL;

lpbi.iImage = NULL;

LPITEMIDLIST lpidl = :: SHBrowseForFolder(&lpbi);

if(lpidl)

if (SHGetPathFromIDList(lpidl, lpDir))

{

strDir = lpDir;

this->SetWindowText(strDir);

return ;

}

}

常用的宽字符函数和安全CRT函数

宽字符类型和函数是C和C++标准(ANSI/ISO/IEC C 1999和ISO/IEC C++ 1998/2003)新增加的内容,它们是用来支持国际通用的Unicode(1993)字符集的。微软公司从Visual C++ 2005版起,开始严格执行C/C++的新标准。

安全CRT函数是微软公司对C/C++语言的扩展,其中的部分内容已于2003

年提交给ISO作为C/C++标准下一版本的修改建议。在VC05/08中,如果不使用这些安全性函数,编译器会报告警告性错误。

1)常用的宽字符函数

由于Windows NT/2000/XP采用的是Unicode字符编码,字符都是双字节的。所以在MFC编程中,一般需要使用双字节的字符类型wchar_t和对应的字符串及其指针类型LPCWSTR和LPCTSTR,并在常数字符串前添加了L转换符,串长计算

函数不能用strlen而改用wcslen,串格式打印函数也不能用sprintf,而是改用swprintf(字符和串格式符也从%c和%s改为%lc和%ls)。

wchar_t类型,在标准C++中为内置的数据类型和关键字;在C99标准中则为typedef类型,其等价的数据类型与具体的实现有关,在Win32和VC中定义为:

typedef unsigned short wchar_t; (双字节的无符号短整数)下面是若干常用的宽字符函数(包含在ISO C99 / ISO C++的标准库中):#include

size_t wcslen(const wchar_t *s);

int wprintf(const wchar_t * format, ...);

int wscanf(const wchar_t * format, ...);

int swprintf(wchar_t * s, size_t n, const wchar_t * format, ...);

int swscanf(const wchar_t * s, const wchar_t * format, ...);

long int wcstol(const wchar_t * nptr, wchar_t ** endptr, int base); float wcstof(const wchar_t * nptr, wchar_t ** endptr);

double wcstod(const wchar_t * nptr, wchar_t ** endptr);

#include

errno_t _itow_s( int value, wchar_t *buffer, size_t sizeInCharacters, int radix );

errno_t _ultow_s( unsigned long value, wchar_t *str, size_t sizeOfstr, int radix );

size_t mbstowcs( wchar_t *wcstr, const char *mbstr, size_t count ); size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_t count );

2)常用的安全CRT函数

安全CRT(C Runtime Library = C运行时间库)函数,是微软公司对C/C++语言的扩展。它在原来函数名后添加了“_s”后缀;一般返回出错代码;并将原来的函数返回值,作为一个参数,添加到函数输入参数列表的最后;对带缓冲区参数的函数,还添加了表示缓冲区大小的输入参数,以防止内存溢出。

在VC05/08中,如果不使用这些安全性函数,编译器会报告警告性错误。

下面是若干常用的安全CRT函数:

char *gets_s( char *buffer, size_t sizeInCharacters); // wchar_t *_getws_s( wchar_t *buffer, size_t sizeInCharacters); // or

errno_t _itoa_s( int value, char *buffer, size_t sizeInCharacters, int radix ); //

errno_t _itow_s( int value, wchar_t *buffer, size_t sizeInCharacters, int radix ); //

errno_t _ultoa_s( unsigned long value, char *str, size_t sizeOfstr, int radix ); //

errno_t _ultow_s( unsigned long value, wchar_t *str, size_t sizeOfstr, int radix ); //

int printf_s( const char *format [, argument]... ); //

int wprintf_s( const wchar_t *format [, argument]... ); // or

int scanf_s( const char *format [, argument]... ); //

int wscanf_s( const wchar_t *format [, argument]... ); // or

int sprintf_s( char *buffer, size_t sizeOfBuffer, const char *format [, argument] ... ); //

int swprintf_s( wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format [, argument]...); // or

int sscanf_s( const char *buffer, const char *format [, argument ] ...);

//

int swscanf_s( const wchar_t *buffer, const wchar_t *format [, argument ] ...); // or

int fprintf_s( FILE *stream, const char *format [, argument ]...); //

int fwscanf_s( FILE *stream, const wchar_t *format [, argument ]... );

// or

int fscanf_s( FILE *stream, const char *format [, argument ]... ); //

int fwscanf_s( FILE *stream, const wchar_t *format [, argument ]... );

// or

errno_t strcpy_s( char *strDestination, size_t sizeInBytes, const char *strSource ); //

errno_t wcscpy_s( wchar_t *strDestination, size_t sizeInWords, const wchar_t *strSource ); // or

errno_t fopen_s( FILE** pFile, const char *filename, const char *mode ); //

errno_t _wfopen_s( FILE** pFile, const wchar_t *filename, const wchar_t *mode ); // or

errno_t mbstowcs_s( size_t *pConvertedChars, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count ); // errno_t wcstombs_s( size_t *pConvertedChars, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count ); // errno_t rand_s( unsigned int* randomValue); // 下面是若干安全函数原型用到的数据类型的定义:

#include

typedef int errno_t;

typedef unsigned short wchar_t;

#ifdef _WIN64

typedef unsigned __int64 size_t;

#else

typedef _W64 unsigned int size_t;

#endif

3)[宽]字符串转换

可以利用L运算符和若干函数在[单字节/多字节的]普通字符串和[双字节的]宽字符串之间进行相互转换。

●char -> wchar_t

?L运算符

在串常量前加上L运算符,可以将普通字符串转换为宽字符串;例如:

wchar_t *wstr = L"A string to a wide character string.";

CString str = L"A string to a wide character string.";

MessageBox(L"创建位图出错!", L"错误");

?AllocSysString函数

可以利用CString类的AllocSysString()函数来将普通字符串转换成宽

字符串:

BSTR AllocSysString() const;

其中BSTR相当于wchar_t *的typedef类型。例如:

CString str("A string to a wide character string.");

wchar_t *wstr = str.AllocSysString();

MessageBox(wstr);

说明:CString类是VC中定义的MFC/ATL共享模板类CStringT的一个实现:template< typename BaseType, class StringTraits > class CStringT :

public CSimpleStringT

StringTraits > ::c_bIsMFCDLLTraits> //

typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString; //

?mbstowcs[_s]函数

可以用中定义的多字节字符串到宽字符串的C语言转换函

数:

size_t mbstowcs( wchar_t *wcstr, const char *mbstr, size_t

count );

// 成功返回被转换的字符数,失败返回-1

// 若wcstr = NULL,则返回所需宽字符串的大小(宽字符数)errno_t mbstowcs_s( size_t *pConvertedChars, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count ); //

成功返回0

来将普通[多字节]字符串转换为宽字符串。例如:

char *str = "A sample string.";

wchar_t wstr[80];

size_t cn = 0; // 输出参数,用于存放被转换的字符数,包括null

结束符'\0'

if (!mbstowcs_s(&cn, wstr, 80, str, strlen(str)))

MessageBox(wstr);

else MessageBox(L"转换字符串出错!");

wchar_t -> char(只能用于西文串,不能用于中文串)

只能利用中定义的宽字符串到多字节字符串的C语言转换函数:(返回值同前)

size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_t

count );

errno_t wcstombs_s( size_t *pConvertedChars, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count );

来将宽字符串转换为普通[多字节]字符串。例如:

char str[80];

wchar_t *wstr = L"A sample string.";

size_t cn = 0; // 输出参数,用于存放被转换的字符数,包括null

结束符'\0'

if (wcstombs_s(&cn, str, 80, wstr, wcslen(wstr))) MessageBox(L"

转换字符串出错!");

又例如:

int m, n;

const size_t bufSize = 300;

char buf[bufSize];

wchar_t wbuf[bufSize];

CString fn = pDoc->GetPathName();

wcscpy_s(wbuf, bufSize, fn);

size_t cn = 0;

wcstombs_s(&cn, buf, bufSize, wbuf, bufSize);

FILE *stream;

if (!fopen_s(&stream, buf, "rt")) {

fscanf_s(stream, "%d %d", &m, &n);

//……

}

算法中的精确时间计数器的应用

评价一个算法的好坏,在运行时所消耗的时间是一个很重要的参数,可以反应出该算法的时间复杂度。要测试一个程序运行时所消耗的时间,我们可以写出很多种算法。很多编译器都提供了相关的时间函数库,还有系统的API等等。但是,我们会发现这些函数在程序中根本本能得到满意的结果。有时候设计得很好的算法,或者很小的算法,在运行的时候非常快,在1ms以内,这时候要测试这个算法所消耗的时间就是一件不容易的事情。

在头文件time.h中有个函数clock(),返回clock_t的类型,可以通过两次调用clock函数,来确定时间间隔。API中有一个函数叫做GetTickCount的函数,可以得到当前计算机运行的时间,它返回一个DWORD 值。在程序短之前加入一句DWORD t=GetTickCount();在程序段后加入t=GetTickCount()-t,则t的结果就是此程序段运行的时间。但是我们会发现很多程序段的结果输出都是0ms,所以我们需要比这个精度更高的函数。有没有这样的函数呢,通过查询MSDN,发现有两个函数满足要求,QueryPerformanceFrequency 和QueryPerformanceCounter,它可以精确到0.5微秒,具体说明可以参见MSDN。为了方便我们以后在对算法时间的计算,我们把他封装成一个计时器类:

#include

#include

using namespace std;

class TimeTake{

public:

TimeTake():dCount(0)

{

// 获得计数器的时钟频率

QueryPerformanceFrequency(&lPoint);

dFreq=(double)lPoint.QuadPart;

}

~TimeTake()

{

}

void print()

{

cout<

}

void start()

{

//第一次取计数器的值

QueryPerformanceCounter(&lPoint);

lPart=lPoint.QuadPart;

}

void end()

{

//再一次取计数器的值并计算中间的时间间隔,表示成ms

QueryPerformanceCounter(&lPoint);

dCount=(double(lPoint.QuadPart-lPart)/dFreq)*1000;

}

private:

LARGE_INTEGER lPoint;

LONGLONG lPart;

double dFreq, dCount;

};

我们可以写三个算法,用其对他们进行测试,下面几个算法都是求最大公约数的问题,第二个是第一个算法的改进,第三个是求使得a*m+b*n=d的最大公因数,详细算法如下:

DWORD mode1(DWORD m,DWORD n)

{

int r=m%n;

while(r!=0)

{

m=n;

n=r;

r=m%n;

}

return n;

}

DWORD mode2(DWORD m,DWORD n)

{

DWORD r,result;

while(1)

{

r=m%n;

if(r==0)

{

result=n;

break;

}

m=n%r;

if(m==0)

{

result=r;

break;

}

n=r%m;

if(n==0)

{

result=m;

break;

}

}

return result;

}

//求接a,b使得am+bn=d,d为最大公倍数DWORD mode(DWORD m,DWORD n,int& a,int& b) {

int al,bl; //求解al,bl使得al*m+bl*n=c; DWORD c,d,q,r,t;

c=m;

d=n;

b=al=1;

while(1)

{

q=c/d;

r=c%d;

if(r==0)

break;

else

{

c=d; d=r;

t=al;

al=a;

a=t-q*a;

t=bl;

bl=b;

b=t-q*b;

}

}

return d;

}

然后编写主程序进行测试:

int _tmain(int argc, _TCHAR* argv[])

{

TimeTake tk;

int a,b;

DWORD m,n,d1,d2;

cout<<"please input m and n"<

cin>>m>>n;

while(n==0)

{

cout<<"n can't be zero,please input n again!"<>n;

}

tk.start();

d1=mode1(m,n);

cout<<"the mode 1's result is "<

tk.print();

tk.start();

d2=mode2(m,n);

cout<<"the mode 2's result is "<

tk.end();

tk.print();

tk.start();

d2=mode(m,n,a,b);

cout<<"the result is "<

if(b>=0)

cout<<"*m+"<

else

cout<<"*m"<

tk.end();

tk.print();

return 0;

}

输出结果如下:

please input m and n

150

456

the mode 1's result is 6

1.9469 ms elapse in the algothim!

the mode 2's result is 6

1.23787 ms elapse in the algothim!

the result is -3*m+1*n=6

1.18842 ms elapse in the algothim!

Press any key to continue

通过多组数据的输入,我们可以肯定的是第二种算法比第一种算法用的时间少,因为第二种算法避免了第一种算法的重复赋值。但是第三种算法与前两种算法相比,体现出时间的不确定性,有时候时间处于前两种算法之间,有时候又比前两种都少。从表面上来看,第三种算法比前两种做的事情都要多,但是为什么他用的时间最少呢?

如何使用MSChart

void CMoreDMcode::OnCacluteDelta(int nRow)

{

m_Chart.SetRedraw(false);

m_Chart.SetRow(1);

for(int i=1;i<=64;i++)

{

m_Chart.GetDataGrid().SetData(i,1,nDelta[i-1],0);

}

CRgn rgn;

m_Chart.GetUpdateRgn(&rgn);

m_Chart.SetRedraw(true);

m_Chart.InvalidateRgn(&rgn,false) ;

}

void CMoreDMcode::InitChart()

{

VARIANT var;

m_Chart.SetColumnCount(1); //设置曲线条数

m_Chart.SetRowCount(64); //一条曲线有64个点

m_Chart.SetTitleText("二位形态码△t变化趋势");

m_Chart.SetChartType(1|2);//

//m_Chart.SetShowLegend(TRUE);

//设置X轴

m_Chart.GetPlot().GetAxis(0,var).GetCategoryScale().SetAuto(FALSE); // 不自动标注X轴刻度

m_Chart.GetPlot().GetAxis(0,var).GetCategoryScale().SetDivisionsPerLabel(8);// 每四刻度一个标注

m_Chart.GetPlot().GetAxis(0,var).GetCategoryScale().SetDivisionsPerTick(8); // 每刻度一个刻度线

//m_Chart.GetPlot().GetAxis(0,var).GetValueScale().SetMinorDivision(1); // 每刻度一个刻度线m_Chart.GetPlot().GetAxis(0,var).GetValueScale().SetMaximum(64); // X轴最大刻度

m_Chart.GetPlot().GetAxis(0,var).GetValueScale().SetMinimum(0); // X轴最小刻度

m_Chart.GetPlot().GetAxis(0,var).GetAxisTitle().SetText("二位形态码");

//设置Y轴

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetAuto(FALSE); // 不自动标注Y轴刻度

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetMaximum(100); // Y轴最大刻度

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetMinimum(0); // Y轴最小刻度

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetMajorDivision(10); // Y轴刻度10等分

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetMinorDivision(1); // 每刻度一个刻度线

//m_Chart.GetPlot().GetAxis(1,var).GetAxisTitle().SetText("△t变化趋势"); // Y轴名称

//m_Chart.GetPlot().GetAxis(1,var).GetAxisTitle().GetTextLayout().SetOrientation(2);//Y轴名称排列方式

m_Chart.GetPlot().SetUniformAxis(FALSE);

}

void CMoreDMcode::OnMSChartDraw()

{

CString str;

int nRow = m_Grid.GetFocusCell().row;

if (nRow<0)

{

MessageBox("请在左表选择要排序的行!","操作错误",MB_OK|MB_ICONWARNING);

return;

}

for(int i=0;i<64;i++)

{

str = m_Grid.GetItemText(nRow,i+3);

nDelta[i] = atoi(str.GetBuffer(0));

}

InitChart();//初始化坐标轴

// 根据不同的数据设定不同的Y轴最大刻度

int m = GetMaxData(nDelta);

m=(m/50)*50+50;//取靠近M的比M大的50的倍数

str = m_Grid.GetItemText(nRow,0);

VARIANT var;

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetMaximum(m);

OnCacluteDelta(nRow);//绘图

str = "当前绘制的是第"+str+"期的△t变化趋势";

m_Tip.SetWindowText(str);

}

函数名字取得不好,大家见笑了,开始取名字错误,后来不想该了,呵呵^_^

====================================================

图表由于其直观明了的特性,在实际应用中十分很广泛。我们常常希望数据能通过图表来显示其特性。例如在Delphi和C++Builder编程中,我们可以很方便地实现数据图表。MsChart(6.0或5.0版)是Windows 系统中Visual studio自带的一个ACTIVEX控件,它功能强大,应用广泛,具有以下特点:

·支持随机数据和随机数组,动态显示。

·支持所有主要的图表类型。

·支持三维显示。

MsChart具有45个属性,9个方法,49 事件,可灵活编程,可实现各类表的显示。

1 MsChart应用编程

首先插入MsChart控件,

在工程中加入mschart

菜单->Project->Add To Project->Components and Controls->Registered ActiveX Controls->Microsoft Chart Control, version 6.0 (OLEDB)

1.1 坐标系属性的设置

a)纵轴初始化属性

Mschart默认支持自动标准,将自动调整,可以缺省设置。

#i nclude "mschart.h" //添加相关的头文件

#i nclude "VcAxis.h"

#i nclude "VcAxisTitle.h"

#i nclude "VcTextLayout.h"

#i nclude "VcDataGrid.h"

#i nclude "VcPlot.h"

#i nclude "VcValueScale.h"

#i nclude "VcSeriesCollection.h"

#i nclude "VcSeries.h"

#i nclude "VcPen.h"

#i nclude "VcCategoryScale.h"

#i nclude "VcColor.h"

#i nclude "VcDataGrid.h"

#i nclude "VcBackdrop.h"

#i nclude "VcFill.h"

#i nclude "VcBrush.h"

#i nclude "VcDataPoints.h"

#i nclude "VcDataPoint.h"

#i nclude "VcDataPointLabel.h"

#i nclude "VcAxisTitle.h"

//最好添加全部头函数,

CMSChart m_Chart;//m_Chart 为图表变量

VARIANT var;

m_Chart.GetPlot().GetAxis(1,var)//获取纵轴

//设置是否支持自动标准;控件默认支持自动标准。

m_Chart.GetPlot().GetAxis().GetValuesScale().SetAuto(FALSE);

//设置最大刻度为M;

m_Chart.GetPlot().GetAxis().GetValuesScale().SetMaximum(M);

//设置最小刻度为m;

m_Chart.GetPlot().GetAxis().GetValuesScale().SetMinimum(m);

//设置轴的等分数D;

m_Chart.GetPlot().GetAxis().GetValuesScale().SetMajorDivision(D);

//设置每等分的刻度线数n;

m_Chart.GetPlot().GetAxis().GetValuesScale().SetMinorDivision(n);

b)横轴初始化属性

VARIANT var;

m_Chart.GetPlot().GetAxis(0,var)//获取横轴

其他属性设置跟纵轴相同。

1.2 数据显示

a)设置标题栏和标签

m_Chart.SetTitleText(“标题”);//设置标题栏

m_Chart.SetRowLabel((“第I行”);//设置第i行标签

m_Chart.SetColumnLabel((“第j列”);//设置第j列标签

b)行列的显示布局

MSChart的行列显示布局有其自身的特点:下面显示是一个行列4×3(矩形图),即(四行,三列)的布局示意图。

m_Chart.SetRowCount(4); //没条曲线三个四个点(曲线图)

m_Chart.SetColumnCount(3); //设置曲线条数为三条(曲线图)

c)行列操作

// 操作行列第i行、第j列

m_Chart.SetRow(i);// 第i行

m_Chart.SetColumn(j);//第j行

m_Chart.SetRowLabel((“第i行”);//设置第i行标签CString str=”90.5”;

m_Chart.SetData((LPCTSTR(str)); //设置行列,j>的显示数据m_Chart.Refresh();//刷新视图

d)显示方式

获取当前的显示方式:

long nType =m_Chart.GetChartType();

设置显示方式:

m_Chart.SetChartType(0);//3D(三维) 显示

m_Chart.SetChartType(1);//2D(二维) 显示

m_Chart.Refresh();

其它常用组合方式为:

m_Chart.SetChartType(1|0) //2D柱(条)形,

m_Chart.SetChartType(0|0) //3D柱(条)形

m_Chart.SetChartType(1|2) //2D线条型

m_Chart.SetChartType(0|2) //3D线条型

m_Chart.SetChartType(1|4) //2D区域型

m_Chart.SetChartType(0|4) //3D区域型

m_Chart.SetChartType(1|6) //2D阶梯型

m_Chart.SetChartType(0|6) //3D阶梯型

m_Chart.SetChartType(1|8) //2D复(混)合型

m_Chart.SetChartType(0|8) //3D复(混)合型

另外,在2D方式中,还有两类:饼型和XY型

m_Chart.SetChartType(14) //2D 饼型

m_Chart.SetChartType(16) //2DXY型

e)其他

其他属性,比如设置字体,颜色,对齐方式等。

//====================================================

//VC知识库上的参考文章

https://www.doczj.com/doc/c64474684.html,/document/viewdoc/?id=959

3.3 设置 m_Chart void CDemoView::InitChart()

{

// 设置标题

m_Chart.SetTitleText("mschart示例 by thinkry@https://www.doczj.com/doc/c64474684.html,");

// 下面两句改变背景色

m_Chart.GetBackdrop().GetFill().SetStyle(1);

m_Chart.GetBackdrop().GetFill().GetBrush().GetFillColor().Set(255, 255, 255);

// 显示图例

m_Chart.SetShowLegend(TRUE);

m_Chart.SetColumn(1);

m_Chart.SetColumnLabel((LPCTSTR)"1号机");

m_Chart.SetColumn(2);

m_Chart.SetColumnLabel((LPCTSTR)"2号机");

m_Chart.SetColumn(3);

m_Chart.SetColumnLabel((LPCTSTR)"3号机");

// 栈模式

// m_Chart.SetStacking(TRUE);

// Y轴设置

VARIANT var;

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetAuto(FALSE); // 不自动标注Y轴刻度

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetMaximum(100); // Y轴最大刻度

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetMinimum(0); // Y轴最小刻度

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetMajorDivision(5); // Y轴刻度5等分

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().SetMinorDivision(1); // 每刻度一个刻度线m_Chart.GetPlot().GetAxis(1,var).GetAxisTitle().SetText("小时"); // Y轴名称

// 3条曲线

m_Chart.SetColumnCount(3);

// 线色

m_Chart.GetPlot().GetSeriesCollection().GetItem(1).GetPen().GetVtColor().Set(0, 0, 255);

m_Chart.GetPlot().GetSeriesCollection().GetItem(2).GetPen().GetVtColor().Set(255, 0, 0);

m_Chart.GetPlot().GetSeriesCollection().GetItem(3).GetPen().GetVtColor().Set(0, 255, 0);

// 线宽(对点线图有效)

m_Chart.GetPlot().GetSeriesCollection().GetItem(1).GetPen().SetWidth(50);

m_Chart.GetPlot().GetSeriesCollection().GetItem(2).GetPen().SetWidth(100);

m_Chart.GetPlot().GetSeriesCollection().GetItem(3).GetPen().SetWidth(2);

// 数据点类型显示数据值的模式(对柱柱状图和点线图有效)

// 0: 不显示 1: 显示在柱状图外

// 2: 显示在柱状图内上方 3: 显示在柱状图内中间 4: 显示在柱状图内下方

m_Chart.GetPlot().GetSeriesCollection().GetItem(1).GetDataPoints().GetItem(-1).GetDataPointL abel().SetLocationType(1);

m_Chart.GetPlot().GetSeriesCollection().GetItem(2).GetDataPoints().GetItem(-1).GetDataPointL abel().SetLocationType(1);

m_Chart.GetPlot().GetSeriesCollection().GetItem(3).GetDataPoints().GetItem(-1).GetDataPointL abel().SetLocationType(1);

}

3.4 设置数据 void CDemoView::DrawChart()

{

int nRowCount = 6;

m_Chart.SetRowCount(nRowCount);

VARIANT var;

// 不自动标注X轴刻度

m_Chart.GetPlot().GetAxis(0,var).GetCategoryScale().SetAuto(FALSE);

// 每刻度一个标注

m_Chart.GetPlot().GetAxis(0,var).GetCategoryScale().SetDivisionsPerLabel(1);

// 每刻度一个刻度线

m_Chart.GetPlot().GetAxis(0,var).GetCategoryScale().SetDivisionsPerTick(1);

// X轴名称

m_Chart.GetPlot().GetAxis(0,var).GetAxisTitle().SetText("日期");

char buf[32];

srand( (unsigned)time( NULL ) );

for(int row = 1; row <= nRowCount; ++row)

{

m_Chart.SetRow(row);

sprintf(buf, "%d号", row);

m_Chart.SetRowLabel((LPCTSTR)buf);

m_Chart.GetDataGrid().SetData(row, 1, rand() * 100 / RAND_MAX, 0);//设置第一条曲线的第row个

m_Chart.GetDataGrid().SetData(row, 2, rand() * 100 / RAND_MAX, 0);//设置第二条曲线的第row个点

m_Chart.GetDataGrid().SetData(row, 3, rand() * 100 / RAND_MAX, 0);//设置第三条曲线的第row个点

}

m_Chart.Refresh();

}

/*

SetData (row, column, dataPoint, nullFlag)

SetData 方法语法包括以下组成部分:

row Integer 类型。标识包含数据点值的行。

column Integer 类型。标识包含数据点值的列。

dataPoint Double 类型。数据点值。

nullFlag Integer 类型。指示数据点值是否为空

*/

3.5 改变显示类型 // 折线图

void CDemoView::OnChartLine()

{

m_Chart.SetChartType(3);

DrawChart();

}

// 柱状图

void CDemoView::OnChartCombi()

{

m_Chart.SetChartType(1);

DrawChart();

}

// 饼状图

void CDemoView::OnChartPie()

{

m_Chart.SetChartType(14);

DrawChart();

}

VC++6.0中MsChart控件的用法

VC++6.0中MsChart控件的用法

1. MSChart制图类

1.1 添加MSChart控件

MSChart是VC++6.0中自带的一个特殊控件类,用于绘制坐标曲线图。如果要使用这个控件,则可以按下图的示意进行添加此控件。

1.2 MSChart控件的使用方法

首先在要使用的类的实现文件中包含如下头文件:

#include "VcPlot.h"

#include "VcAxis.h"

#include "VcValueScale.h"

#include "VcSeriesCollection.h"

#include "VcSeries.h"

#include "VcPen.h"

#include "VcCategoryScale.h"

#include "VcColor.h"

#include "VcDataGrid.h"

#include "VcBackdrop.h"

#include "VcFill.h"

#include "VcBrush.h"

#include "VcDataPoints.h"

#include "VcDataPoint.h"

#include "VcDataPointLabel.h"

#include "VcAxisTitle.h"

#include "math.h"

在要使用的类的头文件中包含:

#include "mschart.h"

本系统中按照如下函数调用来实现MSChart类绘制故障树重要度曲线的功能(CDrawImp是调用MSChart的类)。

1.2.1 类中变量定义

class CDrawImp : public CDialog

{

// Construction

public:

void DrawChart(int type);

void initmschart();

CMSChart m_Chart;

……

}

1.2.2 类中MSChart的初始化函数

void CDrawImp::initmschart()

{

// 下面两句改变背景色

m_Chart.GetBackdrop().GetFill().SetStyle(1);

// 显示图例

m_Chart.SetShowLegend(FALSE);

m_Chart.SetColumn(1);

m_Chart.SetChartType(3);

// 栈模式

m_Chart.SetStacking(FALSE);

相关主题
文本预览
相关文档 最新文档