文章目錄
- Return Value (of OnWizardNext)
- Return Value
1.如何改變按紐的字型?在對話方塊的屬性中改變字型的屬性即可
2.逃跑按紐的實現
1.從CButton派生一個類,CWeixinBtn
2.將IDC_EDIT1關聯成員變數m_btn1,類型為CWeixinBtn,注意要包含標頭檔。
3.在CWeixinBtn中加一個指標成員變數CWeixinBtn *pWeixinBtn,然後將其地址初始化。
4.在新類中增加滑鼠移動的訊息處理。
3.屬性工作表單
1.插入屬性頁面資源。Insert->new Resource->Dialog
2.當選擇Classwizard菜單時,系統提示是否為建立新的類,我們將其從CPropertyPage派生!這樣可以為
方便為其增加訊息響應函數。
3.插入新的從CPropertySheet派生的類,在類中增加3個CPropertyPage的執行個體。
4.在view中增加功能表項目,當點擊時顯示內容表單,出現中文亂碼,修改CPropertyPage屬性為中文,另外將
其字型設為宋體。
5.在CPropertyPage中設定SetWizardButtons可將其屬性改為上一步、完成!
6.為IDC_RADIO1關聯成員變數,需要先設定Group屬性才行。另外別忘記調用UpdateData().
7.為CPropertyPage增加虛函數,OnWizardNext,如果使用者點擊下一步時,不想讓他進入下一步,剛返回-1!
8.將使用者的選擇輸出到螢幕上,此時可以在View中增加幾個成員變數,用來接收使用者選擇的資料。
4.memset()的用法! memset(m_bLike,0,sizeof(m_bLike));
一、 簡單的逃跑按鈕
//開始: 架構對話方塊屬性裡面有Font字型改變的選項,但在其上放置的按鈕沒有
//上面的情況,可以通過前者改變後者
//注意下列方法,定義一個類為了捕獲滑鼠移動點的方便
1,建立一個基於對話方塊的MFC AppWizard工程
2,在View視窗點右鍵,添加一個自訂的類(或者用Classwizard工具添加),基類為CButton
class CWeiXinBtn : public CButton
3,給CWeiXinBtn類新增成員變數CWeiXinBtn* m_pBtn;
4,給對話方塊添加倆按鈕,每個按鈕都關聯一個CWeiXinBtn的變數
5,在OnInitDialog添加
m_btn1.m_pBtn=&m_btn2;
m_btn2.m_pBtn=&m_btn1;
6,CWeiXinBtn::OnMouseMove中添加切換顯示器的語句
ShowWindow(SW_HIDE);
m_pBtn->ShowWindow(SW_SHOW); //將對方顯示出來...
大功告成!
當然可以SetWindowPos函數實現更客觀
//由此可見,我們見到的程式----一切都是虛幻!(超哥等人的名言...)
二、 屬性頁面的編輯
//插入三個IDD_PROPPAGE_LARGE型屬性頁面資源
ID: IDD_PROP 1/2/3 Caption:Prop1/2/3
我們插入的對話方塊: 屬性頁面----More Styles: Disabled
//調整控制項儲存位置:按住Ctrl鍵選擇以後在左下角
Radio
Check
Combox (注意要拉得大一點,否則可能顯示不出來,但是又不能調整大小;所以我們只有在擺放的同時將它拉得大一些)
三種類型: Dropdown: 可以輸入,且有一個列表框;
Simple: 列表框和輸入框一同顯示(果然相當地simple)
DropList: 編輯框不能輸入
CProp1的基類要選擇為: CPropertyPage
添加類時VC++本身的問題看不到Prop1,刪掉.clw,再產生之;還是用原來的Prop.clw這個名字
1,CPropertyPage類
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.
//增加一個CPropSheet類,基類為CPropertySheet;
在CPropSheet中增加成員變數
#include "Prop1.h"
#include "Prop2.h"
#include "Prop3.h"
CProp1 m_prop1;
CProp2 m_prop2;
CProp3 m_prop3;
在sheet的建構函式中添加propertyPage
在CPropSheet兩個建構函式(只是第一個參數UINT nIDCaption和LPCTSTR pszCaption不一樣)中,都增加如下:
AddPage(&m_prop1);
AddPage(&m_prop2);
AddPage(&m_prop3);
//預設是第一個最先出現
prop1sheet::AddPage 把頁面添加到sheet
//在View類出增加OnPropertysheet函數並編輯如下代碼:
CPropSheet propSheet("維新屬性工作表單程式");
prop1sheet.DoModal();
//出現亂碼
解決: 將新增加的IDD_PROP1/2/3語言一欄修改為Chinese(P.R.C),同時修改字型
屬性-->嚮導:
在DoModal之前調用SetWizardMode()即可變為嚮導
但上一步,下一步有問題
CPropertySheet classmembers SetWizardButtons
Enables or disables the Back, Next, or Finish button in a wizard property sheet.
void SetWizardButtons( DWORD dwFlags );
-
dwFlags
-
A set of flags that customize the function and appearance of the wizard buttons. This parameter can be a combination of the following values:
Call SetWizardButtons only after the dialog is open; you can't call SetWizardButtons before you call DoModal. Typically, you should call SetWizardButtons from CPropertyPage::OnSetActive.
於是我們進入OnSetActive (虛函數)
在Prop1右鍵-->增加虛函數
2,屬性頁面變嚮導類型
prop1sheep.SetWindowMode();//嚮導模式語句
prop1sheet.DoModal();
3,第一頁的"上一步",最後一頁的"下一步"取消方法
在第一個/最後一頁屬性頁面類添加虛函數PnSetActive,並在其中添加
((CPropertySheet *)GetParent())->SetWizardButtons(PSWIZB_NEXT);//第一頁 因為AddPage了,故是父視窗? 要注意強制轉換
((CPropertySheet *)GetParent())->SetWizardButtons(PSWIZB_BACK|PSWIZB_NEXT);//中間的頁
((CPropertySheet *)GetParent())->SetWizardButtons(PSWIZB_BACK|PSWIZB_FINISH);//最後一頁
4,"下一步"之前,檢查是否已完成“選擇”等
在PropertyPage的OnWizardNext函數中檢查
//Radio1 屬性勾選中Group (後面的選項按鈕與它是一組了, Radio1關聯的成員變數為0, Radio2關聯的成員變數值為1,依次類推)
//組到什麼時候結束?直到遇到下一個具有組這個屬性的選項按鈕
CProp1中增加m_occupation 選Value,變數類型只能選int了
初始化為-1;這樣如果它為-1則表明使用者沒有選擇
在DoDataExchange中
DDX_Radio(pDX, IDC_RADIO1, m_occupation)關聯起來了;
在哪一步判斷使用者選擇沒有呢?
在CProp1中增加虛函數 OnWizardNext!!
下面解釋: Called when the Next button is clicked while using wizard-type property sheet.
即:點擊"下一步"按鈕時調用;
LRESULT CProp1::OnWizardNext()
{
// TODO: Add your specialized code here and/or call the base class
UpdateData();//不要忘了這個東東
if(m_occupation==-1)
{
MessageBox("請選擇你的職業!");
return -1;
}
if(m_workAddr=="")//CListBox類,
AddString函數:增加字串到列表框,傳回值為基於0的索引
{
MessageBox("請選擇你的工作地點!");
return -1;
}
return CPropertyPage::OnWizardNext();
}
Return Value (of OnWizardNext)
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.
//判斷工作地點:
CProp1::OnInitDialog()中
BOOL CProp1::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: Add extra initialization here
((CListBox*)GetDlgItem(IDC_LIST1))->AddString("北京");
((CListBox*)GetDlgItem(IDC_LIST1))->AddString("天津");
((CListBox*)GetDlgItem(IDC_LIST1))->AddString("上海");
//偶認為將其存在一個字元數組裡,然後利用迴圈加AddString更好...
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
自動進行的初始化
CProp1::CProp1() : CPropertyPage(CProp1::IDD)
{
//{{AFX_DATA_INIT(CProp1)
m_occupation = -1;
m_workAddr = _T("");
//}}AFX_DATA_INIT
}
分別為四個check框添加BOOL型成員變數
LRESULT CProp2::OnWizardNext()
{
// TODO: Add your specialized code here and/or call the base class
UpdateData();//不要忘了加這個東東哦謔謔
if(m_football || m_basketball || m_volleyball || m_swim)
{
return CPropertyPage::OnWizardNext();
}
else
{
MessageBox("請選擇你的興趣愛好!");
return -1;
}
}
//老孫說: 要靈活編程----把系統自己加的放到前面去
5,編輯對話方塊/屬性頁面上的ComBox控制項
((CComoBox *)GetDlgItmem(IDC_ComBOX1))->AddString(" ");//增加選項
把列表框的 Sort屬性取消勾選,則按我們原始AddString的順序顯示
int SetCurSel( int nSelect );
Return Value
The zero-based index of the item selected if the message is successful. The return value is CB_ERR if nSelect is greater than the number of items in the list or if nSelect is set to –1, which clears the selection.
((CComboBox*)GetDlgItem(IDC_COMBO2))->SetCurSel(0);//預設選項
6,擷取List(ComBox)控制項,並進行編輯
int sel=((CComoBox *)GetDlgItmem(IDC_ComBOX1))->GetCurSel();
CString m_str;
((CComoBox *)GetDlgItmem(IDC_ComBOX1))->GetLBText(sel,&m_str);//取出使用者的選擇
BOOL CProp3::OnWizardFinish()
{
// TODO: Add your specialized code here and/or call the base class
int index;
index=((CComboBox*)GetDlgItem(IDC_COMBO2))->GetCurSel(); //返回的index是一個基於零的索引
((CComboBox*)GetDlgItem(IDC_COMBO2))->GetLBText(index,m_strSalary);
//GetLBText: Gets a string from the list box of a combo box.
return CPropertyPage::OnWizardFinish();
}
7,視窗IDOK==xxx.DoModal()後,其上面的控制項生命期仍有效,所以可以用變數接受其值
//在View類中重新定義: int m_iOccupation, CString m_strWorkAddr; BOOL m_bLike[4]來接收
//在建構函式中進行初始化-1;"";
memset(m_bLike,0,sizeof(m_bLike));
三個參數分別為:數組, 字元, 個數;
當DoModal()返回之後,接收資料,視窗消失了,但對象沒有析構,還可以接收;
void CPropView::OnPropertysheet()
{
// TODO: Add your command handler code here
CPropSheet propSheet("維新屬性工作表單程式");
propSheet.SetWizardMode();
if(ID_WIZFINISH==propSheet.DoModal()) //在這裡改動了
IDOK or IDCANCEL if the function was successful; otherwise 0 or -1. If the property sheet has been established as a wizard (see SetWizardMode), DoModal returns either ID_WIZFINISH or IDCANCEL.
{
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_swim;
m_strSalary=propSheet.m_prop3.m_strSalary;
Invalidate();
}
}
8,List控制項的sort屬性選中/不選中,表示是否自動排序,注意有時不需要自己排序
//OnDraw裡面添加: (字型改變)
void CPropView::OnDraw(CDC* pDC) { CPropDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CFont font; font.CreatePointFont(300,"華文行楷"); CFont *pOldFont; pOldFont=pDC->SelectObject(&font); CString strTemp; strTemp="你的職業:"; switch(m_iOccupation) { 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_bLike[0]) { strTemp+="足球 "; } if(m_bLike[1]) { strTemp+="籃球 "; } if(m_bLike[2]) { strTemp+="排球 "; } if(m_bLike[3]) { strTemp+="遊泳 "; } pDC->TextOut(0,tm.tmHeight*2,strTemp); strTemp="你的薪資水平:"; strTemp+=m_strSalary; pDC->TextOut(0,tm.tmHeight*3,strTemp); pDC->SelectObject(pOldFont); } |
下面講述一個屬性頁面對話方塊的使用常式。
1,VC++經常問題。
不能為已建好的類開啟檔案
在VC中為資源(對話方塊、屬性頁面等)添加類時,開啟classwizard=>添加類,輸入類名,選擇baseclass,點OK之後,彈出不能開啟檔案的錯誤"Unable to open the file(XXX.h,XXX.cpp) for class xxx"
解決辦法:刪除類資訊檔XXX.clw;再次調用classwizard,重新產生一個xxx.clw即可
2,屬性頁面資源的增加
在Resource View裡Dialog處點擊右鍵InsertèDialogèIDD_PROPPAGE_LARGE(English(U.S.))
注意看屬性頁面資源的屬性:類型-Child,Border-Thin,System menu不複選,More style中複選了Disabled
也可以通過修改普通對話方塊,而成為屬性頁面。
3,建立類
給屬性頁面對話方塊添加類的時候,基類選為CPropertyPage,而不是CDialog
4,建立屬性工作表單
利用Classwizard插入一個新的類,基類選為CPropertySheet
5,給屬性工作表單添加三個public變數
CProp1 m_prop1;
CProp2 m_prop2;
CProp3 m_prop3;
6,在屬性工作表單的兩個建構函式增加表單
AddPage(&m_prop1);
AddPage(&m_prop2);
AddPage(&m_prop3);
7,在View類添加一個功能表項目,添加響應函數,添加下列語句
CPropSheet propSheet("維新屬性工作表單程式");
//propSheet.SetWizardMode();//嚮導類時增加這一句
if(ID_WIZFINISH==propSheet.DoModal())
{
//擷取各個表單項的選項,僅作為例子
m_iOccupation=propSheet.m_prop1.m_occupation;
m_strWorkAddr=propSheet.m_prop1.m_workAddr;
m_bLike[0]=propSheet.m_prop2.m_football;
m_strSalary=propSheet.m_prop3.m_strSalary;
Invalidate();
}
屬性工作表單建立完畢。屬性頁面具體內容的編輯和內容的顯示過程省略
三. 嚮導類的建立
step1: Excel和Word就是多文檔程式;
支援文檔--視類架構? 如果取消,則沒有Doc類了
step2: 是否要包含對資料庫的支援
step3: 是否要包含對複合文檔姝支援
step4: 去掉列印和預覽列印
Docking toolbar
Initial status bar
Printing and print preview
Context-sensitive help
3D controls
MAPI[Message API]
Windows Sockets
How do you want your toolbars to look?
Normal / Internet Explorer ReBars
進階選項: Windows Styles...等等
文件範本字串:一般不需要修改
使用分隔視窗; 邊框;最小/已最大化的視窗, 系統功能表, 最小/最大化顯示
step5: 工程類型: MFC標準,還是Windows Explorer 資源管理員類型?
注釋
MFC 庫: as a shared dll (多數WINDOWS平台已經隨著系統的安裝安裝了,故多選此項); or as a statically linked library
step6:
修改視類的基類: CEditView或CRichEditView
1,在Domodal之前添加
propSheet.SetWizardMode();
2,設定最初/末頁的“上一步”和“下一步”
在CProp1類處右鍵,載入虛函數OnSetActive,並在CProp1::OnSetActive中添加
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT);
在CProp4::OnSetActive中添加
((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH);
為每一頁添加限制條件:只有在當頁進行必要操作後,才能“下一步”
1, 為每個屬性頁面添加虛函數DoDataExchange,其中不添加代碼
2,為最後一頁添加虛函數OnWizardFinish,其他頁添加OnWizardNext函數,並在其中添加“下一步”的判斷條件
資料交換
UpdateData(TRUE);//從控制項中取回值
UpdateData(FALSE);//將變數值賦給控制項