Visual C 的程式設計兩問題

2021-07-24 16:19:38 字數 2931 閱讀 1351

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設定為乙個不同的值,就可使得對話方塊有不同的標題。

2009-01-01                       

Visual C 程式設計疑難問題解

前言 程式設計中遇到的問題很多,再優秀的程式設計師也不會沒有問題,但很多解決方法被淹沒在論壇浩瀚的 水 中了,為了便於同道查詢同時儲存這些精華,我將在實際程式設計中常見的問題以及論壇中優秀的回貼收集起來以專題的形式發表。本文中的所有問題及回答均來自論壇。問題一 如何實現指定碟符的光碟機彈出彈入 鑰匙...

Visual C 的選單程式設計

選單是軟體介面設計的乙個重要組成方面。它描述著乙個軟體的大致功能和風格。所以在程式設計中處理好 設計好選單,對於乙個軟體開發是否成功有著比較重要的意義。visual c 是.net框架中的乙個重要組成部分,也是微軟公司推出的下一代主流程式開發語言。它在設計 開發程式介面的時候和以前的某些程式開發語言...

Visual C 的Excel程式設計

excel是微軟公司辦公自動化套件中的乙個軟體,他主要是用來處理電子 excel以其功能強大,介面友好等受到了許多使用者的歡迎。在辦公的時候,正是由於excel的這麼多的優點,許多重要的資料,往往以excel電子 的形式儲存起來。這樣就給程式設計師帶來了乙個問題,雖然excel功能比較強大,但畢竟不...