屬性頁對話框
分類
標籤式和嚮導式
相關類
CPropertyPage-父類是CDialog類,稱爲屬性頁或頁面對話框。
CPropertySheet-父類是CWnd,稱爲屬性表單。
一個完整的屬性頁對話框由一個屬性表單+多個屬性頁組成。屬性頁嵌套在屬性表單內。
標籤式屬性頁的創建步驟:
1 插入屬性頁對話框資源,選中對話框資源ID修改語言爲Chinese(P.R.C), 選中資源視圖的右邊的對話框右鍵選擇屬性設置爲宋體,9號字體,雙擊資源,生成相應的類,注意父類選擇CPropertyPage類。
2 右擊工程,選擇添加新的類,父類是CPropertySheet類。
3 在表單類中添加屬性頁對象。在構造函數中,
CPropertySheet::AddPage
4 創建和顯示屬性頁
CPropertySheet::DoModal()
5 當控件的值發生改變時,將應用按鈕設置爲可用
CPropertyPage::SetModified(TRUE);
6 消息處理(通過在頁面類中添加虛函數的方式實現)
CPropertyPage::OnApply
CPropertyPage::OnOK
CPropertyPage::OnCancel
新建一個MFC當文檔應用程序,爲菜單添加一個菜單項,在該菜單項的點擊處理函數中彈出我們的屬性頁對話框。
爲了演示效果,在視圖類的OnDraw函數中創建畫筆,然後繪製一個圖形,畫筆的線寬和顏色由其成員變量m_nWidth和m_color決定,這裏正是在屬性頁對話框中設置線寬和顏色然後作用到上面繪製的圖形上。
爲視圖類添加兩個成員變量:
int m_nWitdh;// 線寬
COLORERF m_color; // 顏色
並在視圖類的構造函數中初始化
m_nWidth = 1;
m_color = RGB (0, 0, 0);
視圖的OnDraw添加繪圖代碼如下:
void CMFCLabelView::OnDraw(CDC* pDC)
{
CMFCLabelDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CPen pen;
pen.CreatePen (PS_SOLID, m_nWidth, m_color);
CPen *pOldPen = pDC->SelectObject (&pen);
pDC->Ellipse (100, 100, 400, 400);
pDC->SelectObject (pOldPen);
pen.DeleteObject ();
}
添加菜單項
插入對話框資源,注意選擇PROPPAGE類型的對話框資源
選中對話框資源,右鍵更改語言爲P.R.C
然後在資源視圖右邊窗口選中對話框資源右鍵屬性修改字體爲宋體9號:
複製一個剛纔我們新建的並且調整好語言和字體的對話框
注意:其中一個爲線寬設置對話框,給它添加一個編輯框控件用以輸入數值
另外一個爲顏色設置對話框,給它添加一個按鈕,點擊按鈕彈出顏色對話框
雙擊他們通過類嚮導生成相應的類,注意選擇父類爲CpropertyPage
這裏分別命名爲:CPage1和CPage2
Ctrl+W爲線寬設置對話框的編輯框控件綁定一個int類型的值變量:m_nLineWidth並設置其範圍爲: 1 –20,並在其構造函數中初始化爲1。
在工程上右鍵選擇New Class 注意選擇父類爲CpropertySheet, 這裏類名我設置爲:ClabelSheet,然後爲該類添加兩個成員變量:
CPage1 m_page1;
CPage2 m_page2;
然後在ClabelSheet的兩個構造函數中都添加屬性頁(這樣無論調用哪個都可以正確添加):
AddPage (&m_page1);
AddPage (&m_page2);
注意包含:Page1.h 和Page2.h頭文件
Ctrl+W爲視圖類添加菜單的命令消息響應函數,添加如下創建標籤式屬性頁的代碼:
注意包含:LabelSheet.h頭文件
爲了使當用戶輸入數據時讓屬性頁對話框上的應用按鈕變爲可用狀態,爲線寬設置對話庫類CPage1的編輯框控件添加EN_CHANGE消息響應函數,當編輯框內容一旦改變將觸發該消息,
消息響應函數如下:
void CPage1::OnChangeEditLinewidth()
{
// 設置應用按鈕爲可用狀態
SetModified (TRUE);
}
爲了在用戶點擊應用按鈕時把用戶的設置反應在視圖類的窗口繪圖上,我們需要響應應用按鈕的消息,然而我們無法直接通過雙擊應用按鈕位它添加消息,正確的做法是通過添加虛函數的方式,此外還有確定, 下一步,等一切屬性頁對話框上的按鈕事件都是虛函數。
那麼這裏我給CPage1添加一個虛函數OnApply來響應”應用”按鈕事件
並添加如下代碼來影響視圖窗口圖形的繪製:
BOOL CPage1::OnApply()
{
// TODO: Add your specialized code here and/or call the base class
// 從控件接收數據到變量
UpdateData (TRUE);
// 獲取視圖類對象指針
CMFCLabelView *pView = (CMFCLabelView*)(((CFrameWnd*)AfxGetMainWnd ())->GetActiveView ());
// 改變視圖類的線寬
pView->m_nWidth = m_nLineWidth;
// 使視圖窗口重繪
pView->Invalidate ();
return CPropertyPage::OnApply();
}
這個時候編譯會包一些錯誤發現是一些頭文件包含問題
首先在Page1中包含MFCLabelView.h
然後在MFCLabelView中包含MFCLabelDoc.h
再編譯就Ok了,設置線寬後點應用按鈕在視圖窗口中可以看到效果。
回到CPage2類的對話框資源對話框,雙擊“設置顏色”按鈕添加響應事件,編寫如下代碼:
#include "MFCLabelView.h"
void CPage2::OnBtnSetcolor()
{
// TODO: Add your control notification handler code here
CColorDialog dlg;
if (IDCANCEL == dlg.DoModal ())
return;
CMFCLabelView *pView = (CMFCLabelView*)(((CFrameWnd*)AfxGetMainWnd ())->GetActiveView ());
pView->m_color = dlg.GetColor ();
pView->Invalidate ();
}
嚮導式屬性頁的創建步驟:
1 插入屬性頁對話框資源,選中對話框資源ID修改語言爲Chinese(P.R.C), 選中資源視圖的右邊的對話框右鍵選擇屬性設置爲宋體,9號字體,雙擊資源,生成相應的類,注意父類選擇CPropertyPage類。
2 右擊工程,選擇添加新的類,父類是CPropertySheet類。
3 在表單類中添加屬性頁對象。在構造函數中,
CPropertySheet::AddPage
4 創建和顯示前,設置爲嚮導模式
CPropertySheet::SetWizardMode
5 創建和顯示
CPropertySheet::DoModal()
6 設置每個頁面的嚮導按鈕,在屬性頁對話框對應的類中添加下面的函數
6.1 在CPropertyPage::OnSetActive()函數中設置
6.2 在頁面中得到表單對象
GetParent()
6.3 設置嚮導按鈕
CPropertySheet::SetWizardButtons()
7 消息處理函數,在屬性頁對話框對應的類中添加下面的虛函數函數
CPropertyPage::OnSetActive()
CPropertyPage::OnCancel()
CPropertyPage::OnWizardNext()
CPropertyPage::OnWizardBack()
CPropertyPage::OnWizardFinish()
這裏簡單起見直接修改本工程爲嚮導模式:來到標籤式屬性對話框創建的地方,修改代碼:
void CMFCLabelView::OnLabel()
{
// TODO: Add your command handler code here
/*
// 構造標籤式(默認)屬性頁
CLabelSheet sheet ("標籤式屬性頁");
// 顯示
sheet.DoModal ();
*/
// 構造嚮導式屬性頁
CLabelSheet sheet ("嚮導式屬性頁");
// 設置爲嚮導模式
sheet.SetWizardMode ();
// 顯示
sheet.DoModal ();
}
第一個屬性頁對話框不應出現先一步按鈕,來到CPage1類,添加OnSetAvtive()函數處理:
#include "LabelSheet.h"
BOOL CPage1::OnSetActive()
{
// TODO: Add your specialized code here and/or call the base class
// 獲取父窗口指針(sheet)
CLabelSheet* pSheet = (CLabelSheet*)GetParent ();
// 設置只有"下一步"按鈕可用
pSheet->SetWizardButtons (PSWIZB_NEXT);
return CPropertyPage::OnSetActive();
}
同理顏色設置對話框只能有 上一步 和 完成按鈕
#include "LabelSheet.h"
BOOL CPage2::OnSetActive()
{
// TODO: Add your specialized code here and/or call the base class
// 獲取父窗口指針(sheet)
CLabelSheet* pSheet = (CLabelSheet*)GetParent ();
// 設置:"上一步"和“完成”按鈕爲可用狀態
pSheet->SetWizardButtons (PSWIZB_BACK | PSWIZB_FINISH );
return CPropertyPage::OnSetActive();
}
那麼我們想在線寬設置對話框設點擊“下一步”按鈕時把用戶的輸入設置到視圖的顯示,中,需要重寫虛函數CPropertyPage::OnWizardNext()
LRESULT CPage1::OnWizardNext()
{
// TODO: Add your specialized code here and/or call the base class
// 從控件接收數據到變量
UpdateData (TRUE);
// 獲取視圖類對象指針
CMFCLabelView *pView = (CMFCLabelView*)(((CFrameWnd*)AfxGetMainWnd ())->GetActiveView ());
// 改變視圖類的線寬
pView->m_nWidth = m_nLineWidth;
// 使視圖窗口重繪
pView->Invalidate ();
return CPropertyPage::OnWizardNext();
}
效果如下: