自定义可视控件

由于本软件为音乐软件,需要大量绘图,现有的基于DC的API及BCB的画布均不能完成要求(速度慢,绘制特定图案困难),为了节省时间,派生了现有的T
WinControl可视窗口控件,组合特定的绘图类,形成一个新的类,图案绘制在可视区域,重载控件的鼠标及键盘事件处理,形成标准的控制,这一切都实现了
,但结果失败了,原因是自绘图完成后,系统刷新了一下控件,结果悲催了,改变窗体尺寸也要刷下一,可视窗口控件这一动作是正常的,问题是系统不认我
的自绘图。解决问题的办法是系统刷后再绘,那么就截获WM_SIZE消息,结果又悲催了,在响应WM_SIZE消息时,自绘图类崩溃,原因是控件WM_SIZE建立先于自
绘图类,自绘图类还没建立,调用成员必然崩溃。解决方法是设一标志,控件建立后,再响应WM_SIZE消息的自绘图,结果怎么改变也不刷新,原因是系统创建
可视窗口组件时,只发一次WM_SIZE。既然WM_SIZE不连续发,那么换一个WM_PAINT"窗口重绘"消息,结果再次悲催,是能够自绘图了,但其他消息不再响应。
通过计数发现WM_PAINT快速猛烈刷新,造成其他消息来不及反映。根据WM_PAINT定义,是不会这样的,所以将派生向上退一级到TControl,结果正常拉。经过一
波三折的折腾,避免了更复杂的完全自定义可视控件。回顾解决问题的思路是这样的:为了节省时间,继承利用现有可视控件,在上面进行自定义绘图,自定义
绘图是自己做的,内存级绘图,中间级少,所以比较快,并且图案内置。使用控件做图元,是为了响应各种事件。在继承派生控件时出了问题,TWinControl和
TControl的关系是TControl是所有可视控件的祖先,TWinControl从TControl派生,加入了句柄,成为可视窗口控件的祖先。TControl是最原始的可视控件,拥有
最早传入的相关消息,比如WM_SIZE,WM_PAINT,与系统定义相近。至此拥有快速高效可任意操作绘制的控件,虽然不具备窗口能力,但以绘图为主要目的是没问
题的。为了方便,以后称这种控件为“图元”,是每一个图形操作的最基本单位。一个界面有很多图形组成,他们各自有一套反映机制,相互呼应相互制约,完
成人机交互。

TControl控件:作为可视控件的祖先类,增加了Top,Left,Width,Height等相关“尺寸”概念及反映“视觉”的WM_SIZE,WM_PAINT消息能力,供后代派生继承,
后代只要“画自己”出来就行了。有些可视控件“画自己”的工作可交出来,称为“自绘”,但必须是系统自己的绘图函数。很多好看的界面就是“自绘”的结
果。TControl是没有“相貌”的,为的是后代有各种“相貌”。TControl除没有“相貌”,但拥有各种支持“相貌”的最基础能力。

TWinControl控件:从TControl派生,拥有TControl的一切能力,主要加入了相关Windows“句柄”概念,一旦有了“句柄”就可与“窗口”挂钩,也就是有了“
窗口”能力,“窗口”和“句柄”在Windows程序设计中,是很重要的概念,拥有窗口句柄几乎可以做任何操作窗口的事情。TWinControl就是含有Windows窗口
句柄的,可视控件祖先类。

以下就是这个控件类,也叫矩形图元(刚解决了问题,仅仅是大概)

class TRectang : public TControl
{
public:

bool bEnable,//控件允许
bVisible,//控件显示允许
bVisibleFrame,//显示边框线
bVisibleText,//显示文本
bRightBorderEnable,//右边框移动允许
bMouseMoveInChangeEnable;//鼠标移入改变

DWORD dwFillColor,//控件(填充)颜色
dwLineColor,//框线颜色
dwTextColor,//文本颜色
dwHotFillColor,//热点控件(填充)颜色
dwHotLineColor,//热点框线颜色
dwHotTextColor;//热点文本颜色

int iFontSize,//字体大小
iAlignment;//文本对齐标志

String sText;//矩形内文本

__fastcall virtual TRectang(TComponent* AOwner);

void __fastcall Connect(TWinControl *pParent);//初始关联
void __fastcall AdjResize(int iLeft, int iTop, int iWidth, int iHeight);//矩形控件尺寸调整

protected:

DYNAMIC void __fastcall MouseDown(TMouseButton Button, Classes::TShiftState Shift, int X, int Y);
DYNAMIC void __fastcall MouseUp(TMouseButton Button, Classes::TShiftState Shift, int X, int Y);
DYNAMIC void __fastcall MouseMove(Classes::TShiftState Shift, int X, int Y);
DYNAMIC void __fastcall Click(void);
DYNAMIC void __fastcall DblClick(void);

private:

TDraw Draw;//绘图

//int iMouseXPos,//鼠标X位置
// iMouseYPos;//鼠标Y位置

void __fastcall SelfDraw(void);//自绘
void __fastcall OnMouseLeave(TMessage &Msg);//鼠标离开处理
void __fastcall OnPaint(TMessage &Msg);

BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, OnMouseLeave);//鼠标离开挂钩
MESSAGE_HANDLER(WM_PAINT, TMessage, OnPaint);//窗口重绘挂钩
END_MESSAGE_MAP(TControl)

};

时间: 2024-10-04 06:55:39

自定义可视控件的相关文章

Android自定义控件之自定义组合控件(三)

前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发成本,以及维护成本. 使用自定义组合控件的好处? 我们在项目开发中经常会遇见很多相似或者相同的布局,比如APP的标题栏,我们从三种方式实现标题栏来对比自定义组件带来的好处,毕竟好的东西还是以提高开发效率,降低开发成本为导向的. 1.)第一种方式:直接在每个xml布局中写相同的标题栏布局代码 <?xm

自定义组合控件和在自定义控件中使用自定义属性

今天,整理了一下我平时的笔记,写一个比较简单的自定义组合控件,仅供小白参考,大神请绕道,希望能够对大家有一些帮助 首先,得明白为什么我们需要自定义组合控件,它是因为原有控件并不能满足开发的需求,或者说并不能达到我们想要的一种效果,这个时候,就需要我们自己定义一些控件,以达到目的 ![先来看一下效果](http://img.blog.csdn.net/20160716224219109) 个人总结自定义控件的步骤: 1.先写一个布局,这里我用的是一个相对布局,我这里的相对布局就是根布局了 <?xm

自定义HtmlHelper控件

在asp.net mvc 中每一个Html控件都返回了MvcHtmlString ,他继承了HtmlString.下面自定义一个关于显示男女性别的自定义Html控件,使在创建页面时,可以直接调用该自定义的Html控件.可以查看其他的Html控件返回的是HtmlHelper,所以自定义的时候也要返回相同的类型直接在Controls文件夹下建立要自定义的html控件代码如下: using System.Web.Mvc; using System.Text; namespace System.Web.

【转】带checkbox的ListView实现(二)——自定义Checkable控件的实现方法

原文网址:http://blog.csdn.net/harvic880925/article/details/40475367 前言:前一篇文章给大家展示了传统的Listview的写法,但有的时候我们并不想在DataHolder类中加一个标识是否选中的checked的成员变量,因为在项目开发中,大部分的ListItemLayout布局都是大家共用的,有些人根本不需要checkbox控件,所以会在初始化的时候把这个控件给隐藏掉,但我们的DataHolder在构造的时候以及ListItemAdapt

Android自定义组合控件--底部多按钮切换

效果图: 现在市场上大多数软件都是类似于上面的结构,底部有几个按钮用于切换到不同的界面.基于OOP思想,我想把下面的一整块布局封装成一个类,也就是我们的自定义组合控件-底部多按钮切换布局,我把它叫做BottomLayout 看上面的布局,几个按钮横向排列,我们先看一下布局 最外面LinearLayout 方向 horizontal,然后5个weight相同的RelativeLayout,每个RelativeLayout里面有一个Button(用了显示选中状态)个ImageView(用来显示红点)

Android_自定义切换控件SwitchView

今天做了一下老师给的第一套题,第一题是判断一个字符串是否在另一个字符串中:做了一下,感觉有好多种写法,java中的类真的好多啊,要掌握好一些基本类的用法: package com.exam.e120; public class java1 { public static void main(String[]args){ String str1,str2; str1="I am Tom, I am from China."; str2="Tom"; int i=str

C#自定义工业控件开发

转自阿凡卢原文C#自定义工业控件开发 由于工作需要,调研过一段时间的工业控制方面的"组态软件"(SCADA)的开发,组态软件常用于自动化工业控制领域,其中包括实时数据采集.数据储存.设备控制和数据展现等功能.其中工控组件的界面展现的实现类似于Windows系统下的各种开发控件,通过各种控件的组装,和硬件协议的集成,就可以实现对相应设备的控制和实时状态的显示. 每个对应的硬件UI展示都可以用一个自定义控件来实现,如下图的一个温度计,就可以使用UserControl来实现. using S

iOS边练边学--(Quartz2D)基本图形的绘制#附加自定义进度控件的练习

一.Quartz2D使用须知 Quartz2D的API是纯C语言的 Quartz2D的API来自于Core Graphics框架 二.<1>通过原始的方法(C语言)绘制简单图形--了解 <2>OC也封装了绘制图形的框架UIKit(贝瑟尔路径)--掌握 三.自定义进度控件的练习,效果图

自定义View控件(2—手写实例代码)

1. 步骤: + 1.自定义一个类继承于UIView + 2.在initWithFrame方法中添加子控件 + 3.在layoutSubviews中设置子控件的位置 + 4.提供一个属性保存外界传入的数据(模型对象), 重写setter方法设置子控件的数据 - 类工厂方法(便利构造器) + 按照苹果的风格和规范, 一般情况一个用于创建对象的对象方法会对应一个类方法 + 可以通过类工厂方法, 快速的根据数据创建一个对象 - 注意点: + 返回值一定要使用instancetype, 不要使用id +