?? 07.5 對話框伸縮功能的實現.txt
字號:
7.5 對話框伸縮功能的實現
先讓我們看看 Windows提供的畫圖程序中的一個功能,單擊畫圖程序的【顏色】菜單下的【編輯顏色】菜單項,將出現編輯顏色對話框,如圖 7.31所示。當單擊該對話框上的【規定自定義顏色】按鈕時,該對話框將擴展為如圖 7 .3 2所示的樣子。
圖 7.3 1原始的畫圖程序編蟹顏色對話框 圖 7.32擴展后的畫圖程序編輯顏色對話框
下面為讀者介紹如何實現對話框的擴展與收縮功能。首先,在 Mybole程序中的測試
對話框上再添加一個按鈕,并在其屬性對話框中將其 Caption設置為:"收縮<<"。當 Mybole
程序運行時,用戶單擊此按鈕后,將把這個測試對話框切除一部分,并且把此按鈕的文本
改成:"擴展》飛當用戶再次單擊這個"擴展"按鈕時,程序還原整個對話框。關于在程
序中動態修改按鈕的文本,可以參考上面的程序中 .lJ且i
修改靜態文本控件文本的實現代碼。首先需要給這
個按鈕添加一個命令響應函數,這可以通過 ClassWizard來完成,也可以直接在這個按鈕上雙擊 IOn8utlOnl ......…:…I_C ICICED 0.,... 10: IOC_BUIION1 旦旦」
鼠標左鍵,即可彈出如圖 7.33所示的添加成員函數 圖 7.33 Add Member Function對話框
的對話框。
從圖 7.33可以看出,這個對話框的功能就是為"收縮<<"按鈕添加鼠標單擊消息 ( BN_CLICKED )響應函數。直接單擊【 OK】按鈕,程序將會跳轉到這個函數的定義處。通過這種方法,就能夠很方便地為對話框添加了一個鼠標單擊按鈕的響應函數。在此函數中,首先實現鼠標單擊按鈕后按鈕文本發生變化這一功能,具體實現代碼如例 7-28所示。
例 7-28
void CTestDlg : : OnButto丑 1 ( )
// TODO: Add your control notification handler code here CString str;
if(GetDlgltemText(i DC-BUTTON1, str ), str == "收縮 << " )
SetDlgItemText(IDC_BUTTON1,"擴展 >> "};
else
SetDlgltemText(工 DC_BUTTON1,"收縮 << ");
上述例 7-28所示代碼中,首先獲得了 IDC_BUTTONl按鈕的文本,然后對該文本進行判斷,如果是"收縮<<",那么將該按鈕的文本改變為"擴展》":否則將其還原為"收縮<<"。
Build并運行 Mybole程序,打開測試對話框,單擊【收縮《】按鈕,該按鈕的文本立即變為"擴展》飛再次單擊此按鈕,其文本又還原為"收縮<<"。也就是說,隨著鼠標的單擊,該按鈕的文本在"收縮<<"和"擴展>>"之間來回切換。
下面在測試對話框資源中放置一個分隔條,用來劃分對話框中要動態切除的部分。這個分隔條可以通過 VC I I提供的圖像控件來實現。首先用鼠標單擊資源控件面板上的圖像控件,然后在測試對話框資源窗口中靠近底部的位置處拖動鼠標拉出一條線。這時的測試對話框資源如圖 7 .3 4所示。
打開這個圖片控件的屬性對話框(如圖 7.35所示),可以看到它的 ID也是 IDC_ STATIC,我們首先將其 m改為 IDC_SEPERATOR,然后打開 Styles選項卡,選中 Sunken選項,這樣,這條分隔條就會呈現出一種下陷的狀態。
下面就要實現這樣的功能:當單擊【收縮《】按鈕時,對話框顯示新添的這條"分隔條"以上的內容:當單擊【擴展》】按鈕時,對話框還原為原來的樣子。為了還原對話框,需要保存其原始位置,對話框的原始位置通過調用 GetWindowRect函數就能得到。那么如何確定收縮后的對話框大小呢?我們注意到,當切除掉"分隔條"以下部分后,對話框的左上角坐標,以及對話框的寬度井沒有改變,發生變化的只是右下角的縱坐標。也就是說,我們只要得到切除后的對話框右下角的縱坐標,也就得到了切除后的對話框的大小和位置。要得到切除后的對話框右下角的縱坐標,就要利用我們所添加的圖像控件窗口 (作為分隔條使用〉。我們可以在圖像控件對象上調用 GetWindowRect函數來得到圖像控件窗口的大小和位置,它的右下角縱坐標也就是收縮后的對話框的右下角縱坐標。
具體的實現代碼如例 7-29所示(其中灰色部分為新添的代碼)。例 7-29 '
void CTestDlg : :OnButtonl()
11 TODO : Add your control notification handler code here CString stri if (GetDlgltemText (IDC_BUTTON1 , str) , str "收縮 << " )
SetDl g工 temText(IDC_BUTTON1,"擴展 >> 11 ) ;
e lse
SetDlgltemText(IDC_ BUTTON1 , '收縮<< " ) i
}
static CRect rec飛 Largei
static CRect rectSmalli
if(rectLarge.工 sRectNull ( ) )
CRect rectSeparatori
GetWindowRect(&rectLarge) i
GetDlg工 tem( 工 DC_SEPARATOR)->GetWindowRect(&rectSeparator)i
rectSmall.left=rectLarge.left;
rectSmall.top=rectLarge.toPi
rectSmall.right=rectLarge.righti
" I 251
第 7童對話框〈一〉
rectSmall.bottom=rectSeparator.bottom;
if(str=="收縮<<" ) SetWindowPos(NULL, O, O, rectSmall.Width() , rectSmall.Height() , SWP_NOMOVE I SWP_NOZORDER); else SetWindowPos(NULL, O, O, rectLarge.Width() , rectLarge.Height() , SWP_NOMOVE I SWP_NOZORDER);
在新添加的代碼中,首先定義了兩個矩形變量: rectLarge和 rectSmall,分別用來保存對話框原始尺寸和切除部分區域之后的尺寸。并且當第一次單擊【收縮《】按鈕獲得這兩個尺寸后,以后再次單擊此按鈕時,并不需要再去設置這兩個變量的值,因此,將這兩個變量定義為靜態變量。
接下來,判斷對話框的原始尺寸是否己經被賦值。 CRect類有兩個成員函數可以用來判斷一個矩形是否為空:
. IsRectEmpty
檢測矩形區域是否為空。如果矩形的寬度和高度為 O或是一個負值,則說明此矩形為空,返回非零值:否則,返回 0。
. IsRectNull
如果矩形的左上角和右下角的四個坐標值都是 0,貝Ij此函數返回一個非零值:否則,返回 0。可以通過下面的例子來看看這兩個函數的區別,首先定義了兩個矩形變量 :
CRect rectl(10 , 10 , 10, 10);
CRect rect2(O , O, O, O);
于是, IsRectEmpty (rect1)和 IsRectEmpty ( rect2)調用都將返回一個非零值, IsRectNull
( rect2)調用也將返回一個非零值,但 IsRectNull ( rectl)調用將返回 0。本例中,因為矩形變量是靜態變量,系統將它們的坐標均初始化為 0。因此,可以使用這兩個函數中的任一個來判斷矩形是否為空。
在上述例 7-28所示程序中,如果判斷出 rec tLarge為空,那么首先調用 GetWindowRect函數獲取這個對話框的原始尺寸,井保存于 rectLarge中。然后獲得 IDC_SEPARATOR圖片控件的位置,并設置對話框切除部分區域之后的位置坐標,即設置 rectSmal1變量的值。上面已經分析過了,對話框切除圖片控件以下的部分區域后,剩余部分的大小,即 rectSma1 1變量的左上角是沒有變化的,右下角橫坐標也沒有變化,只有縱坐標發生了變化,變化后的縱坐標也就是圖像控件的右下角縱坐標。
有了原始和切除后的矩形尺寸,就可以利用 SetWindowPos函數來設置對話框的收縮和擴展之后的大小了。這個函數的原型聲明如下所示 :
252 I
詳解
BOOL SetWindowPos( const CWnd* pWndlnsertAfter , int x , int y , int cx , int cy , UINT nFlags );
該函數的作用是設置窗口的位置和大小,各參數的意義如下所示:
. pWndInsertAfter
標識一個 CWnd對象,該對象是在以Z次序排序的窗口中位于當前窗口前面的那個窗口對象。這個參數可以是指向某個CWnd對象的指針,也可以是指向表7.2中所列值的指針之一。
表7.2 SetWindowPos函數的pWndlnsertAfter參數取值
參數取值 意義
wndBottom 把當前窗口放置于Z次序的底部
wndTop 將當前窗口放置于Z次序的頂部
wndTopMost 將當前窗口設置為一個頂層窗口,放置于所有非頂層窗口之上,即使窗口未被激活也將保持頂層位置
wndNoTopMost 將當前窗口放置于所有非頂層窗口之上,但在所有頂層窗口之后
. x和y窗口左上角的x和y坐標。
. cx和cy窗口的寬度和高度。
. nFlags
設定窗口的只寸和定位。該參數可以是表7.3中所列各種取值的組合。
表7.3 nFlags參數取值
參數取值 意義
SWP DRAWFRAME 在窗口周圍繪制一個邊框,這是在窗口創建時定義的
SWP FRAMECHANGED 給窗口發送 WM_NCCALCSIZE消息,即使窗口尺寸沒有改變也會發送此消息.如果 未指定這個標志,那么只有在改變了窗口尺寸時才發送WM_NCCALCSIZE消息
SWP HIDEWINDOW 隱藏窗口
SWP NOACTIVATE 不激活窗口。如果未設置此標志,那么窗口被激活,并根據pWndlnsertAfter參數的取值,將當前窗口設置到其他頂層窗口或非頂層窗口之上
SWP NOCOPYBITS 消除客戶區的所有內容。如果未設置此標志,客戶區的有效內容將被保存并且在窗口 尺寸更新和重定位后復制回客戶區
SWP NOMOVE 維持窗口當前位置,這將忽略x和y參數
SWPjNOO~RZORDER 不改變Z次序中的所有者窗口的位置
SWP NOREDRAW 不重畫改變的內容。如果設置此標志,則不發生任何重畫動作。適用于客戶區和非客戶 區(包括標題欄和滾動條)和任何由子窗口移動而露出的父窗口的部分.如果設置了此標志,應用程序必須明確地使窗口無效,并且重畫窗口和父窗口中任何需要重畫的部分
SWP _NOREPOSITION 與SWP一NOOWNERZORDER標志的作用相同
SWP NOSENDCHANGING 禁止窗口接收WM_WINDOWPOSCHANGING消息
SWP NOSlZE 維持窗口的當前尺寸,這將忽略cx和cy參數
SWP NOZORDER 維持當前的Z次序,這將忽略pWndInsertAfter參數
SWP SHOWWINDOW 顯示窗口
喝道..-... I 253
可見,本例中 SetWindowPos函數的nFlags參數不能取 SWP_NOSIZE這個值,因為它將忽略 cx和 cy參數,從而就無法改變對話框矩形區域的大小了。
.
飛令·姐1日眉窗口的 Z次序表明了重疊窗口堆中窗口的位置,這個窗口堆是按一個假
想的軸定位的,這個軸就是從屏幕向外伸展的 Z軸。 Z次序最上面的窗口覆蓋所有其他
的窗口, Z次序最底層的窗口被所有其他的窗口覆蓋。應用程序設置窗口在 Z次序中的
位置是通過把它放在一個給定窗口的后面,或是放在窗口堆的頂部或底部。
Windοws系統管理三個獨立的 Z次序一一一個用于頂層窗口、一個用于兄弟窗口,
還有一個是用于最頂層窗口。最頂層窗口覆蓋所有其他非最頂層窗口,而不管它是不是
活動窗口或是前臺窗口。應用程序通過設置 WS_EX_TOPMOST風格創建最頂層窗口。
一般情況下, Windows系統把剛剛創建的窗口放在 Z次序的頂部,用戶可通過激活
另外一個窗口來改變 Z次序; Windows系統總是把活動的窗口放在 Z次序的頂部,應用
程序可用函數 BringWindowToTop把一個窗口放置到 Z次序的頂部。函數 SetWindowPos
和 DeferWindowPos用來重排 Z次序。
·
兄弟窗口
共享同一個父窗口的多個子窗口叫兄弟窗口。
·
活動窗口
活動窗口是應用程序的頂層窗口,也就是當前使用的窗口。只有一個頂層窗口可以是活動窗口,如果用戶使用的是一個子窗口, Windows系統就激活與這個子窗口相應的頂層窗口。
任何時候系統中只能有一個頂層窗口是活動的。用戶通過單擊窗口(或其中的一個子窗口)、使用 ALT+TAB或 ALT+ESC組合鍵來激活一個頂層窗口,應用程序則調用函數 SetActiveWindow來激活一個頂層窗口 O
·前臺窗口和后臺窗口
在 Windows系統中,每一個進程可運行多個線程,每個線程都能創建窗口。創建正在使用窗口的線程稱之為前臺線程,這個窗口就稱之為前臺窗口。所有其他的線程都是后臺線程,由后臺線程所創建的窗口叫后臺窗口。
用戶通過單擊一個窗口、使用 ALT+TAB或 ALT+ESC組合鍵來設置前臺窗口,應用程序則用函數 SetForegroundWindow設置前臺窗口 O如果新的前臺窗口是一個頂層窗口,那么 Windows系統就激活它,換句話說, Windows系統激活相應的頂層窗口。
Bui1d并運行 Mybole程序,打開測試對話框,如圖 7 .36所示。單擊【收縮《】按鈕,會發現對話框立即切除了分隔條以下的部分,并且此按鈕的名稱變為"擴展》飛如圖 7 .3 7所示:再次單擊此按鈕,會發現對話框又還原為原來的樣子,并且此按鈕的名稱也還原為"收縮<<"。可見,程序實現了所需的功能。如果不想讓用戶看到對話框中這條添加的分隔條,可以在對話框資源編輯窗口中,利用控件屬性對話框,去掉這個圖片控件的Visible屬性(如圖 7 .3 8所示)。然后再次運行 Mybole程序,打開測試對話框,這時就看不到添加的分隔條了,如圖 7 .3 9所示。
254 I如~~
..
四
" ...1:rl 。"
「一 E
...
"
" .. .a此lo 』 ' ...
IT幽什
干
一
圖 7.36原始大小的測試對話框圖 7.37切除部分內容后的測試對話框
忡忡""""川川 .,IZ ."" f "1
絢
而,陽帽|咐. 1陽曬t1 81...... , r -
10: I'Dc_sEP.刷.TOR3τ酬 I Fr.me 333 -
.."|
「畫畫「曲"
「田....... r' T曲-即: JBIUk
r.啕由
圖 7 .3 8去掉圖片控件的 Visible選項圖 7.39"分隔條"為不可見狀態
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -