返回首页

{A}{S0}Visual Studio 2005的更新
请注意,我添加了一个Visual Studio 2005的用户可下载的示范项目。一切都在原来的文章,以及适用于Visual Studio 2005中使用的,除了有关使用ClassWizard创建类​​/对象的协会的位。我假设,如果你是使用Visual Studio 2005,你已经知道如何定义协会,添加事件处理程序等,因此,恰恰忽视了类向导意见。重要的是,如果你派生自己的类,你必须做出一定的对话栏的资源ID匹配类的头文件中定义的资源ID。如果您使用的派生类,我已经提供了,那么你需要简单的名称在资源编辑器IDD_DIALOGBAR的对话栏的资源,你将被罚款。看演示,如果你仍然有难以落实,我行。简介
我看到很多帖子最近在论坛和文章评论,读者想知道如何使用一个对话栏绘制业主或自定义控件。尽管这些信息是来自微软的各种物品,我决定发表这篇文章的教程,把一篇文章的所有信息....当然,提供工作的例子来看看。
为了实现这一目标,你必须从CDialogBar派生的类的基础上的对话栏。由于应用程序向导不支持此操作,你必须从CDialog派生类,然后手动将其转换为一个CDialogBar类。由于微软的文章,让您一步一步的指示,我不会重复他们的工作。我就点你该文章:

还有一个姊妹篇:

在这个例子中派生类创建了下面这篇文章的指示,主要。使用示例类
要使用在您的应用程序,例如类,只需按照下列步骤操作。我假设你正在使用Visual Studio,在我的情况,6。
首先,从Visual Studio主菜单,单击"插入/资源,然后展开对话框。单击IDD_DIALOGBAR,然后单击新建。您现在有一个新的对话栏资源添加到项目中。默认情况下,这一资源的ID是IDD_DIALOGBAR。离开,因为它是,如果你改变的ID,那么你就必须改变在派生类的头文件的ID以及。现在,添加到您的项目从派生类的示例项目文件夹的MyDlgBar.h和MyDlgBar.cpp文件。
在这一点上,你将要链接到您的对话栏派生类。进入到项目文件夹,*. clw文件删除(或重命名)。然后选择你在资源编辑器,然后按CTRL_W的对话栏。 ClassWizard将提示重建类向导数据库。确保MyDlgBar.h和MyDlgBar.cpp文件列表中,让它重建。然后它会提示您添加一个新的类,或选择一个对话栏资源现有类。选择选择现有的类,然后选择CMyDlgBar类。单击"确定"。现在,在您为MainFrm.h文件的顶部,只是上面的类声明中,添加下面的行:

 . . . . . . . . . . . . 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000



#include "MyDlgBar.h"  <--- ADD THIS LINE



class CMainFrame : public CFrameWnd

{

 . . . . . . . . . . . . . . .

然后,您为MainFrm.h文件的类声明内,建立一个这样的对话栏的实例:{C}
最后,你MainFrm.cpp文件的OnCreate()函数,添加以下代码:
           if (!m_myDlgBar.Create(this, IDD_DIALOGBAR,

                        CBRS_TOP | CBRS_GRIPPER |CBRS_TOOLTIPS | 

                        CBRS_FLYBY | CBRS_HIDE_INPLACE,

                        IDD_VIEW_DIALOGBAR))

                {

                        TRACE0("Failed to create dialog bar m_wndDlgBar\n");

                        return -1;              // fail to create

                }



                m_myDlgBar.EnableDocking(CBRS_ALIGN_TOP | CBRS_ALIGN_BOTTOM);

                EnableDocking(CBRS_ALIGN_ANY);

                DockControlBar(&m_myDlgBar);

您可以修改此,如果你喜欢。这将创建一个标准的可停靠对话框栏,夹具,所以它可以脱开或移动。默认情况下,它是创建停靠在应用程序的顶部。注意在创建函数IDD_VIEW_DIALOGBAR。这是使用,如果你想在"视图"菜单上添加一个菜单选项来切换隐藏/显示对话栏,工具栏和状态栏通常做。添加这个功能是很容易的。只要在你的资源编辑器的查看菜单上创建一个新的菜单项。给它一个IDD_VIEW_DIALOGBAR编号和任何你想的标题,如放大器;对话酒吧。 MainFrm.cpp文件AFX_MESSAGE_MAP节这样,然后添加以下两行代码:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

 //{{AFX_MSG_MAP(CMainFrame)

 ON_WM_CREATE()

 // AND THE LINE BELOW

 ON_COMMAND_EX(IDD_VIEW_DIALOGBAR, OnBarCheck)  

 // AND THE LINE BELOW

 ON_UPDATE_COMMAND_UI(IDD_VIEW_DIALOGBAR, OnUpdateControlBarMenu)

 //}}AFX_MSG_MAP

END_MESSAGE_MAP()

现在你可以编译和运行。您将有一个对话栏,除非你对此一无所知。因此,让我们添加一个所有者绘制的CBitmapButton的乐趣。添加一个所有者绘制的CBitmapButton的
只需添加一个按钮,正常的对话栏。在"属性",检查所有者绘制的标题。给它一个编号IDC_BUTTON_BITMAP和一个按钮的标题。这是这里的重要组成部分,因为AUTOLOAD()函数读取的标题,以确定哪些位图加载。现在,创建了4位图和添加/导入到您的项目之一,为每个状态:按钮,按钮式,按钮的焦点和按钮禁用。唯一的按钮和按钮式,是必需的;,其他两个是可选的。一旦你添加/导入其中,以下改变自己的ID(注意:包括引号):"BUTTONUquot;,"BUTTONDquot;,"BUTTONFquot;和"BUTTONXquot;
现在在ClassView选项卡,右键点击CMyDlgBar,并选择"添加成员变量。 CBitmapButton的类型变量类型和变量名m_bmButton;使其保护。在MyDlgBar.cpp文件的Create()函数,调用基类后,添加以下代码:
   if(bReturn)

                m_bmButton.AutoLoad(IDC_BUTTON_BITMAP, this);

同样,如果你给你一个不同的ID按钮,您将需要更改ID。这是... ...现在你有一个所有者绘制的CBitmapButton的。唯一剩下的就是为按钮添加消息处理程序。添加消息处理程序
的消息就像任何对话栏,必须处理的大型机,文档或视图类。在视图类中,我们会处理这一个。您必须手动添加您的消息处理程序。在你的视图类的头文件,函数声明中添加消息映射部分,是这样的:
// Generated message map functions

protected:

        //{{AFX_MSG(CDerivedDBView)

        afx_msg void OnButtonBitmap();   <----  ADD THIS LINE

        //}}AFX_MSG

        DECLARE_MESSAGE_MAP()

};

,然后在你的View类的*. cpp文件的消息映射,编辑代码如下:
现在你添加功能的实现您的视图类的*. cpp文件的底部:
void CDerivedDBView::OnButtonBitmap()

{

        CString msg = "You Clicked a CBitmapButton on a Dialog Bar       \n";

        msg += "in a CDialogBar derived class!                ";

        AfxMessageBox(msg);

}

最后一件事:在你的View类的*. cpp文件顶部,添加一行:
#include "MyDlgBar.h"

这是所有有给它。编译,运行和瞧!,您必须在您的对话栏工作CBitmapButton的。这也将与任何自定义的控制。如果您想,您可以添加一个ActiveX控件。您添加任何控制,需要初始化,子类,所有者绘制或什么,只是在MyDlgBar.cpp的Create()重载函数初始化后调用基类。例如:在子类的按钮控制
演示项目包括在对话栏子类的按钮控制。 派生你的类的说明。子类在对话栏的按钮,继承现有项目中使用他的指示。在示例项目中MyDlgBar.h和MyDlgBar.cpp的文件,看看这是如何实现。要使用示例类文件,只需添加NewButton.h和NewButton.cpp到您的项目。
现在拖到对话栏按钮,并给它一个IDC_DBSUB_BUTTON编号。然后,只需添加一个NewButton.h在MyDlgBar.h文件中包括添加成员变量的类型CNewButton(即CNewButton m_subButton)。然后,在Create()函数MyDlgBar.cpp(高于或低于您CBitmapButton的初始化代码),添加一行:
m_subButton.SubclassDlgItem(IDC_DBSUB_BUTTON, this);

既然你有一个以上的指令,可以肯定的周围放置您的指示下,if()语句的括号。还要注意的是,我们没有指定的按钮,在资源编辑器的所有者绘制。这是因为我们成立了我们的派生类(如每克里斯的指示),以强制所有子类的项目业主绘制。就是这样。用你的想象力,你可以与任何一个对话栏的控制类似的自定义。历史04年12月30日 - 新增子类化按钮控制。01/07/05 - 固定ZIP存档的兼容性问题。06年12月7日 - DerivedDlgBar_demo.zip是一个更新的演示项目,修复与类向导添加子类控制变量DDX数据交换方法的问题。 DDX的原因在某些情况下的一个子类调用冗余和调试汇编ASSERTS。如果使用类向导来创建你的子类的控制变量,并获得WinCore.cpp断言,您将需要手动删除的DDX数据地图父*. cpp文件中的条目。在本演示中,CBitmapButton的AUTOLOAD()方法中出现的问题。07年11月7日 - 上传Visual Studio 2005的演示项目

回答

评论会员:jamluke 时间:2011/12/03
您好,
我已经实现了很好的例子,一切正常,但现在我已经增加了一个简单的按钮,我想,"禁用"状态开始,我已经从资源视图改变,但没有...我也试图改变这样的状态MyView的类的OnInitialUpdate:CMainFrame中* p_mainFrame =(CMainFrame中*)AfxGetMainWnd()

CButton的* p_btSelect =(CButton的*)(p_mainFrame> GetConnectDlgBar() - > GetDlgItem(IDC_BUTT_SELECT))

p_btSelect - > SetButtonStyle(WS_DISABLED,TRUE);
任何想法?遗憾,但我从4日开始使用C和MFC: - >

在此先感谢
评论会员:morganrg 时间:2011/12/03
。感谢您的文章,但我使用了Visual Studio的新版本 - 2005 - 这不有一个clw文件

在这种情况下,我应该怎么办?
评论会员:安蒂Keskinen 时间:2011/12/03
我假设你已经知道如何添加事件处理程序,变量等。在VS2005。所以你唯一需要担心的是如何关联的一类与适当的资源,等在这里的最简单的解决方案。如果您使用的派生类,我在示例项目中提供,那么所有你需要做的的就是确保您的DialogBar资源被命名为IDD_DIALOGBAR,你应该罚款。如果您必须将其命名为别的东西,然后你会做一个全局搜索和替换MyDlgBar源文件,这样的类文件是适当的资源。我的文章更新和补充,您可以下载一个VS2005演示项目。可能需要CP A两天在网上得到它,但它观看和下载它。在示例项目看..这是非常简单和直接的..你应该能够很容易弄明白。如果仍然有问题,请给我行祝你好运!



在企业中,如果两个人总是同意,其中之一是不必要的。
评论会员:bhumble 时间:2011/12/03
写得很好,很好的布局和重点上一个很好的话题

这些详细信息,请

- 安蒂

------------------------------{ BR}Windows程序设计就像是
了一盒什锦巧克力。

你永远不知道你
要得到
评论会员:。bhumble 时间:2011/12/03
我很欣赏的反馈


在企业中,如果两个人总是同意,其中之一是不必要的。
评论会员:bhumble 时间:2011/12/03
您好,

感谢非常透彻的教程,我目前正在申请我在哪里,我需要在CDialogBar一些CBitmapButtons工作在一个项目的概念。虽然我看到的是一个问题,当我下载示例代码,作出任何修改,并编译它使用调试配置,我得到一个字符串Wincore断言。如果我通过点击这些断言该程序最终运行良好。此外,如果我在Release模式编译工作正常,但这些说法让我感到担忧。你知道什么可能会导致他们吗?
评论会员:wzh19831221 时间:2011/12/03
对不起... ...我忘了给细节。我在Windows XP上运行VisualStudio 6.0 SP6的。确切的错误是一个调试断言失败wincore.cpp行320,然后321行,然后3866,然后3877,然后运行该程序后,

我遇到了麻烦工作在自己的程序代码,我想知道如果我看到的问题可能与此有关。
评论会员:wzh19831221 时间:2011/12/03

好..
我发现这个问题,这样我就可以删除之前我写的一切。

在MyDlgBar.cpp删除的DoDataExchange DataMap从以下两个项目:
	DDX_Control(pDX, IDC_DBSUB_BUTTON, m_subButton);

	DDX_Control(pDX, IDC_BUTTON_BITMAP, m_bmButton);

然后在MyDlgBar.h移动到空间一般从AFX_DATA段的变量声明,像这样:
// Construction

public:

	CMyDlgBar();   // standard constructor



	CNewButton m_subButton;

	CBitmapButton	m_bmButton;

 

// Dialog Data

	//{{AFX_DATA(CMyDlgBar)

	enum { IDD = IDD_DIALOGBAR };

	//}}AFX_DATA

应该做的伎俩。我会尽力尽快公布一个固定的zip。感谢指出错误。 的问候,道格

- 修改在19点39日(星期四)第七年12月,2006
在企业中,如果两个人总是同意,其中之一是不必要的。
评论会员:wzh19831221 时间:2011/12/03
我已经更新文章下载一个固定的示范项目。发现一个注释,描述的问题是在文章的结尾。历史总之,如果你在未来的子对象添加和使用ClassWizard来生成这些对象的控制变量,DDX的地图在父窗口的cpp文件的DoDataExchange方法(在这种情况下MyDlgBar.cpp)并删除或注释掉这些对象的DDX指令条目。据我所知,这是不是在大多数情况下的问题。我相信它是一个独特的CBitmapButton的怪癖,当使用AUTOLOAD()。我没有验证了这一点,但有人建议,如果你使用CBitmapButton的::的,而不是AUTOLOAD()(..)LoadBitmaps运行时代码将不能断言,即使DDX启用无论如何,如果你有这些相同WinCore.cpp断言,在未来的子对象,你将有一个好主意,在哪里看的问题。感谢您了我的注意。我希望代码在您的项目以及服务。快乐编码...格
在企业中,如果两个人总是同意,其中之一是不必要的。
评论会员:wzh19831221 时间:2011/12/03
谢谢你的更新信息。我还发现,使用LoadBitmaps(而不是AUTOLOAD())无法断言,让我去这条路在我的代码。我没去尽可能学习,DDX指令AUTOLOAD(故障),这是一个很好的知识的一小部分保存供以后我看到这些断言。

再次感谢您的turorial真的帮了我。

〜本
评论会员:cyber_N 时间:2011/12/03
{S2}我有你所说的做
这是我
非常有帮助我已经学会如何以新的从CDialogBar派生类和
创建虚函数的使用()

你能告诉我的create()和OnCreate中的功能differece ()????

wzh
评论会员:andrewtruckle 时间:2011/12/03
can you tell me the differece of the function create() and oncreate()???? 

基本上,它是这样工作的:Create()方法被调用来创建一个Windows窗口。一旦创建窗口,但之前,它是可见的(即前的Create()方法返回的OnCreate()被调用。普遍认为它是这样的:所有建筑的Create(),反之,onCreate()方法的地方修改预构建的对象的属性我希望这会有所帮助。阅读MSDN - 这些方法是有据可查的格

& #160;
在企业中,如果两个人总是同意,其中之一是不必要的。

评论会员:andrewtruckle 时间:2011/12/03
感谢你答复 当我的代码"。自动加载的功能(......)""的OnCreate()"(重载虚函数的类的CWnd),programe出现错误
我想原因是CDialogBar的实例尚未创建

这是

我找不到原因,只是猜测;

希望您的重播

感谢{S2}

wzh
评论会员:andrewtruckle 时间:2011/12/03
爵士
请仔细阅读的文章... ...特别是一节添加一个所有者绘制的CBitmapButton的。它说明了整个过程一步一步。首先,你绝不会重写基类(即CWnd的),你会重写。AUTOLOAD()函数在重写创建属于CMyButton或CMyDialogBar等二,在您的实际类的功能,如, ()函数的CMyDialogBar类 - 的OnCreate()函数,它必须CMyDialogBar方法,不是它的基类CDialogBar或CDialog甚至CWnd的试想一下:当您添加m_myDialogBar.Create (....) MainFrm类,该行调用您的派生对话栏类的Create()方法。我们是压倒一切的,所以我们可以自定义创建的对话栏的,这是非常方法。由于我们的子类的按钮和CBitmapButtons OWNERDRAWN按钮,我们来创建它们。这项工作必须在DialogBar创建的时间。如果等到CMyDialogBar:在OnCreate()被称为对话栏将已经被创建,只是不可见的。 ,在这个阶段,你不能做任何施工,你只能做修改 - 你可以改变背景颜色,或隐藏/显示"按钮,但所有子对象都必须在父母施工过程中建造。请记住,使用Create()当你正在创造的东西,使用的OnCreate(),如果你只修改现有对象的属性。如果你有更多的问题,请阅读的文章,它解释了一切步骤一步。另外,看演示源 - 这是它的存在 - 告诉你这样做是正确的途径。
在企业中,如果两个人总是同意,其中之一是不必要的。