山東科技大學智慧型工程研究所 楊在春 何明祥
microsoft visual c++是一種視覺化程式語言,因功能強大而受到廣大程式設計人員的青睞。但是,由於vc++的應用程式框架結構非常複雜,使得許多初學者望而卻步。本文通過對設定檢視背景顏色和改變對話方塊標題的幾種實現方法的分析研究,揭示了vc++程式**執行時的一些本質特徵和有關的程式設計技巧,對理解mfc庫的結構和windows作業系統的內部工作方式提供了一定的幫助。
設定檢視背景顏色
對於vc++文件、視結構中的檢視,從使用者的角度來看,只是可以改變大小、位置的普通視窗,同其他基於windows應用程式的視窗是一樣的;從程式設計師的角度來看,檢視並不是普通的視窗,而是從mfc庫中cview類派生的類物件。像任何vc++物件一樣,檢視物件的行為由類的成員函式(資料成員)決定,包括派生類中應用程式定義的函式和從基類繼承來的函式。
提出問題
檢視的背景一般來說是白色的,在預設情況下,它和系統定義的顏色color_window是一致的。設計者一般會希望自己的程式可以讓使用者輕鬆地改變視窗背景顏色,或是用漂亮的來充填背景。我們可以用windows函式setsyscolors來重新指定color_window所對應的實際顏色,來達到改變檢視背景顏色的目的。但這樣會同時改變其他應用程式的檢視視窗背景,使得整個windows系統的顏色設定產生混亂。另外,我們可能會用以下方法來設定檢視的背景顏色,即在cview的ondraw函式中添寫如下一段程式**:
void ctestview::ondraw(cdc* pdc)
這樣可以達到改變當前應用程式的檢視背景的目的,但同時也產生了一些不良影響,使得程式執行效果不盡如人意。
分析問題
我們知道,在vc++的文件、視結構中,cview的ondraw函式用於實現絕大部分圖形繪製的工作。如果使用者改變視窗尺寸,或者顯示隱藏的區域,ondraw函式都將被呼叫來重畫視窗。並且,當程式文件中的資料發生改變時,一般必須通過呼叫檢視的invalidate(或invalidaterect)成員函式來通知windows所發生的改變,對invalidate的呼叫也會觸發對ondraw函式的呼叫。正因為ondraw函式被頻繁呼叫,所以在其執行時,每次都重新整理填充一次檢視客戶區域,便會使螢幕不穩定,產生閃爍現象。
筆者通過對vc++應用程式框架結構和windows訊息對映系統的仔細研究,找到另外一種改變檢視背景的方法,其執行效果比上述兩種方法都好。其實在程式呼叫ondraw函式之前,會觸發乙個windows訊息:wm_erasebkgnd,以擦除檢視重新整理區域。在預設情況下,windows系統使用檢視視窗註冊時視窗類中的成員hbrbackground所描述的畫刷來擦除螢幕,這一般會將螢幕重新整理成color_window所對應的顏色。因此,在ondraw函式中設定背景顏色的執行過程是這樣的:先將螢幕重新整理成color_window所對應的顏色,接著又在ondraw函式中填充其他顏色,這正是產生螢幕閃爍的根本原因。
解決問題
通過上述分析,我們應將檢視背景顏色填充移到windows訊息:wm_erasebkgnd所對應的訊息對映函式中,而不是在ondraw函式中。我們可以通過下列步驟實現這一過程:在文件類中增加一成員變數m_viewbkcolor儲存當前背景顏色,同時增加兩個成員函式getviewbkcolor和setviewbkcolor對其進行讀寫操作。這樣做的好處是可以對m_viewbkcolor成員進行序列化,將其和文件聯絡在一起,開啟某一文件時,其背景將和上一次程式操作該文件時的背景保持一致。在檢視類中為檢視的windows訊息wm_erasebkgnd增加訊息對映函式onerasebkgnd,**如下:
bool ctestview::onerasebkgnd(cdc* pdc)
在該函式中不需要對客戶區域矩形進行裝置座標到邏輯座標的轉換,並且windows在呼叫該函式時會自動進行裁剪區域的計算,使得需要重新整理的螢幕面積達到最小。這樣我們可以在程式中通過設計下列選單函式輕鬆地改變檢視背景的顏色,而且執行效果相當令人滿意。
void ctestview::onchangeviewbkcolor()
}改變對話方塊標題
提出問題
在vc++程式設計過程中經常會遇到這樣的情況:執行程式的多個地方需要呼叫同乙個對話方塊,但在不同的情況下希望給對話方塊加上不同的標題。開始我們可能會用下面的一段程式以達到這一目的:
ctestdialog dlg;
dlg.setwindowtext(「標題-1");
dlg.domodal();
利用上述辦法,我們本希望在程式不同的地方,通過設定函式setwindowtext不同的引數,以達到使同一對話方塊具有不同標題的目的,但這樣做是行不通的。
分析問題
利用這種方法,當執行該段程式時,在乙個可以忽略的錯誤之後,對話方塊的標題不會發生任何改變。這是因為,vc++程式設計中,大部分窗體是動態建立的。比如上述對話方塊,在對dlg.domodal的呼叫之前,雖然已構造了對話方塊的vc++物件,但窗體物件還沒有被建立,顯然對乙個沒有建立窗體物件的對話方塊設定標題是行不通的。另外,dlg.domodal的呼叫結束時,對話方塊窗體物件將立即被釋放,因此在該函式之後設定對話方塊標題也是不行的。
解決問題
通過對vc++框架結構中函式的呼叫順序的分析,我們發現在dlg.domodal執行的開始時,程式會自動呼叫對話方塊的一系列初始化函式,其中包括對對話方塊成員函式oninitdialog的呼叫,從這裡入手,將找到改變對話方塊標題的辦法。為此,首先為對話方塊引進乙個型別為cstring的公有成員變數m_strcaption,並將上述程式段改為:
ctestdialog dlg;
dlg.m_strcaption = 「標題-1";
dlg.domodal();
然後過載對話方塊的虛成員函式oninitdialog如下:
bool ctestdialog::oninitdialog()
通過這種辦法,每次在開啟對話方塊之前,只要將對話方塊公有成員變數m_strcaption設定為乙個不同的值,就可使得對話方塊有不同的標題。
小 結
本文介紹的2個技巧有乙個相似之處,就是用於解決問題的程式實現**基本上是相同的,只是被放在了程式流程的不同地方。這正是學習和熟練掌握vc++的乙個非常重要的方面,是影響其程式執行效率和效能的關鍵。
Visual C 的程式設計技巧
microsoft visual c 是一種視覺化程式語言,因功能強大而受到廣大程式設計人員的青睞。但是,由於vc 的應用程式框架結構非常複雜,使得許多初學者望而卻步。本文通過對設定檢視背景顏色和改變對話方塊標題的幾種實現方法的分析研究,揭示了vc 程式 執行時的一些本質特徵和有關的程式設計技巧,對...
Visual C 程式設計技巧小結
example handle hinstance afxgetinstancehandle 2.如何通過 獲得應用程式主視窗的指標?主視窗的 指標儲存在cwinthread m pmainwnd中,呼叫 afxgetmainwnd實現。afxgetmainwnd showwindow sw show...
Visual C 程式設計技巧之二
9.如何改變視窗的圖示?向視窗傳送wm section訊息。example assert hicon afxgetmainwnd sendmessage wm section,true,lparam hicon 10.如何改變視窗的預設風格?重栽cwnd precreatewindow並修改crea...