VS2008, MFC 編程 對話框 筆記6 - 屬性表單 TAB 頁面2 - 嚮導屬性表單 List Box Combo Box

本部分需要 查看 我的另一篇:VS2008, MFC 編程 對話框 筆記6 - 屬性表單 TAB 頁面1 - 點擊子菜單 顯示建立的屬性對話框

1. 在上一篇, 成功的實現了點擊 子菜單 PropertyPage 彈出 屬性表單對話框,只需要在 建立模態對話框之前加入 設置嚮導模式就可以,函數爲 SetWizardMode();

void Cvs2008_SX_jiaocheng08_1View::OnPropertypage()
{
	// TODO: 在此添加命令處理程序代碼
	CPropSheet propSheet(L"Test Property Page sheet");//構造一個屬性表單對象。標題爲"Test Property Page sheet"
 
	propSheet.SetWizardMode();//設置嚮導 出現“下一步”“上一步”按鈕
	propSheet.DoModal();//調用屬性表單的DoModal來顯示 一個模態的屬性表單
}

2. 但是,在屬性表單 第一頁和最後一頁 還是有上一步和下一步 的按鈕,這裏使用 重寫OnSetActive

3. 重寫函數分別爲

BOOL CProp1::OnSetActive(void)
{
	//因爲屬性頁時增加到屬性表單的,所以屬性頁CPropPage是屬性表單的Propsheet的子類
	//所以使用GetParent獲取父類指針。
	((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT);//對於第一頁只有“下一頁”按鈕。
	return CPropertyPage::OnSetActive();
}


BOOL CProp2::OnSetActive(void)
{

    //因爲屬性頁時增加到屬性表單的,所以屬性頁CPropPage是屬性表單的Propsheet的子類
	//所以使用GetParent獲取父類指針。
	((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT  );//對於第二頁 是有“上一頁”和“下一頁”按鈕。
	return CPropertyPage::OnSetActive();
}

BOOL CProp3::OnSetActive(void)
{
	//因爲屬性頁時增加到屬性表單的,所以屬性頁CPropPage是屬性表單的Propsheet的子類
	//所以使用GetParent獲取父類指針。
	((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH);//對於第三頁 上一頁  和 完成。
	return CPropertyPage::OnSetActive();
}

 

4. 設置 當用戶 沒有選擇 單選項  就不能點擊 “下一步”。並提示。

4.1 先把 Radio Button的屬性中group 改爲true,這樣 Radio button:System Engineer 和 project Manager 就和 software Enginner 是一組。因此 給Software Engineer 關聯int 變量,當選擇Software Engineer 時 變量值爲0,當選擇Project Manager 變量值就爲2. (組的的結尾爲遇到下一個爲組屬性的結束,當Project Manager 設置爲組, 那麼Software Engineer 和 Systerm Enginner 爲一組,Project Manager 爲另一組)

4.2 爲單選項 Software Engineer 增加 int 類型的控件變量 m_occupation。默認構造函數把m_occupation初始化爲0,如果想要開始時候不選中任何一個單選項控件,就把初始值改爲-1.

4.3 爲了實現 “下一步” 按鈕的 響應, 在屬性頁1 重寫 如下function(重寫函數的添加 請自行完成),

virtual LRESULT OnWizardNext();

Return Value

0 to automatically advance to the next page; –1 to prevent the page from changing. To jump to a page other than the next one, return the identifier of the dialog to be displayed.

Remarks

Override this member function to specify some action the user must take when the Next button is pressed

4.4 給重寫的OnWizardNext函數添加代碼

LRESULT CProp1::OnWizardNext(void)
{
	UpdateData();//當參數爲真 就是獲取控件中的值,爲false 就是向控件寫值,這個會激發DoDataExchange的調用來實現。
	if( -1 == m_occupation )
	{
		MessageBox(L"Please Select your Occupation");
		return -1;
	}
	return LRESULT();
}

5. 接下來對List Box 列表盒 的操作 

5.1 可以在響應 Windows 消息 WM_INITDIALOA 時候處理時, 在屬性頁1(類CProp1)增加對WM_INITDIALOG的處理函數。即在ListBox顯示之前給ListBox 添加信息。(注意是在重寫 裏面選擇)

5.2 對於列表框ListBox 也是有CListBox類的 其中有個AddString成員函數,利用這個函數給列表框增加信息

BOOL CProp1::OnInitDialog()
{
	CPropertyPage::OnInitDialog();

	// TODO:  在此添加額外的初始化
	((CListBox*)GetDlgItem(IDC_LIST1))->AddString(L"BeiJing");//獲取類方法 (CListBox*)GetDlgItem(IDC_LIST1)
	((CListBox*)GetDlgItem(IDC_LIST1))->AddString(L"TianJing");
	((CListBox*)GetDlgItem(IDC_LIST1))->AddString(L"ShangHai");
	return TRUE;  // return TRUE unless you set the focus to a control
	// 異常: OCX 屬性頁應返回 FALSE
}

5.3 增加功能: 當屬性頁面1(類CProp1)的ListBox沒有被選擇任何信息,就不讓進入下一頁並提示選擇。給列表框ListBox增加一個控件變量m_workAddr到類CProp1,並把判斷代碼寫入 重寫的OnWizardNext函數中

LRESULT CProp1::OnWizardNext(void)
{
	UpdateData();//當參數爲真 就是獲取控件中的值,爲false 就是向控件寫值,這個會激發DoDataExchange的調用來實現。
	if( -1 == m_occupation )
	{
		MessageBox(L"Please Select your Occupation");
		return -1;
	}
	CString none("");
	if(none == m_workAddr)
	{
		MessageBox(L"Please select your work address");
		return -1;
	}
	return LRESULT();
}

6. 下面對複選框 checkbox 進行操作

6.1 分別給4個checkbox 添加bool控件變量,增加給屬性頁2(類CProp2)。分別爲m_football,m_basketball,m_volleyball,m_swimming。當選中時 關聯變量爲真 否則爲假。(自行添加)

6.2 要實現的功能是:當沒有任何複選框被選擇,那麼就不讓其進入下一頁,並提示信息。根據 4.3 裏面一樣的描述 在CProp2中重寫的OnWizardNext函數 並添加代碼


LRESULT CProp2::OnWizardNext(void)
{
	UpdateData();//一定要注意,要取控件關聯的變量 一定要調用,傳遞一個真,
	             //要寫控件變量也要 調用 單參數爲假,UpdateData(FALSE);
	if(m_football || m_basketball || m_volleyball || m_swimming)
	{
		return LRESULT();
	}
	else
	{
		MessageBox(L"Pls select your interests");
		return -1;
	}

}

7. 下面對 組合框 Combo Box的操作

7.1 組合框也有個類CComboBox,其中成員函數AddString 爲增加 內容到組合框。同理,可以在屬性頁3(CProp3類)重寫OnInitDialog函數,在函數裏去給組合框增加信息。

BOOL CProp3::OnInitDialog()
{
	CPropertyPage::OnInitDialog();

	// TODO:  在此添加額外的初始化

	((CComboBox*)GetDlgItem(IDC_COMBO4))->AddString(L"0-1000 YUAN");
	((CComboBox*)GetDlgItem(IDC_COMBO4))->AddString(L"1000-2000 YUAN");
	((CComboBox*)GetDlgItem(IDC_COMBO4))->AddString(L"2000-5000 YUAN");
	((CComboBox*)GetDlgItem(IDC_COMBO4))->AddString(L"5000- YUAN");
	return TRUE;  // return TRUE unless you set the focus to a control
	// 異常: OCX 屬性頁應返回 FALSE
}

7.2 當需要按照自己輸入的順序在 ComboBox中顯示信息,就需要把組合框Sort屬性改爲False;

7.3 要讓組合框初始的時候就選中一條,可以用CComboBox類成員函數SetCurSel,繼續在OnInitDialog函數中操作

BOOL CProp3::OnInitDialog()
{
	CPropertyPage::OnInitDialog();

	// TODO:  在此添加額外的初始化

	((CComboBox*)GetDlgItem(IDC_COMBO4))->AddString(L"0-1000 YUAN");
	((CComboBox*)GetDlgItem(IDC_COMBO4))->AddString(L"1000-2000 YUAN");
	((CComboBox*)GetDlgItem(IDC_COMBO4))->AddString(L"2000-5000 YUAN");
	((CComboBox*)GetDlgItem(IDC_COMBO4))->AddString(L"5000- YUAN");

	((CComboBox*)GetDlgItem(IDC_COMBO4))->SetCurSel(1);//選擇第二條信息 "1000-2000 YUAN"

	return TRUE;  // return TRUE unless you set the focus to a control
	// 異常: OCX 屬性頁應返回 FALSE
}

8. 接下來 讓屬性頁面選擇的內容顯示在View類窗口中

8.1  給第三個屬性頁 CProp3類 增加 一個CString m_strSalary 成員變量 用來保存 屬性頁3(類CProp3)選擇的 信息條。(自行添加)

8.2 在用戶點擊 第三個屬性頁的 完成 按鈕時候 保存第三屬性頁組合框選擇的信息。在CProp3類重寫OnWizardFinish函數在其中實現代碼。要獲取用戶選擇的信息條索引,可以使用CComboBox成員函數GetCurSel來進行。獲取到索引後,再使用成員GetLBText函數來獲取列表字符串。

BOOL CProp3::OnWizardFinish()
{
	// TODO: 在此添加專用代碼和/或調用基類
	int index;
	index = ((CComboBox*)GetDlgItem(IDC_COMBO4))->GetCurSel();//獲取Combobox選擇的信息條
	((CComboBox*)GetDlgItem(IDC_COMBO4))->GetLBText(index,m_strSalary);

	return CPropertyPage::OnWizardFinish();
}

8.3 要在View類中實現信息的顯示,首先一條是要判斷用戶 最終選擇 完成 還是 取消。這個時候就要看DoModal的返回值。如果用戶選擇的是 完成,需要保存 用戶選擇的信息。

void Cvs2008_SX_jiaocheng08_1View::OnPropertypage()
{
	// TODO: 在此添加命令處理程序代碼
	CPropSheet propSheet(L"Test Property Page sheet");//構造一個屬性表單對象。標題爲"Test Property Page sheet"
 
	propSheet.SetWizardMode();//設置嚮導 出現“下一步”“上一步”按鈕
	
	if(ID_WIZFINISH == propSheet.DoModal())//調用屬性表單的DoModal來顯示 一個模態的屬性表單
	{
		//此時屬性表單窗口已經消失,但是類還在,所以還是以進行操作
		//把屬性窗口頁 選擇的信息保存到 CPropSheet成員中.
		m_IOccupation = propSheet.m_prop1.m_occupation;
		m_strWorkAddr = propSheet.m_prop1.m_workAddr;
		m_bLike[0] = propSheet.m_prop2.m_football;
		m_bLike[1] = propSheet.m_prop2.m_basketball;
		m_bLike[2] = propSheet.m_prop2.m_volleyball;
		m_bLike[3] = propSheet.m_prop2.m_swimming;
		m_strSalary = propSheet.m_prop3.m_strSalary;
		Invalidate();//最後是使得窗口無效,讓窗口重繪
	}
}

8.4 然後在工程view類的OnDraw函數中完成 信息的輸出,查看代碼和註釋

void Cvs2008_SX_jiaocheng08_1View::OnDraw(CDC* pDC)
{
	Cvs2008_SX_jiaocheng08_1Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此處爲本機數據添加繪製代碼
	CFont font;
	font.CreatePointFont(300,_T("華文行楷"));//創建字體
	
	CFont *pOldFont;//用來保存先前的字體
	pOldFont = pDC->SelectObject(&font);
	
	CString strTemp;
	strTemp = "Your occupation: ";
	switch(m_IOccupation)
	{
	case 0:
		strTemp += "Software enginer";
		break;
	case 1:
		strTemp += "System engineer";
		break;
	case 2:
		strTemp += "Project Manager";
		break;
	default:
		break;

	}
	pDC->TextOut(0,0,strTemp);//在位置0,0處輸出 字符串

	
	strTemp = "Your work address: ";
	strTemp += m_strWorkAddr;

	TEXTMETRIC tm;
	pDC->GetTextMetrics(&tm);//獲取輸出字體的高度,這樣輸出第二行就直到放哪了
	pDC->TextOutW(0,tm.tmHeight,strTemp);

	strTemp = "Your interests: ";
	if(m_bLike[0])
	{
		strTemp += "football    / ";
	}
	if(m_bLike[1])
	{
		strTemp += "basket ball    /";
	}
	if(m_bLike[2])
	{
		strTemp += "volleyball   /";
	}
	if(m_bLike[3])
	{
		strTemp += "swimming    /";
	}

	pDC->TextOutW(0,tm.tmHeight*2,strTemp);

	strTemp = "Your salary level: ";

	strTemp += m_strSalary;
	pDC->TextOutW(0,tm.tmHeight*3,strTemp);

	pDC->SelectObject(pOldFont);//把原先字體 選擇回去

}

相關類和成員 查看MSDN文件

 

鏈接:https://pan.baidu.com/s/1UPpu61qQMQGk4kLjYl5WbQ 
提取碼:a620

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章