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:
-
PSWIZB_BACK Back button
-
PSWIZB_NEXT Next button
-
PSWIZB_FINISH Finish button
-
PSWIZB_DISABLEDFINISH Disabled Finish button
-
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) CFont *pOldFont; CString strTemp; switch(m_iOccupation) strTemp="你的工作地点:"; TEXTMETRIC tm; pDC->TextOut(0,tm.tmHeight,strTemp); strTemp="你的兴趣爱好:"; 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);//将变量值赋给控件