标签: tframe

如何改进Delphi框架的使用

我在Delphi中使用了多年的框架,它们是VCL最强大的功能之一,但它们的标准使用似乎有一些风险,例如:

  1. 很容易意外地移动或编辑框架主机窗体上的框架子组件,而没有意识到你正在"调整"框架 - 我知道这不会影响原始框架代码,但它通常不是你想要的.

  2. 使用框架时,您仍然可以使用其子组件进行可视化编辑,即使该框架已有数年之久且不应触及.

所以我开始思考......

  1. 是否有一种"分组"组件的方式,使他们的位置"锁定"?这对完成的表格和框架都很有用.通常其他开发人员将代码返回给我,其中只有表单边界发生了变化,甚至他们也不打算进行任何更改.

  2. 有没有办法将框架及其组件转换为单个Delphi组件?如果是这样,框架内部构件将完全隐藏,其可用性将进一步增加.

我对任何想法感兴趣......

布莱恩.

delphi components tframe

25
推荐指数
4
解决办法
1万
查看次数

在对象检查器上显示TFrame后代的其他属性

Delphi对象检查器不会按设计显示TFrame后代的其他属性.人们倾向于建议使用一种已知的技巧,这种技巧通常用于在对象检查器上显示TForm后代的属性.诀窍是:通过设计时包将注册TForm后代的自定义模块注册到Delphi IDE:

RegisterCustomModule(TMyFrame, TCustomModule);
Run Code Online (Sandbox Code Playgroud)

对象检查器可以通过这种方式显示TFrame Descendant实例的其他属性,但是当它嵌入到表单中时会丢失其框架行为.不可重新设计,不可能为其子组件实现事件,并且它接受子控件(它没有).但它在自己的设计领域表现正常.

看起来,Delphi IDE专门为TFrame提供的那些行为.它们可能不是通用设施.

有没有其他方法可以实现这一点而不会丢失框架行为?

我正在使用Delphi 2007


@Tondrej,

请提前阅读此问题的评论.

frameunit.dfm:

object MyFrame: TMyFrame
  Left = 0
  Top = 0
  Width = 303
  Height = 172
  TabOrder = 0
  object Edit1: TEdit
    Left = 66
    Top = 60
    Width = 151
    Height = 21
    TabOrder = 0
    Text = 'Edit1'
  end
end
Run Code Online (Sandbox Code Playgroud)
unit frameunit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls;

type
  TBaseFrame = Class(TFrame)
  protected
    Fstr: string;
    procedure Setstr(const Value: string);virtual; …
Run Code Online (Sandbox Code Playgroud)

delphi tframe

11
推荐指数
1
解决办法
6079
查看次数

控件'xxx'没有父窗口

我正在尝试在Delphi中编写一个dll库,该函数创建一个TFrame后代的实例并返回它.但是当我在一个应用程序中导入这个函数时,每次调用它时我都会得到一个例外,例如"'xxx'控件没有父窗口".我不是百分百肯定,但是当访问任何GUI控件时,该类的构造函数中出现异常.

你能告诉我这种行为的原因是什么吗?我应该只使用TForm后代还是有更好的解决方案?

谢谢!

delphi dll tframe

10
推荐指数
1
解决办法
1万
查看次数

我应该将delphi tframe用于多页表单吗?

我的应用程序中有一些表单具有不同的"状态",具体取决于用户的操作; 例如,当通过他的文件列出时,表单会在网格中显示有关该文件的一些数据,但如果他点击某个按钮,则网格会被与其相关的图表替换.简单地说,表单中的控件取决于用户想要做什么.

当然,这样做的显而易见的方法是根据需要显示/隐藏控件,就像小数字的魅力一样,但是一旦你达到每个状态10/15 +控件(或者真的超过3个状态)它就无法使用.

我现在正在尝试使用TFrame:我为每个状态创建一个框架,然后在我的表单上创建每个框架的实例,然后我只使用Visible显示我想要的那个 - 同时对其进行一些控制最重要的是,因为他们都共享它们.

这是做我想要的正确方法,还是我错过了一些东西?我以为我只能创建一个tframe实例,然后选择在其中显示哪个实例,但它看起来并不那样.

谢谢

delphi tframe

9
推荐指数
2
解决办法
4812
查看次数

在Delphi中使用框架的可接受方法是什么?

我正常地在SO周围散步并碰到一些框架讨论.

我主要是Delphi的爱好者,而不是专业人士,所以我必须学习如何以我自己的方式使用TFrame:

  • 在它的单位内创建一个TFrame.
  • 将该单元添加到主窗体Uses子句中.
  • 拥有该TFrame类型的私有变量
  • 表单的OnCreate实例化TFrame并将其附加到Create和.Parent上的TPanel
  • 在我的一个操作集上设置了TFrame.Visible:= True和.BringToFront.

经过一番个人商议,这是我的做法.

还有哪些方法可以使用框架?

delphi tframe

8
推荐指数
3
解决办法
1万
查看次数

为什么我的TFrame没有"看到"发布的消息?

我刚刚开始大量使用TFrames(好吧,是的,我一直生活在摇滚......).我认为框架支持消息处理程序声明 - 我已经看到很多这样的例子.那么为什么这个用于TFrame的简单测试单元永远不会看到它发布给自己的消息?(当我发现在我的大型应用程序中没有调用消息处理程序时,我创建了测试.)

unit JunkFrame;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

const
  DO_FORM_INITS = WM_USER + 99;

type
  TFrame1 = class(TFrame)
    Panel1: TPanel;
  private
    procedure DoFormInits(var Msg: TMessage); message DO_FORM_INITS;
  public
    constructor Create(AOwner: TComponent); override;
  end;

implementation

{$R *.dfm}

constructor TFrame1.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  PostMessage(self.Handle, DO_FORM_INITS, 0, 0);
end;

procedure TFrame1.DoFormInits(var Msg: TMessage);
begin
  ShowMessage('In DoFormInits!');
end;

end.
Run Code Online (Sandbox Code Playgroud)

此框架仅包含TPanel,框架用于仅包含框架和关闭按钮的简单主文件.

我错过了什么?

delphi message postmessage handler tframe

8
推荐指数
1
解决办法
1648
查看次数

德尔福,框架与形式.什么是多文档界面?

昨天我开始讨论"MDI vs tabbed interface".我已经问过我是否应该继续开发基于MDI的应用程序,或者我应该将子表单嵌入到标签页中.有人指出我应该使用TFrame代替......我的问题是:为什么?

在TFrame上嵌入表单时使用TFrame的优点是什么?到目前为止我不知道,切换只需要我重写代码的某些部分......

(无论如何,我不打算在设计时使用嵌入!)

提前致谢

delphi mdi frames tframe

7
推荐指数
2
解决办法
9348
查看次数

在另一个TForm中嵌入TForm时如何避免问题?

我经常将一个TForm后代嵌入另一个TForm后代,如下所示:

var
  Form1: TForm1;
  Form2: TForm2;
begin
  Form2.Parent      := Form1;
  Form2.BorderStyle := bsNone;
  Form2.Align       := alClient;
  Form2.Show;
end;
Run Code Online (Sandbox Code Playgroud)

通常这很好用,但有时Form2中的控件没有正确对齐.这类问题有一般的解决方法吗?

有人知道造成这种"错位"的原因吗?

我知道我可以TFrame用于这种工作,但我有很多库代码,我必须重写,我没有看到任何理由为什么TFormin TForm方法不起作用?

编辑:我已将组件识别TcxListView为罪魁祸首,我已向组件供应商(DevExpress)提交了错误报告:

http://www.devexpress.com/issue=B194161

编辑2: DevExpress的开发人员已经分析了这个问题并说它实际上是TGridPanelEmbarcadero组件中的缺陷:

http://qc.embarcadero.com/wc/qcmain.aspx?d=90324

delphi layout vcl delphi-2007 tframe

7
推荐指数
1
解决办法
2911
查看次数

为什么我的TScrollBox没有显示滚动条?

这似乎是一个非常简单的问题,但我无法使用滚动条来显示滚动条,这让我发疯.

情况就是这样.我需要在表单的一部分中显示可变数量的帧.可以通过TSplitter或通过调整表单大小来调整显示这些帧的区域.

我在创建表单时根据数据库中的记录动态生成帧.这些框架是FlowPanel的父级,它负责框架放置.FlowPanel位于ScrollBox中.

由于FlowPanel,当用户使用TSplitter或调整表单大小时,帧可能会重新对齐.如果任何框架重新定位在窗体的视图之外,我希望ScrollBox显示滚动条,以便用户可以向下滚动到那些不可访问的框架.这不会发生.位于滚动框尺寸之外的流动板区域中的那些框架是不可访问的.

我在滚动框中使用简单对象构建了一些测试,如果任何包含的对象出现在滚动框的维度之外,则滚动框会正确放置滚动条.

如果流动板与clClient(滚动框)对齐或锚定到滚动框的两侧,或者没有这些都没有关系.

我意识到我可以使用TPanel,并在面板的OnResize事件处理程序的代码中执行框架的放置和重新定位,但这就是FlowPanel的用途.

这里发生了什么?我已经摆弄了许多不同的滚动条属性,仍然无法让它工作.问题是什么,有解决方案吗?


好.我选择Ewe的答案是正确的,但是做这项工作的诀窍在于他的一个评论,我仍然没有对结果感到满意.

这是独家新闻.我确实按照Ewe建议的方式配置了我的ScrollBox和FlowPanel,但是使用了许多其他设置,因为该配置不起作用.我很确定这是由于表单的用户界面的复杂性,它在面板中有许多面板,许多分割器,并且表单本身是PageControl的TabSheet的父级(我省略了这个事实,因为测试表格作为一个立场单独形式产生相同的结果).

让它发挥作用的是Ewe建议将FlowPanel的AutoWrap关闭再打开,尽管它很笨重.我将以下代码添加到ScrollBox的OnResize事件处理程序:

procedure TCurrentJobsForm.ScrollBox1Resize(Sender: TObject);
begin
  Flowpanel1.Autowrap := False;
  FlowPanel1.AutoWrap := True;
end;
Run Code Online (Sandbox Code Playgroud)

调整大小时会有明显的闪烁,但我可以忍受,因为它会产生所需的结果.一旦用户调整表单大小,它将始终使用这些维度重新创建,因此调整大小是用户不经常进行的操作.

delphi tframe tscrollbox

7
推荐指数
2
解决办法
1万
查看次数

Delphi 7 - 处理表单中嵌入式帧的MouseWheel事件?

嗨,我有一个内部有几个框架的表格.

对于某些帧,我希望滚动内容(或至少处理鼠标轮事件).

我尝试过以下方法:

只需为每个帧分配一个OnMouseWheel事件处理程序

覆盖父窗体的MouseWheel事件:

procedure TFmReview.MouseWheelHandler(var Message: TMessage);
var   Control: TControl;
begin
    Control := ControlAtPos(ScreenToClient(SmallPointToPoint(TWMMouseWheel(Message).Pos)), False, True);
    if Assigned(Control) and (Control <> ActiveControl) then
    begin
         ShowMessage(Control.Name);
         Message.Result := Control.Perform(CM_MOUSEWHEEL, Message.WParam, Message.LParam);
         if Message.Result = 0 then
            Control.DefaultHandler(Message);
     end else inherited MouseWheelHandler(Message);
end;
Run Code Online (Sandbox Code Playgroud)

不幸的是,两者似乎都没有用.

  • 在情况1中,事件永远不会被触发,但是父表单鼠标轮处理程序被触发.
  • 在情况2中,接收焦点的控件是保持我希望发送鼠标轮事件的帧的面板.

因此,简单地说,如何将鼠标滚轮事件指向鼠标光标所在的最顶层控件(无论光标位于哪个帧/父/窗体等)?

delphi focus mousewheel tframe tform

6
推荐指数
1
解决办法
3046
查看次数