多行控件面板

I

import

Unregistered / Unconfirmed
GUEST, unregistred user!
Delphi6 的多行Component Palette实现  
  不久前,Borland公司出品的最新的Delphi 6,我也下载了一个Delphi 6练练手,虽然有很多令人兴奋的改进(比如XML和网络Indy控件就是经典),但最为让人恼火的是Delphi的VCL控件体系不是很兼容,我以前在Delphi 5里面用的习惯的一些插件(Experts)和控件大部分无法正确安装,这是一个让人恼火的事情,尤其对于一个喜欢在Delphi里面安装一些第三方产品的人,比如大名鼎鼎的GExperts (http://www.gexperts.org/)。
  GExperts是一个免费的Delphi增强工具,有相当多的功能,其中之一就是Component Palette - 控件面板的多行显示,好像下图显示的那样。我是一个爱玩新鲜的人,或者说我不是很安分,我的Delphi会安装相当多的第三方控件,有时候找起来就很费时间,像下图这样显示多行控件面板,找起来就比较方便。有很多插件提供了如下的多行显示控件面板功能,比如BUPack、CodeRush等等。这些著名的产品都包含有这样的功能,可惜的是现在都没有Delphi 6的版本,我们怎么自己实现该功能呢?
 
 
  做为一个程序员当然会选择自己开发,老是等待他人的恩惠那是多么没有面子的事情。幸运的是,GExperts是一个免费提供源代码的产品,我下载了源代码并进行了相应功能的分析,也分析了一些其他人的实现方法,发现原理非常简单,想知道的话,先看我下面提炼的做了最简单化的源代码。
unit MultiLinePaletteExpert;
interface
uses
Forms, Controls, ComCtrls;
implementation
type
TMultiLinePalette = class
public
procedure ResizeComponentPalette(Sender : TObject);
end;
var
MultiLinePalette : TMultiLinePalette;
procedure TMultiLinePalette.ResizeComponentPalette(Sender : TObject);
var
AHeight : integer;
begin
with (Sender as TTabControl) do begin
AHeight := Height + DisplayRect.Top - DisplayRect.Bottom + 29;
Constraints.MinHeight := AHeight;
Parent.Constraints.MaxHeight := AHeight;
end;
end; {ResizeMultiLineComponentPalette}
procedure SetMultiLineComponentPalette(MultiLine : boolean);
var
AppBuilder : TForm;
TabControl : TTabControl;
begin
AppBuilder := TForm(Application.FindComponent('AppBuilder'));
if (AppBuilder <> nil) then begin
TabControl := TTabControl(AppBuilder.FindComponent('TabControl'));
if (TabControl <> nil) then begin
TabControl.MultiLine := MultiLine;
if MultiLine then
TabControl.OnResize := MultiLinePalette.ResizeComponentPalette
else
TabControl.OnResize := nil;
end;
end;
end; {SetMultiLineComponentPalette}
initialization
MultiLinePalette := TMultiLinePalette.Create;
SetMultiLineComponentPalette(true);
finalization
SetMultiLineComponentPalette(false);
MultiLinePalette.Free;
end.
  这个Unit文件定义了一个TMultiLinePalette类,其实这个类没有什么别的目的,仅仅是定义一个ResizeComponentPalette方法实例,动态赋值给ComponentPalette类的OnResize方法,这里提一句,动态方法赋值是Delphi程序员常用的一个技巧,一个事件对应多个方法,实时配置。其实,我们的代码关键是找到Component Palette的类实例。
  左边的窗口是我写的截取Delphi6的主窗口的所有Component的Name列表,通过使用的是Components[].Name属性获得。Delphi有几个主要的窗口类,左边的是Object Inspector和Object TreeView 窗口,我们的代码编辑窗口和窗体设计窗口,以及最上面的主操作窗口,我们关心的就是它了,因为它包含了Component Palette窗口类,注意,这里的窗口指的是从TWinControl继承下来的含有Handle属性的类,不仅仅是TForm类的子类,这个概念Delphi程序员经常混淆。
  获得该列表的作用是为了获取到Delphi6的主操作窗口的所有Component类的名称,可以告诉你的是,AppBuilder就是这个主操作窗口TForm类的名字,代码
TForm(Application.FindComponent('AppBuilder'));
就是找到主窗口类AppBuilder并赋值给一个TForm对象,这是多态的应用,各位朋友应该不会陌生吧。右边的截图是AppBuilder Form所包含的Components[].Name列表,因为它的子窗口类非常的多,这里只是给出了前面的20个子类,没有关系,我们已经看到第二个Name是TabControl,没错,就是它了,
TabControl := TTabControl(AppBuilder.FindComponent('TabControl'));
写完这行代码就几乎大功告成了,因为我们已经找到控件面板的类实例了。不用怀疑,我们的TabControl变量就是Delphi 6主窗口的控件面板的类实例强制转换为了TTabControl类型的值,最为父类,TTabControl有MultiLine属性,我们按照需要进行设置,OK,搞定!
  这段Unit需要安装,不要嫌我罗嗦,我见过很多Delphi程序员,面对此类代码不知所措,我简单介绍一下安装过程,新建一个Unit,将上面的代码全部拷贝进去,保存为MultiLinePaletteExpert.pas文件,新建一个Package,Add刚刚保存的MultiLinePaletteExpert.pas文件,编译、安装。想卸载该Package,在Delphi菜单项选择Component/Install Pacgage,找到我们的bpl,remove它就可以了,简单吧!另外,如果你还有任何问题,欢迎你联系我dragonpc@21cn.com ,欢迎一起来了解Delphi的奥妙。
Dragon P.C. - DDaa - Bruce Luo
 
 
 
 
 
 
 
作者会员名:dragonpc
 
 
顶部