在 Delphi 2009 中,在我的一个项目中,我有一个自定义框架,上面有一些控件,我想将其用作其他一些控件的基类。我想将此框架注册为 IDE 向导,以便在新项目列表中可用。当我将新添加的项目(我的自定义框架)添加到项目中时,我希望它:
好的,为了让它在对象检查器中显示我的属性和事件,我在 IDE 中注册了一个自定义模块。它不适用于框架。幸运的是,StackOverflow 上有人提到了这一点,并给出了答案:
然后,为了使其加载自定义框架的 DFM,我将 InitInheritedComponent 添加到自定义框架的构造函数中。像这样的东西:
constructor TMyFrame.Create(AOwner: TComponent); override;
begin
inerited;
if (ClassType <> TMyFrame) and not (csDesignInstance in ComponentState) then
begin
if not InitInheritedComponent(Self, TMyFrame) then
raise EResNotFound.CreateFmt('Resource %s not found', [ClassName]);
end;
end;
Run Code Online (Sandbox Code Playgroud)
这不起作用!它仍然在设计器中创建一个空框架而不是我自己的框架。如果我没有将自定义模块注册到 IDE 中,即使不需要 InitInheritedComponent,它也会正确显示我的框架,但对象检查器中不会显示其他属性!
如果我将构造函数源更改为此(用 TFrame 替换 TMyFrame):
constructor TMyFrame.Create(AOwner: TComponent); override;
begin
inerited;
if (ClassType <> TFrame) and not (csDesignInstance in ComponentState) then
begin
if not …Run Code Online (Sandbox Code Playgroud) 另一个来自我的TFrame IDE注册组件问题.感谢所有帮助,其他程序员.:)
在这里玩弄Darrian的TFrame继承建议:
具体细节:
基本上,我有一个基于TFrame的组件,我已经注册到IDE,它工作得非常好.我现在正在开发一些"姐妹"组件,它们将共享大量现有组件的非可视功能和属性.因此,有意义的是将大量的内容移动到父类/超类,然后新组件和旧组件都可以从中继承.
以这种方式"重构"TFrame继承的最佳方法是什么?(这也可能适用于TForm级后代,不确定).有什么需要注意的注意事项和注意事项?
例:
我试过,例如,创建一个新的TFrame,没有任何内容,并调用该框架TMyBaseFrame.然后修改我现有组件的类定义(让我们称之为TMyFrameTreeView)继承而不是TFrame.
它编译得很好,但是当我尝试将其放在表单上时,我得到"ClientHeight not found"(或"找不到ClientHeight属性"),并且它不会丢弃在表单上.从相关的DFM中删除ClientHeight和ClientWidth会造成严重破坏,并且无论如何都会在调整大小时替换它们.我注意到了后代类中的ExplicitHeight和ExplicitWidth,并且我认为这与继承值的属性值覆盖相关,但我不确定.通过New - > Inherited Items重新创建一个全新的框架,然后将所有内容复制过来,也没有取得很好的效果.
最后的说明
我意识到这可能会很快变得混乱,包括流式DFM文件和多代后代等等......这也是我要求整体"注意事项"概念方面的一部分,同时也给出了具体的一部分.现实世界更简单的问题版本(在我看来,应该是可行的).
我已经创建了一个小小的测试软件包来学习尝试,并且我学到了很多东西,但是它很慢,而且德尔福"Jedi Masters"的任何指导/见解都会受到最多的赞赏.:)
稍后回答更新:
以下两个答案都很有帮助.同样,创建一个"基础框架类",它与普通的TFrame没有任何变化,然后在添加任何属性,方法等之前从中继承,这似乎可以极大地稳定继承流.不知道为什么,但到目前为止还有.
我正在使用一个TObjectList<TCustomFrame>商店TCustomFrames.现在我想TCustomFrame在同一个列表中存储更多有关的信息.一个record会很好.
德尔福类,你会更喜欢保存TCustomFrames,并records在同一个列表?
在TCustomFrames和records将在运行时添加.
有FRAME(不是表格)和线程.如何从线程中引用Frame的控件?例如,我想从线程中禁用一个按钮.但我没有指向按钮的指针,框架中没有全局变量.
谢谢!
WM_NOTIFY消息通常用于就地"工具提示"(消息气球)和其他控件通知,但如果我将控件放在TFrame上,那么这些控件就不会发生WM_NOTIFY消息.为什么不再将这些消息发送到我的表单,我该怎么办呢?
我正在使用C ++ Builder创建VCL表单应用程序。现在我有一个包含许多组件的TFrame,看起来像这样...

我也有一个按钮调用“添加”。基本上,每当我按下表单上的“添加”按钮时,都会向其中添加一个新的TFrame,并在前一个TFrame下方添加一个看起来像表格的东西。为了添加重复项,我必须在创建TFrame之前每次都对其重命名。
int __fastcall TForm1::AddMapCells(void)
{
Num++;
TFrame1 * MyFrame = new TFrame1(Form1);
MyFrame->Parent=Form1;
MyFrame->Name = "TFrame" + IntToStr(Num);
MyFrame->Top = 23*Num;
return Num;
}
Run Code Online (Sandbox Code Playgroud)
因此,TFrame的命名为TFrame1,TFrame2,TFrame3等。
现在的问题是我要制造它,因此每当我按下TFrame的“ X”按钮时,它都会删除该TFrame,并且我不确定该怎么做。我在想,也许每次创建TFrame时,我都可以重命名“ X”按钮,所以它就像Button1,Button2,Button3等。然后删除程序,只需将ButtonX与TFrameX匹配即可识别要删除的TFrame。例如,如果我按下按钮4,它应该与TFrame4匹配并删除TFrame4。
我不知道如何实现这个想法。还是会有更简单的方法来做到这一点?
我已经注册为组件TFrame的后代类,我注意到该Loaded过程执行了两次:
运行:
TMyFrame = class(TFrame)
private
protected
procedure Loaded(); override;
public
constructor Create(AOwner : TComponent); override;
end;
constructor TMyFrame.Create(AOwner : TComponent);
begin
ShowMessage('Before TMyFrame.Create');
inherited Create(AOwner);
ShowMessage('After TMyFrame.Create');
end;
procedure TMyFrame.Loaded();
begin
ShowMessage('Before TMyFrame.Loaded');
inherited;
ShowMessage('After TMyFrame.Loaded');
end;
Run Code Online (Sandbox Code Playgroud)
设计时:
procedure Register;
begin
RegisterComponents('Test', [TMyFrame]);
end;
Run Code Online (Sandbox Code Playgroud)
输出:
在运行时,创建一个有TMyFrame组件的表单.
在TMyFrame.Create之前
在TMyFrame.Loaded之前
在TMyFrame.Loaded之后
在TMyFrame.Create之后
在TMyFrame.Loaded之前
在TMyFrame.Loaded之后
在设计时,添加TMyFrame到表单:
在TMyFrame.Create之前
在TMyFrame.Loaded之前
在TMyFrame.Loaded之后
在TMyFrame.Create之后
在设计时,打开一个有TMyFrame组件的表单:
在TMyFrame.Create之前
在TMyFrame.Loaded之前
在TMyFrame.Loaded之后
在TMyFrame.Create之后
在TMyFrame.Loaded之前
在TMyFrame.Loaded之后
为什么Loaded程序执行两次?怎么避免这个?
我用tframe创建了一个dll.如何在我的应用程序中加载它,我不喜欢使用bpls,我只想用我的应用程序来分配exe和dll
我正在尝试在delphi包(bpl)中加载一个tframe,以便在我的主应用程序中显示,请为我提供包和应用程序的代码.
在Delphi 2010中......我有一个表格.表单的左侧是Treeview.它显示了一个多级层次结构.假设有5种不同类型的数据,类型A,B,C,D和E.在表单的右侧,我有一个面板,我将在其中创建一个TFrame.如果我在我的Treeview中单击"A"类型的数据元素,我会在表单的右侧创建一个显示tFrame"A"的TFrame.基本上我正在显示我的TreeView的各种层次结构的详细信息.5种类型的数据中的每一种都使用不同类型的TFrame.虽然我可以动态创建TFrames,但我很难知道WHERE以及如何删除/释放TFrames?
我是否创建了一个显示前一个TFrame的TYPE的变量?删除TFrame的正确方法是什么?是TFrame.Free吗?请记住,我可能需要创建框架A,自由框架A,创建框架B,自由框架B,创建框架A(再次)等等...
我试过了......
if Assigned (TFrameA), then TFrameA.free;
Run Code Online (Sandbox Code Playgroud)
虽然这似乎有效,但这会导致奇怪的行为(导致按钮消失).这也意味着我需要将所有5种类型的TFrame定义为全局变量.
任何和所有的想法都赞赏.
谢谢,
GS
我需要在运行时绘制Canvas框架,就像使用普通形式一样,但由于某种原因,他们决定不将Canvas属性添加到框架中,即使TCustomFrame和TCustomForm都来自处理Canvas的同一父类.
我已经通过覆盖PaintWindow过程来完成可以绘制内容的部分,但我似乎仍然无法在运行时使用Canvas属性,就像我错过了很大一部分代码一样.
这就是我现在所做的事情:
TCustomFrameEx = class(TCustomFrame)
private
FCanvas: TControlCanvas;
function GetCanvas: TCanvas;
public
property Canvas: TCanvas read GetCanvas;
end;
TFrame = class(TCustomFrameEx)
protected
procedure PaintWindow(DC: HDC); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy(); override;
published
...
end;
constructor TFrame.Create(AOwner: TComponent);
begin
inherited;
FCanvas := TControlCanvas.Create();
end;
destructor TFrame.Destroy();
begin
FreeAndNil(fCanvas);
inherited;
end;
function TCustomFrameEx.GetCanvas : TCanvas;
begin
Result := fCanvas;
end;
procedure TFrame.PaintWindow(DC: HDC);
begin
inherited;
FCanvas.Handle := DC;
FCanvas.Control := Self;
FCanvas.Brush.Color := clWhite;
fCanvas.FillRect(GetClientRect);
FCanvas.Handle := 0; …Run Code Online (Sandbox Code Playgroud) tframe ×11
delphi ×10
bpl ×1
c++ ×1
c++builder ×1
components ×1
delphi-2009 ×1
dll ×1
inheritance ×1
list ×1
load ×1
pointers ×1
record ×1
refactoring ×1
refer ×1
runtime ×1
winapi ×1