表单和框架之间的通信

发布于 2024-09-27 15:25:57 字数 532 浏览 0 评论 0原文

我一直在 Delphi 2009 中开发一个程序。它与 Materialise 的“Mimics”程序非常相似,您可以在其中创建和操作 3D 网格。有 4 个具有不同方面的面板,用于查看 3D 对象(XY、YZ、XZ 和 3D 透视)。每个面板都是我为查看 3D 对象而制作的自定义框架的一个实例。然后将这 4 个面板加载到具有按钮和其他组件的表单上。

我遇到的一个问题是框架必须访问它们所在窗体的子例程。 EG 如果我更改了其中一个框架中正在处理的网格的某些内容,则所有框架都应该更新(刷新),这是父表单中可用的过程。但要调用父窗体上的过程,我必须将父窗体的单元文件包含在 3D 框架的实现 use 子句中。这很好,而且一般情况下这不会有任何问题。问题是我无法使用父窗体进行继承。如果我从父窗体创建继承类,则单元名称和窗体名称会更改,然后我必须更改 3D 框架以引用这个新更改的窗体。

这确实是我问题的症结所在。我不知道如何在不明确说明表单名称的情况下从其子框架引用父表单的属性。我希望能够重用和扩展父表单,但我不知道如何在不更改表单使用的 3D 框架的情况下实现这一点。

任何帮助将不胜感激。谢谢。

I've been working on a program in Delphi 2009. It very similar to the program "Mimics" by materialise, where you can create and manipulate 3D meshes. There are 4 panels with different aspects for viewing a 3D object (XY,YZ,XZ, and 3D perspective). Each of the panels is an instance of a custom frame I made for viewing 3D objects. The 4 panels are then loaded onto a form which has buttons and other components.

A problem that I am running into is that the frames must access subroutines of the form on which they reside. E.G. If I change something about the mesh im working on in one of the frames, ALL of the frames should be updated (refreshed) which is a procedure available in the parent form. But to call procedures on the parent form I have to include the parent form's unit file in the implementation uses clause of the 3D frame. That is fine, and this in general works without any trouble. The problem is that I cannot use the parent form to inherit from. If i create an inherited class from the parent form, the unit name and form name change and I must then alter the 3D frame to reference this new changed form.

Thats really the crux of my problem. I dont know how to reference the attributes of a parent form from its child frames without explicitly stating the name of the form. I want to be able to reuse and expand upon the parent form, but I dont see how its possible without also changing the 3D frames which are used by the form.

Any help would be greatly appreciated. Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冰魂雪魄 2024-10-04 15:25:57

因此,您有一个独立的组件(框架),它必须能够从其所在的表单调用代码,而无需了解表单本身的编译时知识?听起来很像一个 TButton,当您单击它时,它不知道如何处理它所在的表单,解决方案是相同的:使用事件处理程序。将 OnChangeMes​​h (或类似的)事件属性添加到您的框架中,并让您的表单在创建框架时分配适当的方法。

So you have a self-contained component (a frame) that has to be able to invoke code from the form it's placed on, without having compile-time knowledge of the form itself? Sounds a lot like a TButton that doesn't know what to do with the form it's on when you click it, and the solution is the same: use an event handler. Add an OnChangeMesh (or something like that) event property to your frame, and have your form assign the appropriate method when it creates the frames.

久随 2024-10-04 15:25:57

另一种选择可能是定义父表单实现的接口。它应该具有您想要从子框架访问的所有属性和方法,例如:

ImyFormInterface=interface
['{08BD9B3C-C48E-47B7-AE67-279277C7E024}']
  function GetValue1: integer;
  function GetValue2: integer;
  procedure SetValue1(val: integer);
  procedure SetValue2(val: integer);

  procedure SomeMethod;
  function GetSomeValue: integer;


  property Value1: integer read GetValue1 write SetValue1;
  property Value2: integer read GetValue2 write SetValue2;
end;

然后让您的主窗体实现该接口:

TForm1 = class(TForm, ImyFormInterface)
private
  { Private declarations }
public
  // Implement ImyFormInterface
  function GetValue1: integer;
  function GetValue2: integer;
  procedure SetValue1(val: integer);
  procedure SetValue2(val: integer);

  procedure SomeMethod;
  function GetSomeValue: integer;
public
  { Public declarations }
end;

然后在您的框架中您可以使用类似的东西:

procedure Tframe1.Button1Click(Sender: TObject);
var pform: TcustomForm;
i: ImyFormInterface;
begin
  pform:=GetParentForm(self);
  if (pform.GetInterface(ImyFormInterface, i)) then
  begin
    i.SomeMethod;

    i.Value1:=i.Value1+10;

    Self.SomeProperty:=i.GetSomeValue;
  end;
end;

现在,如果您从父窗体继承,它将一切仍然有效,因为您仍然可以获得界面。另外,您可以将框架放在一个全新的表单上,只要该新表单实现了该接口,那么它也可以在那里工作。

Another option may be to define an interface that the parent form implements. It should have all the properties and methods that you want to access from your child frame, something like:

ImyFormInterface=interface
['{08BD9B3C-C48E-47B7-AE67-279277C7E024}']
  function GetValue1: integer;
  function GetValue2: integer;
  procedure SetValue1(val: integer);
  procedure SetValue2(val: integer);

  procedure SomeMethod;
  function GetSomeValue: integer;


  property Value1: integer read GetValue1 write SetValue1;
  property Value2: integer read GetValue2 write SetValue2;
end;

Then make your main form implement that interface:

TForm1 = class(TForm, ImyFormInterface)
private
  { Private declarations }
public
  // Implement ImyFormInterface
  function GetValue1: integer;
  function GetValue2: integer;
  procedure SetValue1(val: integer);
  procedure SetValue2(val: integer);

  procedure SomeMethod;
  function GetSomeValue: integer;
public
  { Public declarations }
end;

Then in your frame you can use something like:

procedure Tframe1.Button1Click(Sender: TObject);
var pform: TcustomForm;
i: ImyFormInterface;
begin
  pform:=GetParentForm(self);
  if (pform.GetInterface(ImyFormInterface, i)) then
  begin
    i.SomeMethod;

    i.Value1:=i.Value1+10;

    Self.SomeProperty:=i.GetSomeValue;
  end;
end;

Now if you inherit from your parent form it will all still work because you will still get the interface. Also, you could put your frames on an entirely new form and as long as that new form implements the interface then it will work there too.

幸福丶如此 2024-10-04 15:25:57

您可以使用订阅结构。维护视图框架的全局列表。如果帧需要更新,只需循环此列表并为每个帧调用 updatee 过程。如果某些内容发生变化,这允许您更新 1,2 或 100 帧。

如果您想完全采用 OOP 并且对此感到非常高兴:这就是观察者模式。

http://en.wikipedia.org/wiki/Observer_pattern

You could use a subscription structure. Maintain a global list of the view-frames. If the frames need to update simply loop over this list and call the updae procedure for eacht of the frames. This allows you to have 1,2 or 100 frames update if something has changed.

If you want to go all OOP and be really happy about it: this is the observer pattern.

http://en.wikipedia.org/wiki/Observer_pattern

猛虎独行 2024-10-04 15:25:57

最终的解决方案可能是检查视觉表单/框架继承。

可以从基本表单导出表单,从基本框架导出框架。将虚拟方法添加到基框架并在继承版本中覆盖它们。

A final solution might be to check out visual form/frame inheritance.

It is possible to derive forms from a baseform and frames from a baseframe. Add virtual methods to the baseframe and override them in the inherited versions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文