VC++技術內幕(第四版)筆記(第6章)

/**************************************/
第六章:模式對話框和Windows通用控件

1,對話框也是窗口,它不當可以接受消息,而且還可以被移動和關閉,甚至可以在它的客戶區中進行繪圖操作。

2,模式對話框在被關閉之前,用戶無法在同一應用程序的其它地方進行工作。模式對話框更易於編程。
無模式對話框在它仍保留在屏幕的同時,用戶還可以在應用程序的其它窗口進行工作。

3,對話框控件既可以通過CWnd指針來引用,也可以通過資源文件定義的索引值(和#define常量相關聯)來引用。對話框控件本身就是一個窗口。控件通過向上級對話框發送消息來響應用戶的動作。
利用ClassWizard可以幫助產生CDialog派生類,還可以使對話框類數據成員和對話框控件相聯繫。

4,在現存在項目中添加模式對話框步驟:
1)用對話框編輯器創建包含各種控件的對話框資源。對話框編輯器會對項目的資源文件更新,使之包含新的對話框資源,並且該項目的resource.h文件也會被更新,以便能夠包含新的#define常量。
2)利用ClassWizard創建CDialog派生類,並將它和第一步所創建的資源相連接。
3)利用ClassWizard添加控件消息響應函數,並進行編輯。
4)在其它類中需要使用地方先構造該對話框類對象,再調用DoModal顯示模式對話框。
說明:
1)在產生的對話框頭文件中包含一個枚舉類型常量IDD,用於設置該對話框資源ID。枚舉常量IDD的使用減弱了CPP文件對資源ID的依賴。
2)《在其它類中顯示模式對話框後,只有當模式對話框退出後,才繼續執行該類顯示模式對話框代碼後的代碼。》

5,在組合筐中Data屬性頁下,添加一條後按CTRL+RETURN來結束(或添加下條item)。(VC6中按?鍵可以獲取相關幫助提示的)。組合框有Simple,Dropdown,Drop List三中風格,可以是Styles中選擇。
列表筐中,用戶只能用鼠標選擇選擇一個條目,而且在對話框編輯器中不能輸入列表框的初始選擇條目。
在靜態文本控件中可以內置'&'符號。運行時候,&符號後面的字符下將有一個下劃線。用戶在按下ALT鍵後同時按下相應帶下劃線的字母,則就可以跳轉到相應的控件上去。注意同一對話框中跳轉字符不能重複。

6,當DoModal被調用後,實際在幕後引起一系列如下的動作:
CDialog::DoModal->CEx06Dialog::OnInitDialog->其它的初始化->CDialog::OnInitDialog->CWnd::UpdateData(FALSE)->CEx06Dialog::DoDataExchange
用戶輸入數據...
用戶單擊OK按鈕
CEx06Dialog::OnOk->...其它的確認處理...->CDialog::OnOk->CWnd::UpDateData(TURE)->CEx06Dialog::DoDataExchange->CDialog::EndDialog(IDOK)
說明:
1)virtual BOOL OnInitDialog( );
//CDialog::OnInitDialog This member function is called in response to the WM_INITDIALOG message. This message is sent to the dialog box during the Create, CreateIndirect, or DoModal calls, which occur immediately before the dialog box is displayed.
//Override this member function if you need to perform special processing when the dialog box is initialized.

2)BOOL UpdateData( BOOL bSaveAndValidate = TRUE );
//CWnd::UpdateData :Call this member function to initialize data in a dialog box, or to retrieve and validate dialog data.
//bSaveAndValidate:Flag that indicates whether dialog box is being initialized (FALSE) or data is being retrieved (TRUE).
//By default UpdateData(TRUE) is called in the default CDialog::OnOK handler and UpdateData(FALSE) is called in the default CDialog::OnInitDialog.

3)virtual void DoDataExchange( CDataExchange* pDX );
//CWnd::DoDataExchange  Called by the framework to exchange and validate dialog data.
//Never call this function (DoDataExchange) directly. It is called by the UpdateData member function.
//Call UpdateData to initialize a dialog box’s controls or retrieve data from a dialog box.

4)void EndDialog( int nResult );
//CDialog::EndDialog  makes the dialog box invisible but does not destroy it.
//Call this member function to terminate a modal dialog box. This member function returns nResult as the return value of DoModal(IDOK表示接受對話框數據,IDCANCEL表示取消對話框數據). You must use the EndDialog function to complete processing whenever a modal dialog box is created.
//注意:If you implement the OK button in a modeless dialog box, you must override the OnOK member function and call DestroyWindow from within it.

5)當DoModal函數返回的時候,對話框窗口不再存在。我們可以在堆棧中創建模式對話框對象,這樣就可以保證當程序控制轉向到C++對話框對象所在的範圍之外時,它及時的刪除掉。


7,代碼解釋:
void CEx06aDialog::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CEx06aDialog)
 DDX_Text(pDX, IDC_BIO, m_strBio);//
 DDX_Radio(pDX, IDC_CAT, m_nCat);
 ...
 DDV_MinMaxInt(pDX, m_nSsn, 0, 999999999);
 //}}AFX_DATA_MAP
}
說明:
1)DoDataExchange、DDX_(交換)、DDV_(確認)函數都具有雙向性。如果調用UpdateData(FALSE)(參數爲FALSE),則這些數據就會將與控件相關聯(值關聯)的數據成員的值傳遞給對話框中的控件;相反,如果UpDateData(TURE)(參數是TURE),則這些函數會將數據從對話框控件中傳遞給與之相關聯(值關聯)的數據成員。
2)這裏DDX_Text函數被重載,具體參閱MSDN。The DDX_Text function manages the transfer of int, UINT, long, DWORD, CString, float, or double data between an edit control in a dialog box, form view, or control view and a CString data member of the dialog box, form view, or control view object.
其它DDX_函數參閱MSDN。

8,Enter鍵觸發OnOk函數調用:
當用戶按下ENTER鍵後,OS會自動去查找輸入焦點落在哪個按鈕上,獲得焦點的按鈕四周將被點線矩形框包圍。如果所有的按鈕都沒獲得輸入焦點,則OS會自動去尋找程序或資源所指定的默認按鈕(默認按鈕邊框較粗)。如果對話框沒有默認按鈕,那麼即使對話框中沒有OK按鈕,OnOk函數也會自動被調用。
由於OnOk函數是虛函數,可以重寫OnOk函數,將其函數體置空,變可以使使ENTER鍵無效。
分離OK按鈕:改寫OK按鈕ID,併除掉其默認按鈕(Default Button)的設置。

9,p107至WIN32程序員:強烈建議看看,下爲簡要筆記。
對話框控件會向他們父對話框發送WM_COMMAND通告消息。大多數窗口程序處理函數都是通過一個嵌套的switch結構了處理這些通告消息的,而MFC則更直接了當地把這些控件通知消息和其它的Windows消息放在同一個層次上處理。

10,Esc鍵觸發OnCancel函數的調用,導致控制從對話框中退出,如果是模式對話框則DoModal的還返回IDCANCEL值。其消除方法同ENTER鍵。

11,事例代碼涉及的一些主要函數及補充說明:
1)CWnd* GetDlgItem( int nID ) const;//可用它來獲取對話框上控件指針(返回的時候,強制轉換成所需要的控件指針),注意臨時性。
   void CWnd::GetDlgItem( int nID, HWND* phWnd ) const;
//Retrieves a pointer to the specified control or child window in a dialog box or other window. The pointer returned is usually cast to the type of control identified by nID.
說明:如果需要包CWnd指針轉化成一個控件ID,則可以使用MFC中CWnd類GetDlgCtrlID成員函數。
2)GetScrollPos  Retrieves the current position of a scroll box.
   SetScrollPos  Sets the current position of a scroll box.
   GetScrollRange  Retrieves the current minimum and maximum scroll-bar positions for the given scroll bar.
   SetScrollRange  Sets minimum and maximum position values for the given scroll bar.
3)afx_msg void OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar );//CWnd::OnHScroll 
afx_msg void OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar );//CWnd::OnVScroll 
3)所有的水平滾動條都綁在WM_HSCROLL消息控制函數,所有的豎直滾動條則都綁在一個WM_VSCROLL消息控制函數上。(一般控件都有自己的獨立的消息控制函數,但[滾動條控件]有點不同,所以對同一個對話框多個滾動條消息處理的時候,一般都將它們的滾動範圍設置一致,方便編程)


/////////////////////////
/////////////////////////
///P109-125頁內容筆記待續
12,每個控件在顯示之前會向其父對話框發送WM_CTLCOLOR消息,對話框本身也會發送該消息。
《對話框和對話框控件都是窗口,也可以在這些窗口中進行繪圖操作。(添加OnPain函數,調用Invalidate/UpdateWindow讓窗口重繪)》

13,在運行時加入對話框控件:
一般步驟:
1)在對話框類中添加一個內嵌的控件窗口數據成員。一個內嵌控件C++對象將與相應的對話框對象一起被構造和刪除。
2)從View菜單中選擇Resource Symbols,爲新的控件添加一個ID常量。(也可以在Resource.h中用定義)
3)用ClassWizard映射WM_INITDIALOG消息覆蓋(Override)基類 CDialog::OnInitDialog函數。在該函數裏調用控件窗口的Create成員函數,並顯示新的控件(可以用ShowWindow函數)。Windows回在刪除對話框窗口的同時也刪除該控件窗口。
4)在派生對話框類裏,爲新控件手工加入必要的通知消息控制函數。(三步:消息控制函數原型說明,消息映射,消息處理函數)

14,Win32編程經驗:父窗口和控件之間是通過Windows消息進行通信的(如MFC中象CListBox::InserString函數),但適用於所有窗口類型的控件類成員函數並不發送消息,而是調用Win32函數。

15,Windows通用控件:Win95引進的象[進度指示器],[滑桿條],[微調按鈕控件],[列表控件]和[樹狀控件]。這些控件的代碼在Windows的COMCTL32.DLL文件中,其中包括了每個控件的窗口過程函數,及每個控件的註冊窗口類的代碼,這些註冊代碼在DLL加載時候被調用。當應用程序初始化對話框時,將使用對話框資源中符號化的類名,來連接到DLL裏的窗口過程函數上。這樣應用程序就有了控件的窗口,但代碼實際上在DLL裏。
除了ActiveX控件,大多數控件都是用這種方法實現的。

16,WM_NOTIFY
    idCtrl = (int) wParam; //控件ID
    pnmh = (LPNMHDR) lParam; //指向NMHDR結構指針,該結構由控件管理。
說明:
1)Sent by a common control to its parent window when an event has occurred in the control or the control requires some kind of information.
2)Not all controls will send WM_NOTIFY messages. In particular, the standard Windows controls (edit controls, combo boxes, list boxes, buttons, scroll bars, and static controls) do not send WM_NOTIFY messages.

/////////////////////////
/////////////////////////
///P115-125頁內容筆記待續

發佈了30 篇原創文章 · 獲贊 4 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章