• 一个托管的c++按钮控件


    如果你喜欢这篇文章,请为它投票。如果你不喜欢这篇文章,请投票,并告诉我你为什么不喜欢它。 介绍 我开始这个项目是为了了解如何开发一个在质量上类似于标准。net按钮控件的管理自定义控件。像大多数。net初学者一样,我从UserControl类开始继承,但很快就了解到我想实现的一些概念有很大的局限性。 在对谷歌和MSDN文档进行了大量的搜索之后,我决定开发一个继承自ButtonBase和IButtonControl的按钮控件。继承ButtonBase的一个问题是这个类是抽象的。这意味着不能在设计器中直接获取按钮控件。但是,可以将它添加到工具箱中,并且它在表单设计器中工作得非常好。 该控制是为灵活性而设计的。它允许圆角或正方形控件。此外,您可以指定哪些角是圆角,哪些角是正方形。您还可以更改角的半径。我使许多颜色可配置。我还包括了为悬停和普通颜色绘制渐变的能力。我实现了标准。net按钮控件可以响应的大多数事件。通过实现IButtonControl接口,还公开了几个标准的按钮行为。 背景 有很多。net自定义控件上传到CodeProject。我们为什么需要另一个?部分原因是因为我是一个c++程序员。我想知道将我的WTL和ATL技能转移到。net需要什么。我想了解在WTL中设计一个控件和在VB中设计一个控件之间的区别。净或c#。我大量使用属性来描述属性和分配默认值。我还添加了XML文档标签,这样当在表单中使用控件时,Intellisense就会很有意义。 我基于WiB和Alan Zhao的工作建立了这个控制模型。他们的两篇文章都提供了大量的灵感和教育。 编译和使用源代码 下载并解压缩演示项目。请确保保留源文件的目录结构。 第一次加载解决方案时,可能会看到许多关于缺少引用的消息。这是因为该程序集尚未在您的机器上构建。(我没有在源分发版中包含任何二进制文件,因此缺少引用。)只需选择发布或调试模式,然后重新编译。将构建程序集,并验证所有引用。此时,可以通过将程序集拖动到工具箱表面或从上下文菜单中选择“add Item…”并导航到根目录dir> mehControls
    elease并选择mehButton.dll将控件添加到工具箱中。 使用组件 将控件添加到工具箱后,可以将其拖动到任何窗体。我实现了一个设计器组件,因此所有属性都正确地显示在“properties”视图中。您会注意到,我在设计器的PostFilterProperties方法中删除了一些最难实现的属性。其他属性,比如“平面”属性,是多余的。编程mehControl是相当标准的。下面的代码说明了表单设计器向导是如何在c#项目中初始化控件的: 隐藏,收缩,复制Code

    //
    // mehButton1
    //
    this.mehButton1.BackColor = System.Drawing.SystemColors.Control;
    this.mehButton1.ButtonStyle = mehControls.mehButton.ButtonStyles.Rectangle;
    this.mehButton1.CurveMode = mehControls.mehButton.CornerCurveStyle.None;
    this.mehButton1.DialogResult = System.Windows.Forms.DialogResult.None;
    this.mehButton1.GradientStyle = mehControls.mehButton.GradientStyles.None;
    this.mehButton1.HoverBorderColor = System.Drawing.SystemColors.ControlDark;
    this.mehButton1.HoverColorA = System.Drawing.SystemColors.ButtonFace;
    this.mehButton1.HoverColorB = System.Drawing.SystemColors.ButtonHighlight;
    this.mehButton1.Image = null;
    this.mehButton1.Location = new System.Drawing.Point(12, 122);
    this.mehButton1.Name = "mehButton1";
    this.mehButton1.NormalBorderColor = System.Drawing.SystemColors.WindowFrame;
    this.mehButton1.NormalColorA = System.Drawing.SystemColors.ButtonHighlight;
    this.mehButton1.NormalColorB = System.Drawing.SystemColors.ButtonFace;
    this.mehButton1.Radius = 0;
    this.mehButton1.Size = new System.Drawing.Size(127, 38);
    this.mehButton1.SmoothingQuality = mehControls.mehButton.SmoothingQualities.AntiAlias;
    this.mehButton1.TabIndex = 4;
    this.mehButton1.Text = "m&ehButton Flat";
    this.mehButton1.UseVisualStyleBackColor = false;
    this.mehButton1.MouseLeave += new System.EventHandler(this.mehButton1_MouseLeave);
    
    ...
    
    // The control's events are implmented in a standard fashion.
    // The C# design wizard is able to auto-fill the events
    // properly from the "Properties" sheet.
    private void mehButton1_MouseLeave(object sender, EventArgs e)
    {
        this.lblEventText.Text = "Mouse has left mehButton1";
    }

    实现一个设计师 当您为。net开发自定义可视化控件时,您将需要实现一个设计器。设计器可以很简单(就像我实现的那样),也可以很复杂。下面的代码说明了最小设计器的定义: 隐藏,复制Code

    namespace mehControls
    {
        ref class mehButtonDesigner : 
            public System::Windows::Forms::Design::ControlDesigner
        {
        public:
            mehButtonDesigner(void)
            {
            };
    
            ~mehButtonDesigner(void)
            {
            };
    
        protected:
            virtual void PostFilterProperties(IDictionary ^) override;
            virtual void OnPaintAdornments(PaintEventArgs ^e) override;
    
        };
    }

    将属性 您需要正确地设置属性。这将允许您控制属性在属性显示中的分组位置以及属性的默认值。 隐藏,复制Code

    [DefaultValue(System::Drawing::Color::typeid, "System::Drawing::SystemColors::Control")]
    [Description("Background Color for button"), Category("Appearance")]
    // This is how you split a property definition
    // This is useful if the property has many lines of
    // code or you do not want to expose the
    // inner workings of your code in the header.
    property virtual Color BackColor
    {
        // The property function prototypes are specified here
        Color get() override;
        void set(Color value) override;
    }

    处理控件的OnPaint事件 与本机模式编程一样,大多数工作是在控件的OnPaint(或OnPaintBackground)事件中处理的。在控件的情况下,DrawRoundRectangle完成了大部分繁重的工作。为了实现圆角,我大量使用了gp->AddArc(arc, angle1, angle2),其中GraphicsPath ^gp = gcnew GraphicsPath()。 总结 该按钮实现了。net 2.0按钮的许多属性。弄清楚如何添加“热”边界的绘画是一件很有趣的事情。在画圆角的时候,我必须使用我十年级的几何知识来计算出正确的圆角中心。这是我用于开发圆角算法的基本图: 我也能够实现背景的渐变绘制,当鼠标在按钮上或点击事件时,允许一些非常酷的效果。下面的枚举说明了i的梯度类型mplemented: 隐藏,复制Code

    enum class GradientStyles
    {
        None,
        Horizontal,
        Vertical,
        ForwardDiagonal,
        BackwardDiagonal
    };

    控制还远远没有完成。我已经为所有属性添加了属性。但是,使用XML文档标记还有很多工作要做。我还没有在这个版本的控件中实现主题。 你应该知道的事情 我发现在管理模式和混合模式的c++中,有一些项要容易得多。首先,您不必担心导入API调用。您可以包含来自平台SDK的任何头文件,Visual c++将为您处理调用。这是一个巨大的帮助,可以在处理API调用时节省大量时间。在托管的c++项目中,在wchar_t和String之间来回移动要简单得多。 VS 2005没有像c#那样的漂亮的c++向导。当您选择一个Windows控件项目时,就会得到这样的结果。没有设计师。没有铃铛和哨子。在早期,您必须经常查阅文档。然而,我发现我通过艰苦的方式学习了很多关于我的环境的东西。在我知道之前,我并没有经常查阅文档。 在c++和c#之间,向项目添加引用是不同的。您可以使用项目属性页添加引用。只需导航到通用属性,然后单击添加新引用…按钮。 指定名称空间和解析引用的名称:在托管c++中,解析名称时使用"::"而不是"."。 隐藏,复制Code

    // You'll use this syntax in managed C++
    using namespace System::Windows::Forms;
    // Instead of the C# syntax
    //using System.Windows.Forms;

    历史 版本1.0—2008年4月11日—控件的初始版本。 本文转载于:http://www.diyabc.com/frontweb/news458.html

  • 相关阅读:
    推销
    5132. 颜色交替的最短路径
    5130. 等价多米诺骨牌对的数量
    @babel/plugin-transform-runtime和@babel/preset-env的区别
    5128. 最深叶节点的最近公共祖先(二叉树)
    1094. 拼车
    1109. 航班预订统计(数组)
    5129. 表现良好的最长时间段(数组)
    path.resove 和 path.join
    【原生】 call、apply、bind 的基本使用方法,已经解析了某些源码
  • 原文地址:https://www.cnblogs.com/Dincat/p/13450161.html
Copyright © 2020-2023  润新知