用VC5開發監控介面的方法 (轉)
用VC5開發監控介面的方法 (轉)[@more@] 用VC5開發介面的方法
南京師範大學物理系 (伶俐 黃斌 顧敏芬)
VC5開發工具提供了現成的視窗、控制與工具條的製作手段,大大簡化了介面的開發
過程,並且使得開發出的介面具有組態風格,使用起來方便、靈活、簡單易學。
本文以一例項介紹如何實現三個獨立的分離視窗:監視視窗,控制視窗和動畫視窗,
並以圖1中的進水和溫度值傳遞為例,介紹如何實現控制功能和不同視窗間的資料共享,
並介紹實現無閃爍動畫的方法。
(圖略)
如圖1,將工作臺分離成為三個視窗,動畫視窗用於模擬鍋爐的進、出水、升溫的畫
面顯示,其中的畫面與採集的資料相對應。控制視窗用於實現預設溫度值,調節水位、
控制加熱、暫停等功能。監視視窗用來實時跟蹤取樣的溫度值,作出溫度--時間曲線。
一、創立分離視窗
要實現多視窗顯示,必須使用CSplitterWnd類,將視窗分成三個子視窗,然後將各個
功能類與視窗聯絡起來。在建立應用時,在第一步中選擇Single Document Interface, 並
選用中文字型檔,在第4步中按下Advanced,選擇Use Split Window選項。設定應用程式名
為Animation。目前我們只有一個視類CAnimationView,它將與動畫視窗對應,此外我們
還要生成具有對話功能的監視視窗(對應CShowView類)和控制視窗(對應 CControlView
類)。在Re View中調出上下文選單並選擇Insert,選擇屬性為IDD_FORMVIEW,創
建監視對話方塊IDD_SHOWVIEW和控制對話方塊IDD_CONTROLVIEW,並單擊滑鼠右鍵在
Properties選擇項中選擇中文字型檔。然後編輯IDD_CONTROLVIEW:利用VC5提供的
生成器生成ID名為IDC_SETTEMPERATURE的文字編輯域,並生成Caption為“設定溫
度初始值”。再利用button生成器,生成控制元件IDC_WATERIN,IDC_CONFIRM,Caption
分別為“進水”和“確認”。再利用ClassWizard,建立基於CFormView類的新類,分別為
CShowView和CControlView類,並將它們與剛建立的兩個對話方塊聯絡。
在CMainFrame類中,過載OnCreateClient()建立三個靜態分離視窗,先在
MainFrame.h中宣告所需變數:
protected:
CSplitterWnd m_wndSplitter2;
轉入MainFrame.cpp程式,在開頭處包含頭“ShowView.h”,向下找到函式
OnCreateClient(),新增如下程式碼,生成兩個視窗,三個檢視:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT/*lpcs*/,CCreateContext* pContext)
{
//先分裂成兩個視窗,一行兩列
if(!m_wndSplitter.CreateStatic(this,1,2))
{
TRACE0("Failed to CreateStaticSplittern");
return FALSE;
}
// 加上動畫視窗,將其放在左邊
if(!m_wndSplitter.CreateView(0,0,pContext->m_pNewViewClass,CSize(425,50),pContext))
{
TRACE0("Failed to create first panen");
return FALSE;
}
//將第二個視窗再一分為二
if(!m_wndSplitter2.CreateStatic(
&m_wndSplitter, //原來的m_wndSplitter是父指標,m_wndSplitter2是子指標
2,1, //視窗分為兩行,一列
WS_CHILD|WS_VISIBLE|WS_BORDER,m_wndSplitter.IdFromRowCol(0,1)))
{
TRACE0("Failed to create nested splittern");
return FALSE;
}
//增加兩個檢視,並調整檢視大小
if(!m_wndSplitter2.CreateView(0,0,
RUNTIME_CLASS(CShowView),CSize(0,175),pContext))
{
TRACE0("Failed to create second panen");
return FALSE;
}
if(!m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(CControlView),
CSize(0,0),pContext))
{
TRACE0("Failed to create third panen");
return FALSE;
}
return TRUE;
}
再轉入Animation.cpp中,修改InitInstance()函式,將其中的m_pMainWnd->ShowWindow
(SW_SHOW),改為m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);至此,我們
可以生成圖1的介面。
二、動畫顯示視窗的實現
動畫是透過一幅幅的圖片來實現的,因此先將所需的畫面載入資源BITMAP中,
並按順序編輯它們的ID號,然後在定時器中,每隔一定的時間呼叫一次動畫函式。第一
步先生成定時器,用ClassWizard給CAnimationView新增訊息處理程式:OnCreate()函式
對應於訊息WM_CREATE,OnTimer()函式對應於訊息WM_TIMER。編輯函式OnCreate(),
生成每隔0.1秒的時鐘。
int CAnimationView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CView::OnCreate(lpCreateStruct)= = -1)
return -1;
SetTimer(2,100,NULL); //產生每隔0.1秒的時鐘
return 0;
}
在函式OnTimer()中,呼叫動畫服務函式ServicedAnimation(),該函式根據系統情況作出
無閃爍動畫,並可以根據不同的功能,選擇畫面。
void CAnimationView::OnTimer(UINT nvent)
{
CClientDC ClientDC(this);
ServicedAnimation(&ClientDC); //呼叫動畫服務函式
CView::OnTimer(nIDEvent);
}
ServicedAnimation()用於檢查系統的時鐘,並能計算從發生最後一個動畫事件開始計算
起所經過的時間,然後這個函式檢查本幀動畫的延遲時間,並決定是否到達了另一次
的時間,若到了另一次更新的時間,那麼m_nCurrentFrame變數就增加,此時若進水標誌
成功,則呼叫DrawWaterinAnimation(),開始新一幀動畫畫面。如果由於其它原因造成了
到達ServicedAnimation()函式的延遲也計算在內。
先在CAnimationView中,定義變數:
public:
D mLastEventServiced;
BOOL m_bPause, m_bDone; //暫停、動畫終點標誌
int m_nCurrentFrame, m_nFrame; //當前的動畫幀數,總動畫幀數
建構函式中,新增:
CAnimationView::CAnimationView()
{
mLastEventServiced=0;
m_bPause=FALSE;
m_bDone=FALSE;
m_nCurrentFrame=0;
m_nFrame=100; //圖畫的幀數設為100幅
}
編輯ServicedAnimation()函式:
void CAnimationView::ServicedAnimation(CDC* pDC)
{
DWORD Elapsed=0L;
DWORD FirstSample=::GetTickCount();
DWORD WorkValue=mLastEventServiced;
CAnimationDoc *pDoc=(CAnimationDoc*) GetDocument();
ASSERT(pDoc->IsKindOf(TUNTIME_CLASS(CAnimationDoc)));
if(m_bPause||m_bDone) return; //如果動畫被暫停或結束,就返回
while(FirstSample!=WorkValue)
{
WorkValue++;
Elapsed++;
}
//如果Elapsed達到其閾值點,並滿足或超過這幀動畫的延遲值,則可進入下一個程式碼
//資訊塊,這樣,動畫順序將移動到下一幀:
if(Elapsed>=1L) //設定每幀動畫的延遲值都為1
{
m_nCurrentFrame++;
if(m_nCurrentFrame>=m_nFrame)
{
m_nCurrentFrame=0; //將要開始時,應把幀記數置於零
if(!pDoc->m_bWaterInFlagDoc)
{
m_nCurrentFrame=m_nFrame-1;
m_bDone=TRUE;
}
if(pDoc->m_bWaterInFlagDoc&&!m_bDone)
{
DrawAnimationWaterIn(pDC);
m_bWaterInFlagDoc=FALSE;
mLastEventServicced=::GetTickCount(); // 把系統當前的時鐘記錄下來
}
}
}
DrawAnimationWaterIn()為顯示不同的進水水位的畫面的函式,要連續顯示畫面,應將
一幅幅點陣圖宣告成一個靜態陣列。
Static int bitmapswaterin[]= {I_WATERIN1,
IDB_WATERIN2 ...... IDB_WATERIN100};
利用ClassWizard宣告CAnimationView的變數:
protected:
CBitmap bmpWI[100];
CDC dcMemWI[100];
BITMAP bmWI;
在CAnimationView的建構函式里新增如下語句:
for(int i=0;i<100;i++)
{
bmpWI[i].LoadBitmap(bitmapswaterin[i]);
bmpWI[i].Get(sizeof(BITMAP),&bmWI[i]);
}
編輯DrawAnimationWaterIn()函式,在此函式中,應重新宣告bmpWI[100],dcMemWI[100]
為區域性變數,這樣當重新呼叫同一幅點陣圖時,可以及時重新整理,不會引起衝突。
void CAnimationView: DrawAnimationWaterIn(CDC* pDC)
{
CBITMAP bmpWI[100];
CDC dcMemWI[100];
CRect rect;
GetClientRect(rect); //選擇當前使用的矩形視窗
dcMemWI[m_nCurrentFrame].CreateCompatibleDC(pDC); //在記憶體中準備圖象
bmpWI[m_nCurrentFrame].LoadBitmap(bitmapsWaterIn[m_nCurrentFrame]);// 裝載一個
//由lpszResourcceName標識的點陣圖資源,並將它連線到CBitmap上
CBitmap *pOldBitmn=dcMemWI[m_nCurrentFrame].Object
(&bmpWI[m_nCurrentFrame] ); //將GDI物件選入裝置描述表
pDC->BitBlt((recct.right-bmWI[m_nCurrentFrame].bmWidth)/2,
(rect.bottom-bmWI[m_nCurrentFrame].bmHeight)/2,//點陣圖放在視窗正中
bmWI[m_nCurrentFrame].bmWidth,bmWI[m_nCurrentFrame].bmHeight,
&dcMemWI[m_nCurrentFrame],0,0,SRCCOPY);//顯示點陣圖
dcMemWI[m_nCurrentFrame].SelectObject(pOldBitmapIn);
}
三、控制視窗功能的實現
利用ClassWizard中的Member Variables標籤為CControlView增加成員變數。
控制元件
控制元件ID
型別
成員
預設溫度值
IDC_SETTEMPERATURE
int
m_nSetTemperature
在CControlView中增加訊息處理函式:
物件
物件ID
函式
訊息
進水按鍵
IDC_WATERIN
OnWaterIn()
BN_CLICKED
確認按鍵
IDC_CONFIRM
OnComfirm()
BN_CLICKED
下面以輸入預設溫度值和進水響應為例,來講述如何實現控制功能。當控制視窗
(CControlView類)中預置溫度設定之後,按下確認鍵即響應訊息OnConfirm(),在監視視窗
(CShowView類)中的狀態監測圖中畫一條預設溫度的橫線。當控制視窗(CControlView
類)中按下進水鍵,便在動畫檢視(CAnimationView類)有進水動畫產生。
這時控制檢視要向監視檢視、動畫檢視傳送資料,但它們之間無法直接實現資料共享。
MFC類庫中CDocument類及其派生類用來管理工作資料,它能夠讀寫和檢視所要觀
察和處理的資料,並可以同時擁有多個檢視。所以,此處用CDocument的派生類
CAnimationDoc作為資料傳輸的中介,來實現不同視窗之間的資料傳遞。
預置溫度(變數名為m_nSetTemperature)的資料傳送示意圖如圖2所示。
m_nSetTemperature m_nSetTemperatureDoc
圖2 省略
在CAnimationDoc中,設定公共變數:
public:
int m_nSetTemperatureDoc; //用來傳遞m_nSetTemperature的Document派生類變數
BOOL m_bSetTemperatureFlagDoc; //溫度設定成功標誌
BOOL m_bWaterInFlagDoc; //進水標誌
在CAnimationDoc的建構函式中初始化變數:
CAnimationDoc::CAnimationDoc()
{
m_nSetTemperatureDoc=0;
m_bSetTemperatureFlagDoc=FALSE;
m_bWaterInFlagDoc=FALSE;
}
編輯CControlView的OnConfirm()函式:
void CControlView::OnConfirm()
{
CAnimationDoc* pDoc=(CAnimationDoc*) GetDocument();
ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));//找到當前的
//CDocument類
UpdateData(); //更新檢視資料
pDoc->m_nSetTemperatureDoc=m_nSetTemperature;
pDoc->m_bSetTemperatureFlagDoc=TRUE; //預設溫度成功標誌
}
編輯CControlView的OnWaterIn()函式:
void CControlView::OnWater()
{
CAnimationDoc*pDoc=(CAnimationDoc*)GetDocument();
ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));
pDoc->m_bWaterInFlagDoc=TRUE; //進水響應成功
}
最後在ControlView.cpp的開頭包含“AnimationDoc.h"。
然後轉入CShowView中,為了要能達到實時監測的目的,資料的接收要做在定時器中,這
樣才可以不斷地檢測是否有新的資料輸入。檢測到溫度設定標誌後,畫一條橫線。
void CShowView::OnTimer(UINT nIDEvent)
{
CClientDC dc(this);
CAnimationDoc*pDoc=(CAnimationDoc*)GetDocument();
ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));
UpdateData();
If(pDoc->m_bSetTemperatureFlagDoc)
{
dc.MoveTo(0,145-pDoc->m_nSetTemperatureDoc);
dc.Lo(400,145-pDoc->m_nSetTemperatureDoc); //畫一條橫線
pDoc->m_bSetTemperatureFlagDoc=FALSE; //保證只做一次
}
CFormView::OnTimer(nIDEvent);
}
同樣,在CAnimationView中,編輯OnTimer()函式呼叫的過程ServicedAnimation(),檢
測到進水鍵響應成功後,呼叫進水動畫例程DrawAnimationWaterIn()。
四、監視視窗功能的實現
溫度、水位跟蹤實現的原理類似於控制功能,它實現的是CAnimatinDoc與CShowView
類之間的資料傳遞,當系統取樣的溫度與水位變化時,CShowView中的m_nTemperature(溫
度變數)即隨之變化,在利用MoveTo()與LineTo()函式,便可將其畫在圖上。再把這些做
在定時器當中,就可以實時監測。
參考文獻:
1、《Visual C++5開發人員指南》David Bennett機械工業出版社
2、《Visual C++4開發人員指南》tt Stanfield機械工業出版社
3、《MFC開發人員參考手冊》 Robert D. Thompson機械工業出版社
南京師範大學物理系 (伶俐 黃斌 顧敏芬)
VC5開發工具提供了現成的視窗、控制與工具條的製作手段,大大簡化了介面的開發
過程,並且使得開發出的介面具有組態風格,使用起來方便、靈活、簡單易學。
本文以一例項介紹如何實現三個獨立的分離視窗:監視視窗,控制視窗和動畫視窗,
並以圖1中的進水和溫度值傳遞為例,介紹如何實現控制功能和不同視窗間的資料共享,
並介紹實現無閃爍動畫的方法。
(圖略)
如圖1,將工作臺分離成為三個視窗,動畫視窗用於模擬鍋爐的進、出水、升溫的畫
面顯示,其中的畫面與採集的資料相對應。控制視窗用於實現預設溫度值,調節水位、
控制加熱、暫停等功能。監視視窗用來實時跟蹤取樣的溫度值,作出溫度--時間曲線。
一、創立分離視窗
要實現多視窗顯示,必須使用CSplitterWnd類,將視窗分成三個子視窗,然後將各個
功能類與視窗聯絡起來。在建立應用時,在第一步中選擇Single Document Interface, 並
選用中文字型檔,在第4步中按下Advanced,選擇Use Split Window選項。設定應用程式名
為Animation。目前我們只有一個視類CAnimationView,它將與動畫視窗對應,此外我們
還要生成具有對話功能的監視視窗(對應CShowView類)和控制視窗(對應 CControlView
類)。在Re View中調出上下文選單並選擇Insert,選擇屬性為IDD_FORMVIEW,創
建監視對話方塊IDD_SHOWVIEW和控制對話方塊IDD_CONTROLVIEW,並單擊滑鼠右鍵在
Properties選擇項中選擇中文字型檔。然後編輯IDD_CONTROLVIEW:利用VC5提供的
生成器生成ID名為IDC_SETTEMPERATURE的文字編輯域,並生成Caption為“設定溫
度初始值”。再利用button生成器,生成控制元件IDC_WATERIN,IDC_CONFIRM,Caption
分別為“進水”和“確認”。再利用ClassWizard,建立基於CFormView類的新類,分別為
CShowView和CControlView類,並將它們與剛建立的兩個對話方塊聯絡。
在CMainFrame類中,過載OnCreateClient()建立三個靜態分離視窗,先在
MainFrame.h中宣告所需變數:
protected:
CSplitterWnd m_wndSplitter2;
轉入MainFrame.cpp程式,在開頭處包含頭“ShowView.h”,向下找到函式
OnCreateClient(),新增如下程式碼,生成兩個視窗,三個檢視:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT/*lpcs*/,CCreateContext* pContext)
{
//先分裂成兩個視窗,一行兩列
if(!m_wndSplitter.CreateStatic(this,1,2))
{
TRACE0("Failed to CreateStaticSplittern");
return FALSE;
}
// 加上動畫視窗,將其放在左邊
if(!m_wndSplitter.CreateView(0,0,pContext->m_pNewViewClass,CSize(425,50),pContext))
{
TRACE0("Failed to create first panen");
return FALSE;
}
//將第二個視窗再一分為二
if(!m_wndSplitter2.CreateStatic(
&m_wndSplitter, //原來的m_wndSplitter是父指標,m_wndSplitter2是子指標
2,1, //視窗分為兩行,一列
WS_CHILD|WS_VISIBLE|WS_BORDER,m_wndSplitter.IdFromRowCol(0,1)))
{
TRACE0("Failed to create nested splittern");
return FALSE;
}
//增加兩個檢視,並調整檢視大小
if(!m_wndSplitter2.CreateView(0,0,
RUNTIME_CLASS(CShowView),CSize(0,175),pContext))
{
TRACE0("Failed to create second panen");
return FALSE;
}
if(!m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(CControlView),
CSize(0,0),pContext))
{
TRACE0("Failed to create third panen");
return FALSE;
}
return TRUE;
}
再轉入Animation.cpp中,修改InitInstance()函式,將其中的m_pMainWnd->ShowWindow
(SW_SHOW),改為m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);至此,我們
可以生成圖1的介面。
二、動畫顯示視窗的實現
動畫是透過一幅幅的圖片來實現的,因此先將所需的畫面載入資源BITMAP中,
並按順序編輯它們的ID號,然後在定時器中,每隔一定的時間呼叫一次動畫函式。第一
步先生成定時器,用ClassWizard給CAnimationView新增訊息處理程式:OnCreate()函式
對應於訊息WM_CREATE,OnTimer()函式對應於訊息WM_TIMER。編輯函式OnCreate(),
生成每隔0.1秒的時鐘。
int CAnimationView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CView::OnCreate(lpCreateStruct)= = -1)
return -1;
SetTimer(2,100,NULL); //產生每隔0.1秒的時鐘
return 0;
}
在函式OnTimer()中,呼叫動畫服務函式ServicedAnimation(),該函式根據系統情況作出
無閃爍動畫,並可以根據不同的功能,選擇畫面。
void CAnimationView::OnTimer(UINT nvent)
{
CClientDC ClientDC(this);
ServicedAnimation(&ClientDC); //呼叫動畫服務函式
CView::OnTimer(nIDEvent);
}
ServicedAnimation()用於檢查系統的時鐘,並能計算從發生最後一個動畫事件開始計算
起所經過的時間,然後這個函式檢查本幀動畫的延遲時間,並決定是否到達了另一次
的時間,若到了另一次更新的時間,那麼m_nCurrentFrame變數就增加,此時若進水標誌
成功,則呼叫DrawWaterinAnimation(),開始新一幀動畫畫面。如果由於其它原因造成了
到達ServicedAnimation()函式的延遲也計算在內。
先在CAnimationView中,定義變數:
public:
D mLastEventServiced;
BOOL m_bPause, m_bDone; //暫停、動畫終點標誌
int m_nCurrentFrame, m_nFrame; //當前的動畫幀數,總動畫幀數
建構函式中,新增:
CAnimationView::CAnimationView()
{
mLastEventServiced=0;
m_bPause=FALSE;
m_bDone=FALSE;
m_nCurrentFrame=0;
m_nFrame=100; //圖畫的幀數設為100幅
}
編輯ServicedAnimation()函式:
void CAnimationView::ServicedAnimation(CDC* pDC)
{
DWORD Elapsed=0L;
DWORD FirstSample=::GetTickCount();
DWORD WorkValue=mLastEventServiced;
CAnimationDoc *pDoc=(CAnimationDoc*) GetDocument();
ASSERT(pDoc->IsKindOf(TUNTIME_CLASS(CAnimationDoc)));
if(m_bPause||m_bDone) return; //如果動畫被暫停或結束,就返回
while(FirstSample!=WorkValue)
{
WorkValue++;
Elapsed++;
}
//如果Elapsed達到其閾值點,並滿足或超過這幀動畫的延遲值,則可進入下一個程式碼
//資訊塊,這樣,動畫順序將移動到下一幀:
if(Elapsed>=1L) //設定每幀動畫的延遲值都為1
{
m_nCurrentFrame++;
if(m_nCurrentFrame>=m_nFrame)
{
m_nCurrentFrame=0; //將要開始時,應把幀記數置於零
if(!pDoc->m_bWaterInFlagDoc)
{
m_nCurrentFrame=m_nFrame-1;
m_bDone=TRUE;
}
if(pDoc->m_bWaterInFlagDoc&&!m_bDone)
{
DrawAnimationWaterIn(pDC);
m_bWaterInFlagDoc=FALSE;
mLastEventServicced=::GetTickCount(); // 把系統當前的時鐘記錄下來
}
}
}
DrawAnimationWaterIn()為顯示不同的進水水位的畫面的函式,要連續顯示畫面,應將
一幅幅點陣圖宣告成一個靜態陣列。
Static int bitmapswaterin[]= {I_WATERIN1,
IDB_WATERIN2 ...... IDB_WATERIN100};
利用ClassWizard宣告CAnimationView的變數:
protected:
CBitmap bmpWI[100];
CDC dcMemWI[100];
BITMAP bmWI;
在CAnimationView的建構函式里新增如下語句:
for(int i=0;i<100;i++)
{
bmpWI[i].LoadBitmap(bitmapswaterin[i]);
bmpWI[i].Get(sizeof(BITMAP),&bmWI[i]);
}
編輯DrawAnimationWaterIn()函式,在此函式中,應重新宣告bmpWI[100],dcMemWI[100]
為區域性變數,這樣當重新呼叫同一幅點陣圖時,可以及時重新整理,不會引起衝突。
void CAnimationView: DrawAnimationWaterIn(CDC* pDC)
{
CBITMAP bmpWI[100];
CDC dcMemWI[100];
CRect rect;
GetClientRect(rect); //選擇當前使用的矩形視窗
dcMemWI[m_nCurrentFrame].CreateCompatibleDC(pDC); //在記憶體中準備圖象
bmpWI[m_nCurrentFrame].LoadBitmap(bitmapsWaterIn[m_nCurrentFrame]);// 裝載一個
//由lpszResourcceName標識的點陣圖資源,並將它連線到CBitmap上
CBitmap *pOldBitmn=dcMemWI[m_nCurrentFrame].Object
(&bmpWI[m_nCurrentFrame] ); //將GDI物件選入裝置描述表
pDC->BitBlt((recct.right-bmWI[m_nCurrentFrame].bmWidth)/2,
(rect.bottom-bmWI[m_nCurrentFrame].bmHeight)/2,//點陣圖放在視窗正中
bmWI[m_nCurrentFrame].bmWidth,bmWI[m_nCurrentFrame].bmHeight,
&dcMemWI[m_nCurrentFrame],0,0,SRCCOPY);//顯示點陣圖
dcMemWI[m_nCurrentFrame].SelectObject(pOldBitmapIn);
}
三、控制視窗功能的實現
利用ClassWizard中的Member Variables標籤為CControlView增加成員變數。
控制元件
控制元件ID
型別
成員
預設溫度值
IDC_SETTEMPERATURE
int
m_nSetTemperature
在CControlView中增加訊息處理函式:
物件
物件ID
函式
訊息
進水按鍵
IDC_WATERIN
OnWaterIn()
BN_CLICKED
確認按鍵
IDC_CONFIRM
OnComfirm()
BN_CLICKED
下面以輸入預設溫度值和進水響應為例,來講述如何實現控制功能。當控制視窗
(CControlView類)中預置溫度設定之後,按下確認鍵即響應訊息OnConfirm(),在監視視窗
(CShowView類)中的狀態監測圖中畫一條預設溫度的橫線。當控制視窗(CControlView
類)中按下進水鍵,便在動畫檢視(CAnimationView類)有進水動畫產生。
這時控制檢視要向監視檢視、動畫檢視傳送資料,但它們之間無法直接實現資料共享。
MFC類庫中CDocument類及其派生類用來管理工作資料,它能夠讀寫和檢視所要觀
察和處理的資料,並可以同時擁有多個檢視。所以,此處用CDocument的派生類
CAnimationDoc作為資料傳輸的中介,來實現不同視窗之間的資料傳遞。
預置溫度(變數名為m_nSetTemperature)的資料傳送示意圖如圖2所示。
m_nSetTemperature m_nSetTemperatureDoc
圖2 省略
在CAnimationDoc中,設定公共變數:
public:
int m_nSetTemperatureDoc; //用來傳遞m_nSetTemperature的Document派生類變數
BOOL m_bSetTemperatureFlagDoc; //溫度設定成功標誌
BOOL m_bWaterInFlagDoc; //進水標誌
在CAnimationDoc的建構函式中初始化變數:
CAnimationDoc::CAnimationDoc()
{
m_nSetTemperatureDoc=0;
m_bSetTemperatureFlagDoc=FALSE;
m_bWaterInFlagDoc=FALSE;
}
編輯CControlView的OnConfirm()函式:
void CControlView::OnConfirm()
{
CAnimationDoc* pDoc=(CAnimationDoc*) GetDocument();
ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));//找到當前的
//CDocument類
UpdateData(); //更新檢視資料
pDoc->m_nSetTemperatureDoc=m_nSetTemperature;
pDoc->m_bSetTemperatureFlagDoc=TRUE; //預設溫度成功標誌
}
編輯CControlView的OnWaterIn()函式:
void CControlView::OnWater()
{
CAnimationDoc*pDoc=(CAnimationDoc*)GetDocument();
ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));
pDoc->m_bWaterInFlagDoc=TRUE; //進水響應成功
}
最後在ControlView.cpp的開頭包含“AnimationDoc.h"。
然後轉入CShowView中,為了要能達到實時監測的目的,資料的接收要做在定時器中,這
樣才可以不斷地檢測是否有新的資料輸入。檢測到溫度設定標誌後,畫一條橫線。
void CShowView::OnTimer(UINT nIDEvent)
{
CClientDC dc(this);
CAnimationDoc*pDoc=(CAnimationDoc*)GetDocument();
ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CAnimationDoc)));
UpdateData();
If(pDoc->m_bSetTemperatureFlagDoc)
{
dc.MoveTo(0,145-pDoc->m_nSetTemperatureDoc);
dc.Lo(400,145-pDoc->m_nSetTemperatureDoc); //畫一條橫線
pDoc->m_bSetTemperatureFlagDoc=FALSE; //保證只做一次
}
CFormView::OnTimer(nIDEvent);
}
同樣,在CAnimationView中,編輯OnTimer()函式呼叫的過程ServicedAnimation(),檢
測到進水鍵響應成功後,呼叫進水動畫例程DrawAnimationWaterIn()。
四、監視視窗功能的實現
溫度、水位跟蹤實現的原理類似於控制功能,它實現的是CAnimatinDoc與CShowView
類之間的資料傳遞,當系統取樣的溫度與水位變化時,CShowView中的m_nTemperature(溫
度變數)即隨之變化,在利用MoveTo()與LineTo()函式,便可將其畫在圖上。再把這些做
在定時器當中,就可以實時監測。
參考文獻:
1、《Visual C++5開發人員指南》David Bennett機械工業出版社
2、《Visual C++4開發人員指南》tt Stanfield機械工業出版社
3、《MFC開發人員參考手冊》 Robert D. Thompson機械工業出版社
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988833/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 開源監控系統Prometheus介紹Prometheus
- 前端監控SDK開發分享前端
- 用C#開發Windows服務監控系統使用C#Windows
- C# 開發技巧 輕鬆監控方法執行耗時C#
- Django開發Web監控工具-pyDashDjangoWeb
- (轉)開源IT監控系統對比
- 海康安防產品-[監控]影片監控原理介紹
- 3-主機監控、應用監控
- Linux下很全面的監控工具dstatLinux
- Linux下應用程式開發:QT開發簡介(轉)LinuxQT
- 監控oracle的觸發器語句(轉)Oracle觸發器
- 用python指令碼監控併發量Python指令碼
- WINDOWS鍵盤事件監控原理及應用 (轉)Windows事件
- 效能監控方面的一些SQL語句SQL
- MongoDB監控方法總結MongoDB
- sessions,processes的監控方法Session
- 信貸風控模型開發----模型簡介模型
- 監控平臺前端SDK開發實踐前端
- 淘寶開發的系統監控工具 Tsar 開源
- 路由閘道器網路管理和監控功能介紹(轉)路由
- 一種對雲主機進行效能監控的監控系統及其監控方法
- Oracle常用監控SQL(轉)OracleSQL
- 【IT運維監控】幾大運維監控工具優缺點介紹運維
- 化工能耗管理系統開發能源線上監控系統開發
- Linux流量監控工具 - iftop (最全面的iftop教程)Linux
- 監控Oracle資料庫方法Oracle資料庫
- Flutter效能監控工具(1)--- Observatory簡介Flutter
- 001.常見監控簡介
- MyCAT的命令列監控工具介紹命令列
- MongoDB自帶的監控工具介紹MongoDB
- hp_unix glance監控工具介紹
- 為你介紹4個超實用的Linux監控工具Linux
- 開源監控利器grafanaGrafana
- 費用管控定製開發
- 叢集式數字監控應用模型研究(一) (轉)模型
- Solaris記憶體監控(轉)記憶體
- 雪亮工程視訊監控系統建設方案重點人員監控系統開發
- 網站安全監控的方法講解,網站安全監控技術網站