第八課:對話框第二部分
1. 逃跑按鈕的巧妙實作:
首先建立一個對話框程式,再建立兩個一樣的按鈕,使其中一個的屬性設為不可見,我們要捕獲按鈕的WM_MOUSEMOVE消息,是以要先建一個按鈕的CRunBtn類,并且把兩個按鈕進行控件關聯到m_btn1和m_btn2,以CRunBtn為基類,就可以響應WM_MOUSEMOVE消息了。在OnInitialDialog中交換兩個變量的記憶體位址,如何交換呢,就是建立一個CRunBtn類的一個指針變量m_pBtn。交換代碼如下:m_btn1.m_pBtn=&m_btn2; m_btn2.m_pBtn=&m_btn1;
這個我不了解為什麼這樣可以交換記憶體位址。然後在OnMouseMove中添加代碼:ShowWindow(SW_HIDE); m_pBtn->ShowWindow(SW_SHOW);
用SetWindowPos實作目前還沒有解決,網上的方法也不可行哎。
2.建立屬性表單→建立屬性頁
先建立3個屬性頁,通過右鍵Dialog→插入→IDD_PROPPAGE_LARGE,這裡最好将屬性中的字型改為中文,因為我們在後面将用到中文輸入。
在屬性頁中添加組合框時要注意(Combo Box)它有三個選擇:在樣式中可以選擇是隻能下拉選擇,還是能輸入的組合框。
那麼如何做呢,msdn中查找CPropertyPage是這麼介紹的:
Objects of class CPropertyPage represent individual pages of a property sheet, otherwise known as a tab dialog box. As with standard dialog boxes, you derive a class from CPropertyPage for each page in your property sheet. To use CPropertyPage-derived objects, first create a CPropertySheet object, and then create an object for each page that goes in the property sheet. Call CPropertySheet::AddPage for each page in the sheet, and then display the property sheet by calling CPropertySheet::DoModal for a modal property sheet, or CPropertySheet::Create for a modeless property sheet.
大體的意思就是我們在屬性表單中為每一個CPropertyPage派生一個類,首先建立一個CPropertySheet類對象,然後在CPropertySheet中為每一個屬性頁建立一個對象,在構造函數中為每一個屬性頁調用CPropertySheet::AddPage,然後調用CPropertySheet::DoModal将它顯示出來。顯示對話框是在View中完成的,為View類添加一個類向導,
void CPropView::OnShowPropSheet()
{
// TODO: Add your command handler code here
CPropSheet propSheet("職業屬性表單",this,0);
propSheet.SetWizardMode();//這個表示建立的是向導類的。
propSheet.DoModal();
}
要使得CPropertySheet中的back、next等不可用,則可調用CPropertySheet::SetWizardButtons。Typically, you should call SetWizardButtons from CPropertyPage::OnSetActive.是以我們在CPropertyPage派生的類中添加OnSetActive的虛函數進行覆寫,實作我們的需求。
然後我們實作讓使用者如果不選擇相應的選項就不讓他進入下一步,通過添加函數
還要為組框和清單框關聯變量。
LRESULT CProp1::OnWizardNext()
{
// TODO: Add your specialized code here and/or call the base class
UpdateData();//這裡一定要加
if(m_occupation==-1)
{
MessageBox("請選擇你的職業!");
return -1;//若為-1則不進入下一步。
}
if(m_workAddr=="")
{
MessageBox("請選擇你的工作地點!");
return -1;
}
return CPropertyPage::OnWizardNext();
}
初始化清單框則用:
((CListBox*)GetDlgItem(IDC_LIST1))->AddString("杭州");
((CListBox*)GetDlgItem(IDC_LIST1))->AddString("美國");
((CListBox*)GetDlgItem(IDC_LIST1))->AddString("西班牙");
在第三個屬性頁中要使自動選擇一個選項可調用
CComboBox::SetCurSel這個函數。
為最後一個屬性頁類添加一個虛函數OnWizardFinish()當單擊完成按鈕時,将使用者的選擇存入m_strSarlary中。
int index;
index=((CComboBox*)GetDlgItem(IDC_COMBO1))->GetCurSel();
((CComboBox*)GetDlgItem(IDC_COMBO1))->GetLBText(index,m_strSarlary);
然後在CPropView類中為對應3個屬性頁面添加變量,存儲屬性頁選擇的内容。并進行視窗重繪使得我們可以在OnDraw函數中輸出相應選擇的内容:
CPropSheet propSheet("職業屬性表單",this,0);
propSheet.SetWizardMode();
if(ID_WIZFINISH==propSheet.DoModal())
{
m_nOccupation=propSheet.m_prop1.m_occupation;
m_strWorkAddr=propSheet.m_prop1.m_workAddr;
m_like[0]=propSheet.m_prop2.m_car;
m_like[1]=propSheet.m_prop2.m_plane;
m_like[2]=propSheet.m_prop2.m_qq;
m_like[3]=propSheet.m_prop2.m_love;
m_strSarlary=propSheet.m_prop3.m_strSarlary;
Invalidate();//視窗重繪。
}
在OnDraw函數中先為要輸出的文本建立字型,這裡我們選擇幼圓,然後建立一個臨時變量strTemp儲存要輸出的内容。
void CPropView::OnDraw(CDC* pDC)
{
CPropDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CFont font;
font.CreatePointFont(150,"幼圓");
CFont *pOldFont;
pOldFont=pDC->SelectObject(&font);
CString strTemp="你的職業是:";
switch(m_nOccupation)
{
case 0:
strTemp+="籃球運動員";
break;
case 1:
strTemp+="足球運動員";
break;
case 2:
strTemp+="排球運動員";
break;
default:
break;
}
pDC->TextOut(0,0,strTemp);
strTemp="你的工作地點是:";
strTemp+=m_strWorkAddr;
TEXTMETRIC tm;
pDC->GetTextMetrics(&tm);
pDC->TextOut(0,tm.tmHeight,strTemp);
strTemp="你的興趣愛好是:";
if(m_like[0])
{
strTemp+="飙車 ";
}
if(m_like[1])
{
strTemp+="開飛機 ";
}
if(m_like[2])
{
strTemp+="qq ";
}
if(m_like[3])
{
strTemp+="love ";
}
pDC->TextOut(0,tm.tmHeight*2,strTemp);
strTemp="你的薪資水準是:";
strTemp+=m_strSarlary;
pDC->TextOut(0,tm.tmHeight*3,strTemp);
pDC->SelectObject(pOldFont);
// TODO: add draw code for native data here
}
還要注意的是GetTextMetrics是取一個字型而GetTextExtend取的是一個字元串