⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 03.3.2 在窗口中显示按钮(1).txt

📁 网上第一本以TXT格式的VC++深入详解孙鑫的书.全文全以TXT格式,并每一章节都分了目录,清晰易读
💻 TXT
字号:
3.3.2  在窗口中显示按钮
为了更好地理解窗口类、窗口类对象和窗口之间的关系,我们接下来实现在窗口中显示一个按钮这一功能,仍在已有的Test程序中实现。首先需要创建一个按钮类对象,按钮对应的MFC类是CButton类,其继承层次结构如图3.24所示,从而可以得知CButton类派生于CWnd类。



图3.24  CButton类的继承层次结构

在MFC提供的资源类中,有些类的对象的构造(包括对象构造与初始化)直接通过其构造函数就可以完成。也就是说,这些对象的构造函数包含这个对象的初始化操作。但有些对象的产生除了调用构造函数外,还需要调用其他一些函数来进行初始化的工作,然后才能使用该对象。

对于一个CButton对象,在定义之后就可以使用了。但是作为一个窗口类对象,即CWnd对象,如果在构造之后还需要产生这个窗口的话,还需要调用CreateEx函数来完成初始化工作。也就是说,如果要显示一个按钮的话,在定义这个CButton类对象之后,即调用CButton类的构造函数之后,还需要调用CButton的Create函数创建这个按钮窗口,从而把按钮窗口与CButton对象关联起来。

CButton的Create函数声明如下。

BOOL Create( LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

各个参数的意义如下所述。

n  lpszCaption

指定按钮控件的文本。

n  dwStyle

指定按钮控件的风格。按钮控件不仅具有按钮风格类型,还具有窗口风格类型。多种风格类型可以通过位或操作加以组合。

n  rect

指定按钮控件的大小和位置。该参数是RECT结构体类型,通过指定左上角和右下角两个点的坐标定义一个矩形。结构体也是一种特殊的类,所以可以用类CRect来构造一个RECT结构体。

n  pParentWnd

指定按钮控件的父窗口。这是一个CWnd类型的指针。MFC中不再通过窗口句柄,而是通过一个与窗口相关的C++窗口类对象指针来传递窗口对象。

n  nID

指定按钮控件的标识。

为了在框架窗口上产生一个按钮控件,显然应该是在框架窗口产生之后,再创建该按钮控件,否则没有地方放置它。窗口创建时都会产生WM_CREATE消息,CMainFrame类提供一个OnCreate函数,该函数就是用来响应这条窗口创建消息的。该函数的默认实现代码如例3-22所示。

例3-22

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)

        return -1;

    

    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP

        | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||

        !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

    {

        TRACE0("Failed to create toolbar\n");

        return -1;      // fail to create

    }

 

    if (!m_wndStatusBar.Create(this) ||

        !m_wndStatusBar.SetIndicators(indicators,

          sizeof(indicators)/sizeof(UINT)))

    {

        TRACE0("Failed to create status bar\n");

        return -1;      // fail to create

    }

 

    // TODO: Delete these three lines if you don't want the toolbar to

    //  be dockable

    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

    EnableDocking(CBRS_ALIGN_ANY);

    DockControlBar(&m_wndToolBar);

 

    return 0;

}

从例3-22所示代码可知,CMainFrame类的OnCreate函数首先调用基类CFrameWnd的OnCreate函数,创建一个窗口,然后创建工具条(m_wndToolBar)和状态栏(m_ wndStatusBar)对象。我们可以在该函数的最后完成按钮的创建工作,即在return语句之前添加例3-23所示代码中加灰显示的代码。

例3-23

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

……

    CButton btn;

    btn.Create("按钮",WS_CHILD | BS_DEFPUSHBUTTON,CRect(0,0,100,100),this, 123);

 

    return 0;

}

其中,将该按钮的名称设置为“按钮”,其位置由CRect(0,0,100,100)这一矩形确定,ID号为123。前面已经讲过,按钮控件不仅具有按钮风格类型,还具有窗口风格类型,因此,在按钮的Create函数中指定该按钮具有WS_CHILD窗口风格类型,同时还具有BS_DEFPUSHBUTTON按钮风格类型,即下按按钮风格。

另外,我们知道每个对象都有一个this指针,代表对象本身。为了使按钮控件的父窗口就是框架窗口,这里可以直接将代表CMainFrame对象的this指针作为参数传递给按钮的Create函数。

编译并运行Test程序,但发现按钮并没有显示出来。问题的原因有两个:一是这里定义的btn对象是个局部对象,当执行到OnCreate函数的右大括号(})时,该对象的生命周期就结束了,就会发生析构。前面已经讲过,如果一个窗口与一个C++窗口类对象相关联,当这个C++对象生命周期结束时,该对象在析构时通常会把与之相关联的窗口资源进行回收。这就是说,当执行到例3-22所示的OnCreate函数的右大括号时,刚刚创建的btn窗口就被与之相关的C++对象销毁了。因此,不能将这个按钮对象定义为一个局部对象。解决方法是:将其定义为CMainFrame类的一个成员变量,可以将其访问权限定义为private类型以实现信息隐藏。

有多种方法可以定义一个类的成员变量,可以直接在该类的定义中添加成员变量定义代码,也可以利用VC++提供的工具来定义。后者的方法是:在ClassView标签页中的类名上单击鼠标右键,从弹出的快捷菜单上选择【Add member variable…】菜单命令,将弹出Add Member Variable对话框。通常,在定义类的成员变量名称时都以“m_”为前缀,表明这个变量是类的一个成员变量。在添加成员变量对话框的Variable Type(变量类型)文本框中输入变量类型CButton,Variable Name(变量名称)文本框中输入按钮对象名称m_btn,并为其选择private类型的访问权限,如图3.25所示。



图3.25  Add Member Variable对话框

然后单击对话框上的【OK】按钮,即可以在CMainFrame类的头文件中看到新成员变量的定义,代码如下:

private:

    CButton m_btn;

修改例3-23所示CMainFrame类OnCreate函数中创建按钮的代码,删除局部按钮对象的定义,并将按钮创建函数的对象名称改为m_btn,结果如例3-24所示。

例3-24

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

……

    m_btn.Create("按钮",WS_CHILD | BS_DEFPUSHBUTTON,CRect(0,0,100,100), this,123);

 

    return 0;

}

再次运行Test程序,将会发现按钮还没有出现。这一问题的第二个原因就是在一个窗口创建完成之后,应该将这个窗口显示出来。因此,需要在调用Create函数之后再添加一条窗口显示代码,如例3-25所示。

例3-25

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

……

1. m_btn.Create("按钮",WS_CHILD | BS_DEFPUSHBUTTON,CRect(0,0,100,100), this,123);

2. m_btn.ShowWindow(SW_SHOWNORMAL);

 

    return 0;

}

再次运行Test程序,这时就可以看到按钮出现了,如图3.26所示。



图3.26  在框架窗口中显示按钮

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -