自定义可视控件

由于本软件为音乐软件,需要大量绘图,现有的基于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)

};

posted @ 2016-02-18 18:14  hbg200  阅读(272)  评论(0编辑  收藏  举报