當前位置:編程學習大全網 - 編程語言 - 誰有mschrt20.ocx這個控件的所有屬性說明,VB編程使用的

誰有mschrt20.ocx這個控件的所有屬性說明,VB編程使用的

進行程序設計時,選用壹個合適的ActiveX控件,有時可大大減少編程工作量。ActiveX?控件(又稱OCX)基於COM技術,作為獨立的軟件模塊,它可以在任何程序設計語言中插入使用。本文僅以VC++為例說明Chart控件的使用。?

Chart控件指Mschart.ocx(5.0版)或Mschrt20.ocx(6.0?版),是Visual?Studio自帶的ActiveX控件之壹,其屬性、事件很多,功能非常強大,可實現柱狀直方圖、曲線走勢圖、餅狀比例圖等,甚至可以是混合圖表,可以是二維或三維圖表,可以帶或不帶坐標系,可以自由配置各條目的顏色、字體等等。?

壹?安裝和使用Chart控件

在用到Chart控件的項目中安裝該控件:從Project->Add?to?Project->Components?And?Controls->Registered?Active?Xcontrols,選擇Chart控件,則?ClassWizard會生成相應的C++類,其中類CMSChart是由CWnd派生來的,它是Chart?控件的主要類,其他的類全部是由COleDispatchDriver派生來,控制控件中的相應對象,完成各部分相關功能,如CvcAxis類是實現坐標軸相關功能的源代碼。同時在項目的控件工具箱上會出現代表Chart控件的按鈕,使用時把Chart控件按鈕從工具箱拖到對話框中,調整大小即可。?

Chart控件至少有45個屬性、9個方法、49個事件,在這裏就不壹壹列舉了。?

在設計中,我們可以在主要屬性頁裏修改各屬性的屬性值:右擊對話框窗口中的Chart控件,選擇“Properties”菜單項,就會彈出主要屬性頁對話框,對其中各屬性值進行設置。有些屬性在主要屬性頁裏沒有列出,只能編程修改。另外要動態繪制圖表,必須掌握對控件的編程控制。?

首先在對話框類中定義控件變量,以便編程時操縱控件。如對話框類定義如下:?class?CAbcDlg?:?public?CDialog{

public:

CAbcDlg(CWnd*?pParent?=?NULL);

//{{AFX_DATA(CAbcDlg)

enum?{?IDD?=?IDD_ABC_DIALOG?};

CMSChart m_Chart;

//}}AFX_DATA

......

};

ActiveX控件的屬性和方法在控件內部對應唯壹壹個整數索引值,編程時可以通過索引來設置或獲取控件的屬性值,也可以通過調用控件的C++類(在這裏就是CMSChart)的成員函數設置或獲取控件的屬性值及調用控件的方法。例如:?

在CMSChart類實現中有如下代碼:?CString?CMSChart::GetData(){

CString?result;

InvokeHelper(0x9,?DISPATCH_PROPERTYGET,

VT_BSTR,?(void*)&result,?NULL);

return?result;

}

void?CMSChart::SetData(LPCTSTR?lpszNewValue){

static?BYTE?parms[]?=VTS_BSTR;

InvokeHelper(0x9,?DISPATCH_PROPERTYPUT,

?VT_EMPTY,?NULL,?parms,lpszNewValue);

}

void?CMSChart::Refresh(){

InvokeHelper(DISPID_REFRESH,?

DISPATCH_METHOD,?VT_EMPTY,?NULL,?NULL);

}

這段代碼表明:屬性“Data”索引值為0x9,我們可以調用函數SetData對圖表中某點的值進行設置。索引值為DISPID_REFRESH的方法?“Refresh”,調用它進行刷新。如:?CString?str=“34.5";

m_Chart.SetData(str);

m_Chart.Refresh();

......

閱讀CMSChart類的實現會發現,有些屬性的值不是普通的BOOL、CString等數據類型,而是另壹個控件驅動類的類變量,如:?CVcPlot?CMSChart::GetPlot(){

LPDISPATCH?pDispatch;

InvokeHelper(0x28,?DISPATCH_PROPERTYGET,

VT_DISPATCH,?(void*)&pDispatch,?NULL);

return?CVcPlot(pDispatch);

}

在CVcPlot類的實現中有如下代碼:?CVcAxis?CVcPlot::GetAxis

(long?axisID,?const?VARIANT&?Index){

LPDISPATCH?pDispatch;

static?BYTE?parms[]?=VTS_I4?VTS_VARIANT;

InvokeHelper(0x1f,?DISPATCH_PROPERTYGET,

VT_DISPATCH,?(void*)&pDispatch,?parms,?axisID,?&Index);

return?CVcAxis(pDispatch);

}

而CVcAxis類的實現中有如下代碼:?CVcValueScale?CVcAxis::GetValueScale(){

LPDISPATCH?pDispatch;

InvokeHelper(0x9,?DISPATCH_PROPERTYGET,

VT_DISPATCH,?(void*)&pDispatch,?NULL);

return?CVcValueScale(pDispatch);

}

而CVcValueScale類的實現中又有如下代碼:?void?CVcValueScale::SetMaximum(double?newValue){

static?BYTE?parms[]?=VTS_R8;

InvokeHelper(0x3,?DISPATCH_PROPERTYPUT,

VT_EMPTY,?NULL,?parms,newValue);

}

這正是Chart控件的靈活性所在,根據上述代碼,如下的調用: VARIANT?var;

m_Chart.GetPlot().GetAxis(1,?var).GetValueScale()

.SetMaximum(50.0);

可實現把縱坐標的最大刻度設為50.0。

控件觸發的事件,如Click、MouseDown等,如果需要處理,可以通過ClassWizard在對話框類中定義相應的處理函數,實現相關的處理功能。?

二?動態繪制圖表實例

在壹個溫度采集系統中,希望把采集來的各項溫度值實時顯示,用Chart控件繪制曲線走勢圖:?

各溫度項以不同顏色的曲線表示;?

橫坐標為時間,縱坐標為溫度值,均要求滾動顯示;?

在每次采樣完成後,刷新屏幕。?

設計思路?

隨著時間的推移,采集來的數據不斷增加,不壹定在壹屏中顯示,所以系統打開壹個實時數據庫,存放采集來的實時數據。顯示時,需要哪個時間段的數據,就從數據庫中讀取。?

在對話框資源編輯時,增加水平滾動條和垂直滾動條,以便配合Chart控件進行滾動顯示。?

為對話框啟動定時器,按采樣間隔進行采樣,並刷新屏幕顯示。?

主要相關代碼如下:?BOOL?CAbcDlg::OnInitDialog(){

CDialog::OnInitDialog();

pDataDB?=?new?dbase;

//實時數據記錄庫,類dbase的基類為CDaoRecordset

pDataDB->Open(dbOpenDynaset,?“select

*?from?data");

VARIANT?var;

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().

SetAuto(FALSE);//不自動標註y軸刻度

m_Chart.GetPlot().GetAxis(1,?var).GetValueScale().

SetMaximum(37);//y軸最大刻度

m_Chart.GetPlot().GetAxis(1,?var).GetValueScale().

SetMinimum(32);//y軸最小刻度

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().

SetMajorDivision(5);//y軸刻度5等分

m_Chart.GetPlot().GetAxis(1,var).GetValueScale().

SetMinorDivision(1);//每刻度壹個刻度線

m_Chart.SetColumnCount(3);?//3個溫度項,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(2);//線寬

m_Chart.GetPlot().GetSeriesCollection().

GetItem(2).GetPen().SetWidth(2);

m_Chart.GetPlot().GetSeriesCollection().

GetItem(3).GetPen().SetWidth(2);

m_Chart.SetRowCount(10);?//壹屏顯示10個采樣時刻

m_Chart.GetPlot().GetAxis(0,var).GetCategoryScale().

SetAuto(FALSE);//不自動標註x軸刻度

m_Chart.GetPlot().GetAxis(0,var).GetCategoryScale().

SetDivisionsPerLabel(1);//每時刻壹個標註

m_Chart.GetPlot().GetAxis(0,var).GetCategoryScale().

SetDivisionsPerTick(1);//每時刻壹個刻度線

? m_ScrLeft.SetScrollRange(0,45);

?//垂直滾動條可滾動範圍(溫度值範圍0-50,

? 每滾動1度,壹屏顯示5度)

m_ScrLeft.SetScrollPos(45-32);//垂直滾動條的當前位置

m_ScrBottom.SetScrollRange(0,?0);//水平滾動條的可滾動範圍

m_ScrBottom.SetScrollPos(0);//水平滾動條的當前位置

SetTimer(23,?300000,?NULL);//啟動定時器,定時間隔5分鐘

Sample();//調用采樣函數進行第壹次采樣,並把數據記錄入庫

?return?TRUE;?

}

void?CAbcDlg::OnTimer(UINT?nIDEvent)?{

Sample();//采樣,並把數據記錄入庫

if?(pDataDB->GetRecordCount()>10)

theApp.nBottomRange?=?pDataDB->GetRecordCount()-10;

else

theApp.nBottomRange?=?0;?

//用全局變量保存水平滾動條的範圍值

m_ScrBottom.SetScrollRange(0,theApp.nBottomRange);

theApp.nBottomPos?=?theApp.nBottomRange;

m_ScrBottom.SetScrollPos(theApp.nBottomPos);

//修正水平滾動條的顯示

DrawPic();//調用函數,刷新曲線顯示

CDialog::OnTimer(nIDEvent);

}

void?CAbcDlg::DrawPic()?{

char?s[10];

UINT?row?=?1;

pDataDB->MoveFirst();

pDataDB->Move(theApp.nBottomPos);

//只從數據庫中取某時間段的數據進行顯示

while?((!pDataDB->IsEOF())?&&?(row?<=?10)){

m_Chart.SetRow(row);

m_Chart.SetRowLabel((LPCTSTR)pDataDB

->m_date_time.Format(“%H:%M"));

//以采樣時刻做x軸的標註

m_Chart.SetColumn(1);

sprintf(s,?“%6.2f",?pDataDB->m_No1);

m_Chart.SetData((LPCSTR)s);

m_Chart.SetColumn(2);

sprintf(s,?“%6.2f",?pDataDB->m_No2);

m_Chart.SetData((LPCSTR)s);

m_Chart.SetColumn(3);

sprintf(s,?“%6.2f",?pDataDB->m_No3);

m_Chart.SetData((LPCSTR)s);

pDataDB->MoveNext();

row++;

}

while?((row?<=?10)){

m_Chart.SetRow(row);

m_Chart.SetRowLabel((LPCTSTR)“");

m_Chart.GetDataGrid().SetData(row,?1,?0,?1);

//采樣數據不足10個點,?對應的位置不顯示

m_Chart.GetDataGrid().SetData(row,?2,?0,?1);

m_Chart.GetDataGrid().SetData(row,?3,?0,?1);

row++;

}

m_Chart.Refresh();

}

void?CAbcDlg::OnHScroll(UINT?nSBCode,?

UINT?nPos,?CScrollBar*?pScrollBar)?{

if?(pDataDB->GetRecordCount()>10)

theApp.nBottomRange?=?pDataDB->GetRecordCount()-10;

else

theApp.nBottomRange?=?0;

m_ScrBottom.SetScrollRange(0,?theApp.nBottomRange);

switch?(nSBCode){

case?SB_LINERIGHT:

if?(theApp.nBottomPos?<?theApp.nBottomRange){

theApp.nBottomPos?=?theApp.nBottomPos?+?1;

m_ScrBottom.SetScrollPos(theApp.nBottomPos);

DrawPic();

}

break;

case?SB_LINELEFT:

if?(theApp.nBottomPos?>?0){

theApp.nBottomPos?=?theApp.nBottomPos?-?1;

m_ScrBottom.SetScrollPos(theApp.nBottomPos);

DrawPic();

}

break;

}

CDialog::OnHScroll(nSBCode,?nPos,?pScrollBar);

}

void?CAbcDlg::OnVScroll(UINT?nSBCode,?

UINT?nPos,?CScrollBar*?pScrollBar)?{

VARIANT?var;

double?max1,min1,f;

switch?(nSBCode){

case?SB_LINEDOWN:

f?=?m_Chart.GetPlot().GetAxis(1,?var).

GetValueScale().GetMinimum()?-?1;

if?(f>=0)?{//最小刻度大於等於0,?則可以滾動

m_Chart.GetPlot().GetAxis(1,?var).GetValueScale().

SetMinimum(f);

f?=?m_Chart.GetPlot().GetAxis

(1,?var).GetValueScale().GetMaximum()?-?1;

m_Chart.GetPlot().GetAxis(1,?var).GetValueScale().

SetMaximum(f);

pScrollBar->SetScrollPos(pScrollBar->GetScrollPos()?+?1);

m_Chart.Refresh();

}

break;

case?SB_LINEUP:

f?=?m_Chart.GetPlot().GetAxis(1,?var).

GetValueScale().GetMaximum()?+?1;

if?(f?<=?50)?{//最大刻度小於等於50,?則可以滾動

m_Chart.GetPlot().GetAxis

(1,?var).GetValueScale().SetMaximum(f);

f?=?m_Chart.GetPlot().GetAxis(1,?var).

GetValueScale().GetMinimum()?+?1;

m_Chart.GetPlot().GetAxis(1,?var).GetValueScale().

SetMinimum(f);

pScrollBar->SetScrollPos(pScrollBar->GetScrollPos()?-?1);

m_Chart.Refresh();

}

break;

}

CDialog::OnVScroll(nSBCode,?nPos,?pScrollBar);

}

特別註意,程序中用到的關於控件的類,如CVcAxis等,需要在AbcDlg.cpp文件的開始處說明:#include?“VcAxis.h"。?

限於篇幅,文中僅僅是壹個簡單示例的部分代碼。在實際應用中,壹般會有更多的需求,比如:對坐標軸進行縮放顯示;采樣有可能得不到正確的采樣值時曲線顯示不連續等等,這時需要根據需求編寫相應代碼。

  • 上一篇:剛學多線程的壹點小問題
  • 下一篇:北師大版小學四年級上冊語文課件:《林中樂隊》
  • copyright 2024編程學習大全網