第8课 逃跑按钮的巧妙实现

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)
{
    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);//将变量值赋给控件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值