(孙鑫 八) 对话框

逃跑按钮的巧妙实现。如何制作属性页对话框和向导对话框,融合讲解组合框(如何调整组合框的大小)、列表框、单选按钮、复选按钮等常用对话框控件的多种使用方法。如何限制用户在不满足设定的条件时切换到其他属性页和向导页。 

1.逃跑按钮:在对话框上点右键可设置按钮的字体等。制作两个一样的按钮,鼠标移动到一个按钮时就消失,另一个显示。
  用类向导增加一个新的类,CWeiXinBtn,基类选择CButton。再将两个按钮关联成员变量,如m_btn1/m_btn2,数据类型选择CWeiXinBtn。要在CTestDlg的头文件里包含#include "WeiXinBtn.h"
  在CWeiXinBtn中添加消息处理WM_MOUSEMOVE,再在CWeiXinBtn类中添加成员变量,public的CWeiXinBtn*的m_pBtn,用来存放另外一个按钮的对象指针。
  可在CTestDlg的OnInitDialog函数(响应WM_INITDIALOG消息,对话框要显示之前发送的)中保存按钮对象指针:
	m_btn1.m_pBtn=&m_btn2;
	m_btn2.m_pBtn=&m_btn1;
  然后在CWeiXinBtn的OnMouseMove函数中,隐藏自身,显示其他。
	ShowWindow(SW_HIDE);
	m_pBtn->ShowWindow(SW_SHOW);  //可以去掉其中一个按钮的visible复选

2.属性表单(多个信息不能在一页显示完,要有属性页)、向导(如下一步……)
  可插入一个属性页资源:Dialog--IDD_PROPPAGE_……(有large、medium和small),这里插入3个large的属性页。分别取ID号为IDD_PROP1,PROP2,PROP3,名字分别叫page1、page2、page3(也就是选项卡的名字)
  在第一个页面中创建一个组框(group box标记、分组的作用),第一个标题设置为“请选择你的职业:”,在里面放置3个单选框。(名字分别为程序员、系统工程师、项目经理)
  再添加一个列表框,其上放一个静态文本框(标志作用:请选择你的工作地点)
  在第二个页面中创建一个组框(选择兴趣爱好),添加几个复选框。
  在第三个页面中增加一个组合框,拉动得大一些(因为拉多大它就显示多大),组合框Combo box有3种格式,simple(不用点击下拉,直接显示)、dropdown(默认),droplist(只能显示)。在上面放一个静态文本框(请选择你的薪资水平)。
  选择类向导,为刚才的3个资源创建新的类,注意要选择CPropertyPage基类。这时VC会有问题(据说是编译器自己的问题,貌似这个版本没有问题),这时类视图中虽然有了这个类,但在类向导中没有。名字叫CProp1
  工程的一些类信息就保存在clw文件中。(classwizard)删除之后,就可以重新建立了。

3.CPropertyPage也是从CDialog派生的。需要创建一个CPropertySheet来增加每个属性页。(AddPage、DoMal模态、Create非模态)
  插入一个新的类,CPropSheet……基类。
void AddPage( CPropertyPage *pPage ); //添加属性页
  可在属性表单的构造函数中添加。在属性表单对象中增加成员变量CProp1,m_prop1(添加3个)。还要在Sheet的头文件里包含这三个类的头文件。它有两个构造函数(一个用ID号,一个用字符串)
CPropertySheet( UINT nIDCaption, CWnd *pParentWnd = NULL, UINT iSelectPage = 0 );
CPropertySheet( LPCTSTR pszCaption, CWnd *pParentWnd = NULL, UINT iSelectPage = 0 );
//若父窗口为NULL,则默认为程序的主窗口。iSelectPage设置初始显示的属性页码
 	AddPage(&m_prop1);
	AddPage(&m_prop2);
	AddPage(&m_prop3);
//而CPropertySheet是从CWnd派生出来的。
  再增加一个菜单项来显示属性表单IDM_PROPERTYSHEET(属性表单),添加命令响应,增加函数。(在view类)
  在此函数中,先构造一个对象。
	CPropSheet2 propSheet("属性表单程序");  //即为表单窗口名称
	propSheet.DoModal();
  但这样插入后,属性表单是乱码,因为默认设置的英文,要改为中文。(资源视图中右键改即可),还要将属性页的字体都改为“宋体”。

4.向导创建
  后面跟创建属性页一样的,但在调用DoModal之前要调用SetWizardMode。
	CPropSheet2 propSheet("属性表单程序");
	propSheet.SetWizardMode();
	propSheet.DoModal();

//CPropertySheet::SetWizardButtons有关成员函数,void SetWizardButtons( DWORD dwFlags );
//可设置PSWIZB_BACK,NEXT,FINISH,DISABLEDFINISH
  它一般在CPropertyPage::OnSetActive中调用&&&,当选项页被选择的时候,OnSetActive就会被框架调用。
  对着CProp1点右键增加一个虚函数,选择OnSetActive,然后设置按钮:
	((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH);		

5.对单选框进行判断:对单选框(先设置属性:将 组group 复选上,则从属于一个组;后面的不选)右键--选择类向导,增加一个变量m_occupation value int.(被初始化为-1,说明没有选按钮),在DoDataExchange中与控件交换了数据。//选中了哪个,m_occupation就变成……
  对着CProp1右键增加一个虚函数,OnWizardNext(下一步按钮被点击时调用),此函数若返回0就跳到下一个界面,若返回-1就不跳。
  
LRESULT CProp1::OnWizardNext() 
{
	// TODO: Add your specialized code here and/or call the base class
	UpdateData();  //这句必须,否则控件内容没给m_occupation做数据更新
	if(-1==m_occupation)
	{
		MessageBox("请选择一个职业!");
		return -1;
	}
	return CPropertyPage::OnWizardNext();
}

CProp1的InitDialog函数中初始化列表框控件(CListBox类),用AddString增加一个字符串
	((CListBox*)GetDlgItem(IDC_LIST1))->AddString("北京"); //增加到列表框

  再对列表框关联一个变量(判断是否选择列表框),m_WorkAddr value CString ,初始化为空
  所以可在OnWizardNext里面判断,是否为空
	if(""==m_WorkAddr)
	{
		MessageBox("请选择工作地点!");
		return -1;
	}

  给4个复选框添加4个成员变量 BOOL m_…………当选中的时候,关联的成员变量就是真。增加虚函数OnWizardNext来判断
	UpdateData();
	if(m_football || m_basketball || m_volleyball || m_swimming)
		return CPropertyPage::OnWizardNext();
	else
	{
		MessageBox("请选择你的兴趣爱好!");
		return -1;
	}

  组合框(编辑框和列表框的组合)是CComboBox类,也有AddString增加一个字符串。但组合框本身有关排序的功能,在属性--样式--分类复选框(默认选中),可以取消它(就按你输入的顺序排列了)。
	((CComboBox*)GetDlgItem(IDC_COMBO1))->AddString("1000元");
  可用它的成员函数,SetCurSel选择一个选项。int SetCurSel( int nSelect );//-1就是空,从0开始
					((CComboBox*)GetDlgItem(IDC_COMBO1))->SetCurSel(0);

  在CProp3添加虚函数OnWizardFinish,用int GetCurSel( ) const;//获取选择的数据的索引值
用GetLBText从组合框中获取字符串
int GetLBText( int nIndex, LPTSTR lpszText ) const;
void GetLBText( int nIndex, CString& rString ) const;
在完成按钮中存储数据:
 	int index;
	index=((CComboBox*)GetDlgItem(IDC_COMBO2))->GetCurSel();
	((CComboBox*)GetDlgItem(IDC_COMBO2))->GetLBText(index,m_strSalary);

  然后再view类输出选择的数据。这里要看view中调用的DoModal返回值是什么来判断是取消还是完成(若成功,它返回IDOK或者IDCANCEL,否则0或-1;若是一个向导,则返回ID_WIZFINISH或者IDCANCEL)
  在view类定义一些变量来记录用户选择的数据:
	int m_occupation;
	CString m_strWorkAddr;
	BOOL m_bLike[4];
	CString m_strSalary;
  在构造函数中初始化:
	m_occupation=-1;
	m_strWorkAddr="";    
//void *memset( void *dest, int c, size_t count );//设置数组,方便&&&
 	//dest是数组名,c是设置值,count是数组大小
	memset(m_bLike,0,sizeof(m_bLike));
	m_strSalary="";

  在OnPropertysheet函数中,创建的propSheet对象在DoModal完成后还没有销毁,所以可以读取数据。
	CPropSheet2 propSheet("属性表单程序");
	propSheet.SetWizardMode();
	if(ID_WIZFINISH==propSheet.DoModal())
	{
		m_occupation=propSheet.m_prop1.m_occupation;
		m_strWorkAddr=……m_bLike[0]=……
		……
		Invalidate();  //使窗口无效??然后再OnDraw函数中重画
	}

  在view的OnDraw函数中:
	CFont font;
	font.CreatePointFont(300,"华文行楷");
	
	CFont *pOldFont;
	pOldFont=pDC->SelectObject(&font);

 	CString strTemp;
	strTemp="你的职业:";
	
	switch(m_occupation)
	{
		case 0:
			strTemp+="系统工程师" //后面省略
			break;
		case 1:
			break;
		default:
			break;

	}
	
	pDC->TextOut(0,0,strTemp);
//后面继续,strTemp="你的工作地点:",然后+=m_strWorkAddr;
//TEXTMETRIC tm;
//pDC->GetTextMetrics(&tm);  然后在此高度输出

//然后再strTemp="你的兴趣爱好:";
//if(m_bLike[0])strTemp+="足球 ";
//……然再tmHeight*2的地方输出
//薪资水平也直接加就可以了
	pDC->SelectObject(pOldFont);


你可能感兴趣的:(编程学习)