max*_*fax 1 delphi treeview height
我有一个树视图作为主菜单.程序启动后,我添加新的子项.
然后我做 TreeView1.Perform(TVM_SETITEMHEIGHT, 28, 0);
在设计时我将Form的Position属性设置为poDesigned.为什么TreeView1.Perform Position在运行时没有工作?
请查看此问题的视频:http://liga-installer.realservers.info/tv.mp4
这是我的代码:
procedure TForm1.FormCreate(Sender: TObject);
begin
TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Sub Menu1');
TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Sub Menu2');
TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Sub Menu3');
TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Sub Menu4');
TreeView1.Perform(TVM_SETITEMHEIGHT, 28, 0);
Position:=poScreenCenter;
end;
Run Code Online (Sandbox Code Playgroud)
NGLN的答案给出了问题的解释.
如果您只需要设置Position(或任何其他属性,将导致窗口(在技术意义上)重新创建)同时您设置树视图项的高度,您可以做
procedure TForm1.FormCreate(Sender: TObject);
begin
Position := poDesigned;
TreeView1.HandleNeeded;
TreeView1.Perform(TVM_SETITEMHEIGHT, 28, 0);
end;
Run Code Online (Sandbox Code Playgroud)
问题在于,设置窗体的Position属性会导致调用RecreateWnd。RecreateWnd意味着销毁Windows屏幕对象并从头开始构建它。似乎需要(或最简单的方法)来完全实现更改此属性的所有效果。窗口句柄的创建并不少见:例如,更改窗体的BorderStyle甚至是Edit控件的BorderStyle都会导致调用RecreateWnd。
RecreateWnd级联为重新创建所有子窗口控件,也就是您的TreeView。通常,组件从其内部(属性,私有数据)知道如何重新创建自身。例如:TreeView在句柄销毁之前将其节点保存到临时内存流,并在句柄重新创建后将其重新加载。
那么,谁应该负责:Form的Position属性,TreeView或两者都不是?如果没有TreeView的ItemHeight属性,则必须手动发送WinAPI消息。这是对未由VCL注册的控件的修改。到目前为止,解释了为什么会发生这种情况。
最好的解决方案是确保每次重新创建TreeView时都完成自定义。不幸的是,没有活动可用。您将需要覆盖CreateWnd(请参见下面的更新)。但是,当您保留Ctl3D和BorderStyle属性不变时,也可以在父级上控制它。我不得不重写CM_ShowingChanged,因为不幸的是,TreeView在TForm1.CreateWnd之后还没有完全重建:
TForm1 = class(TForm)
TreeView1: TTreeView;
...
private
procedure CMShowingChanged(var Message: TMessage);
message CM_SHOWINGCHANGED;
end;
procedure TForm1.CMShowingChanged(var Message: TMessage);
begin
inherited;
TreeView1.Perform(TVM_SETITEMHEIGHT, 28, 0);
end;
Run Code Online (Sandbox Code Playgroud)
根据以下注释的要求,这是使用重写的TTreeView.CreateWnd的解决方案:
unit Unit1;
interface
uses
Windows, Classes, Controls, Forms, StdCtrls, ComCtrls, CommCtrl, XPMan;
type
TTreeView = class(ComCtrls.TTreeView)
protected
procedure CreateWnd; override;
end;
TForm1 = class(TForm)
TreeView1: TTreeView;
XPManifest1: TXPManifest;
procedure FormCreate(Sender: TObject);
end;
implementation
{$R *.dfm}
{ TTreeView }
procedure TTreeView.CreateWnd;
begin
inherited CreateWnd;
Perform(TVM_SETITEMHEIGHT, 38, 0);
end;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Sub Menu1');
TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Sub Menu2');
TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Sub Menu3');
TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Sub Menu4');
Position := poScreenCenter;
end;
end.
Run Code Online (Sandbox Code Playgroud)
而且,如果您不想继承TTreeView的子类,请重写该窗体的CreateWnd,但是在这种情况下,您需要调用Andreas Rejbrand回答的HandleNeeded:
unit Unit1;
interface
uses
Windows, Classes, Controls, Forms, StdCtrls, ComCtrls, CommCtrl, XPMan;
type
TForm1 = class(TForm)
TreeView1: TTreeView;
XPManifest1: TXPManifest;
procedure FormCreate(Sender: TObject);
protected
procedure CreateWnd; override;
end;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Sub Menu1');
TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Sub Menu2');
TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Sub Menu3');
TreeView1.Items.AddChild(TreeView1.Items.Item[0],'Sub Menu4');
Position := poScreenCenter;
end;
procedure TForm1.CreateWnd;
begin
inherited CreateWnd;
TreeView1.HandleNeeded;
TreeView1.Perform(TVM_SETITEMHEIGHT, 38, 0);
end;
end.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2167 次 |
| 最近记录: |