当德尔菲(2006)变成量子的时候:我有一个“东西”,它看上去是TToolBar和TPanel,这取决于你是如何观察它的。我想了解这是怎么回事。
下面是如何创建它以及发生了什么:
- add a TToolBar named bar;
- in that TToolBar, put a TPanel.
- the panel appears in the list of buttons bar.Buttons[], let's say at index i
- bar.Buttons[i], from the compiler point of view, is a TToolButton
- bar.Buttons[i].ClassName = 'TPanel'
- (bar.Buttons[i] is TToolButton) = true, but that's the compiler optimising the call to 'is' out;
- indeed IsBarButton(bar.Buttons[i]) is false for function IsBarButton (defined below);
- bar.Buttons[i].Name is the name I gave the TPanel in the DFM
- inspecting the value bar.Buttons[i] in the debugging:
- it has a property 'Caption' the real TToolButton's don't have
- strangely, it has all properties TToolButton's have, like TToolButton.Indeterminate (=true).
IsToolButton:
function IsToolButton(X : TObject) : boolean;
begin
Result := X is TToolButton;
end;所以bar.Buttonsi既是和不是TToolButton.怎么了?
(说到底,我想把我的TPanel和真正的TToolButton区别开来,我可以或多或少地用一些讨厌的方式来做。我在这里问这个问题的目的是更充分地了解这里到底发生了什么。)
问:发生了什么事?子问题:将TPanel添加到TToolBar中是否合法?
发布于 2010-06-21 14:10:48
操作系统允许添加到工具栏的唯一东西是工具按钮。要添加任何其他内容,技术上您需要创建一个按钮,然后将您的其他东西放在上面。添加的按钮实际上是占位符。它是用来占用空间的,所以下一个你添加的东西会被正确的定位。
如果添加的非工具按钮控件是透明的,有时您可以看到这一点。然后,您可以看到工具栏的分隔符在下面,因此它看起来有一条垂直线运行在您的控制中心。
将非工具按钮控件添加到工具栏时,Buttons属性实际上取决于控件的类型。在整个ComCtrls.pas中,您会注意到TToolBar本身总是将按钮抛给TControl,然后检查它们是否真的来自TToolButton。将非按钮添加到工具栏是完全合法的;这就是表单设计器首先允许它的原因。
我建议您使用表单设计器来创建工具栏。这样,IDE将在表单中为您维护一个标识符,因此您将始终直接引用您的面板。你不用去工具栏里找它。即使您是手动创建工具栏,创建一个额外的字段来引用面板也是个好主意。即使您在工具栏内移动面板,它也将始终是相同的对象,因此不必担心挂起引用。
发布于 2010-06-21 10:37:41
当您在工具栏上放置几个按钮和一个面板以及某个地方的备忘录时,请在表单的onCreate中运行以下代码:
procedure TForm1.FormCreate(Sender: TObject);
function _IsToolButton(const aObject: TObject): Boolean;
begin
Result := aObject is TToolButton;
end;
function _IsPanel(const aObject: TObject): Boolean;
begin
Result := aObject is TPanel;
end;
var
i: Integer;
begin
for i := 0 to bar.ButtonCount - 1 do begin
Memo.Lines.Add(Format('bar.Buttons[%d].Name: %s', [i, bar.Buttons[i].Name]));
Memo.Lines.Add(Format('bar.Buttons[%d].ClassName: %s', [i, bar.Buttons[i].ClassName]));
Memo.Lines.Add(Format('bar.Buttons[%d] is TToolButton: %s', [i, BoolToStr(_IsToolButton(bar.Buttons[i]), True)]));
Memo.Lines.Add(Format('bar.Buttons[%d] is TPanel: %s', [i, BoolToStr(_IsPanel(bar.Buttons[i]), True)]));
// Memo.Lines.Add(Format('bar.Buttons[%d] has Caption property: %s', [i, 'dunno yet']));
Memo.Lines.Add('');
end;
end;您将看到面板不是一个TooButton,而且肯定不是一个TPanel。
显示面板的ToolButton属性的调试器就是调试器将每个bar.Buttonsi转换为TToolButton。当您右键单击Debug检查器的"Data“选项卡时,您可以将其类型转换为TPanel,您将得到正确的信息。
发布于 2010-06-21 11:57:00
“这是合法的吗?”--嗯,你肯定是在使用工具栏,而工具栏的创建者并没有允许它被使用。它会在你脸上爆炸吗?谁知道呢。我想您可以遍历工具栏的源代码并检查它是否安全,但是可能的第三方工具或组件呢,希望在工具栏中找到按钮?
我想看看能不能找到别的办法解决我的问题。聪明的黑客总有一种不那么聪明的倾向,这肯定会增加代码的wtf-费率。
你必须使用工具栏吗?用按钮和面板代替的流动面板怎么样?还是带有工具栏和面板的面板?
https://stackoverflow.com/questions/3083657
复制相似问题