1 MFC中OnCreate()和OnInitDialog()的区别
实例:做了一个属性页对话框,在上面添加了一个ListBox控件,用代码AddString("example item")添加项目,先是在属性对话框类的构造函数里添加,运行报错,后在OnCreate()中添加又报错,于是在OnInitDialog()中添加就OK了,经查发现:OnCreate()是在对话框创建时,此时对话框上的控件还没有,所以不能对对话框上的控件进行操作。OnInitDialog()则是对话框创建完毕,执行此函数时控件也可以使用。
2 属性页,向导生成 练习程序41
eg.
①插入对话框IDD_PROPPAGE_LARGE_[English US]. 连续插入三个, 更改属性中的ID,语言改为中文(否则在上面显示中文时会乱码,默认为English).
②新建类--基类选择CPropertyPage,分别对应上面三个对话框新建三个类,CProp1, CProp2, CProp3
③新建类--基类选择CPropertySheet, 类名CPropSheet
④在CPropSheet类中添加三个成员变量 :CProp1 prop1; CProp2 prop2; CProp3 prop3;
NOTE: take wizard for example blew ( not include Property )
prop1应该只有下一步按钮可用,prop2上一步 下一步可用, prop3上一步 完成可用
在三个prop类上添加virtual functio OnSetActive(), 分别设置SetWizardButtons(),注意这里该函数是CPropertyPage的函数,所以要用该函数的对象或指针调用,而不是用CPropertyPage的对象或指针调用
BOOL CProp1::OnSetActive()
{
// TODO: Add your specialized code here and/or call the base class
CPropSheet *pSheet = (CPropSheet*) GetParent();here
pSheet->SetWizardButtons(PSWIZB_NEXT); //here
return CPropertyPage::OnSetActive();
}
为页面的 下一步 完成 上一步(if nessary)添加检测是否选择了该页面上的控件值的代码,几个控件的用法见下面 “ 3 几种控件的用法”
⑤在CPropSheet类构造函数(有两个构造函数)中,添加三个上面三个对象
AddPage(&prop1);
AddPage(&prop2);
AddPage(&prop3);
⑥找个地方能调出这个属性/向导 ,本例中是在View类中响应菜单上的按钮命令来调出的(也可以在框架类CMainFrame中响应菜单命令),
添加消息响应的方法:
类声明中: afx_msg void OnDialog();
类定义中消息映射的地方:ON_COMMAND(ID_XXX, OnDialog) //NOTE: 没有分号 函数没有括号
函数定义如下 ,这里是完成向导的功能
void CMy41View::OnDialog()
{
CString str = "向导";
CPropSheet propSheet(str);
propSheet.SetWizardMode(); //在DoModal()之前调用SetWizardMode()就是向导,否则就是属性页,这里主 //要介绍向导
if (ID_WIZFINISH == propSheet.DoModal()) //如果是向导,DoModal()返回值为ID_WIZFINISH or //IDCANCEL, 如果是属性页,该函数返 回IDOK or IDCANCEL
{
CClientDC dc(this);
TEXTMETRIC tm;
CFont font;
font.CreatePointFont(200, "幼圆", NULL);
CFont *oldFont = dc.SelectObject(&font);
dc.SetTextColor(RGB(100, 100, 100));
dc.GetTextMetrics(&tm);
CString str1 = "您的职业及工作地是: ";
str1 += CMainFrame::strWorkInfo;
dc.TextOut(0, 0, str1);
CString str2 = "您的兴趣爱好是: ";
str2 += CMainFrame::strFun;
dc.TextOut(0, tm.tmHeight, str2);
CString str3 = "你的收入水平是: ";
str3 += CMainFrame::strSalary;
dc.TextOut(0, 2 * tm.tmHeight, str3);
dc.SelectObject(oldFont);
}3 几种控件的用法
①RADIO单选按钮
拖出几个按钮后,如果要在这几个按钮中选择一个,那么就在拖出的第一个按钮上右键--组 勾选,那么直到遇到下一个为“组” 的RADIO为止,之前的都是一个组里的 也就是说是从一组中选一个。
为这一组按钮添加一个value的int型成员变量,可以看到在类向导中只有勾选组的那个按钮显示在上面,添加完后,可以在该对话框类(RADIO所在的对话框)中看到添加的成员变量值为-1, 该组中按钮按顺序,选中第一个后该成员变量为0, 选第二个为1,依次。。,根据其值为n可以判断是选择的第n+1个单选按钮。
NOTE: value类型的控件成员变量使用前后要注意刷新
UpDateData(TRUE);//控件-->变量
//code : use this variable
UpDateData(FALSE);//变量-->控件
②CListBox
在所在的对话框的OnInitDialog()中添加给ListBox控件添加项目的代码
BOOL CProp1::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: Add extra initialization here
CString str[] = {"北京", "上海", "青岛"};
for (int i = 0; i < sizeof(str) / sizeof(CString); i ++)
{
m_listBox.AddString(str[i]); ///here
}
CMainFrame::strFun = CMainFrame::strSalary = CMainFrame::strWorkInfo = "";
// SetDlgItemText(IDC_TXT, str2[0] + str2[1]);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
为该控件添加一个成员变量CString类型的value变量,初始空,选择后即有值。
③CheckBOx
添加value变量,BOOL型,初始为FALSE, 勾选后为TRUE,从而判断。
④ComboBox
在所在的对话框的OnInitDialog()中添加给ComboBox控件添加项目的代码
BOOL CProp3::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: Add extra initialization here
CString strSalary[] = {"2000以下","2000到3000","3000到5000","5000以上"};
for (int i = 0; i < sizeof(strSalary) / sizeof(CString); i ++)
{
m_comboBox.AddString(strSalary[i]); /here
}
m_comboBox.SetCurSel(0); /// here 设置哪个显示出来 也就是默认。
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
⑤SUMMARY
选择控件的值(文字 , 比如RADIO的职业选择)
CString str = "";
都可以使用GetDlgItemText(IDD_XXX, str);
?