我的应用程序布局基于左侧的treeView和右侧的面板.该面板托管一个不同的TForm类,具体取决于所选的树节点(一种'形式浏览器').一次只显示一个表单,该表单公开存储在别处的基础数据,并在每个新的树节点点击时创建和销毁表单实例.
除了以下场景外,这一切都正常.单击表单上的一个按钮,该按钮启动需要一秒左右的操作.在此操作期间,可能会调用Application.ProcessMessages.现在,在此操作实际完成之前,用户单击一个新的树节点.处理此wmMousedown消息,导致表单立即释放.然后,操作代码返回到表单代码,以查找自己已更改并导致AV.
我的问题是,在我允许表单被释放之前,有没有办法知道表单的消息已经全部处理完毕?单击关闭按钮时,模态窗体似乎会执行此操作,因为如果忙,它们会在关闭之前暂停...
谢谢Brian
我有一个MDI应用程序,有许多MDI子项(以及非MDI表单),并希望跟踪当前激活的表单,并始终关注.当用户在应用程序中从一种形式切换到另一种形式时,我想捕获窗口激活消息,并在后台设置一个全局变量到活动形式的属性(此属性继承自基类).我最初将代码放在基类的OnActivate事件处理程序中(我的应用程序中的所有表单都使用)但是已经注意到这个事件并不总是被引发.有任何想法吗?
我正在使用Delphi 2006 BDS.
我有一个需要几秒钟才能加载的应用程序(大量初始化)。GUI 在启动期间冻结。所以我想创建一个在应用程序加载时淡入淡出的启动画面。我使用TBackgroundWorker组件在后台线程中执行动画。
但是,当我使用这个组件时会发生一些奇怪的事情:当它发出“工作完成”的信号时(请参阅 BackgroundWorkerWorkComplete),同时我打开的消息对话框会自动关闭。
procedure TMainForm.ButtonStartSplashClick(Sender: TObject);
VAR
frmSplash: TfrmSplash;
begin
frmSplash:= TfrmSplash.Create(NIL);
frmSplash.StartAnimation;
//MessageBox(Handle, 'Hi', nil, MB_OK); // This remains on screen
Application.MessageBox(PChar('Hi'), PChar('Box'), MB_ICONINFORMATION); // This is automatically closed when the background thread is done
end;
Run Code Online (Sandbox Code Playgroud)
这是启动画面:
procedure TfrmSplash.StartAnimation;
begin
Show;
BackgroundWorker.Execute;
end;
procedure TfrmSplash.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;
procedure TfrmSplash.BackgroundWorkerWork(Worker: TBackgroundWorker);
VAR i: Integer;
begin
for i:= 1 to 255 DO
begin
AlphaBlendValue:= i; // do not access GUI directly from …Run Code Online (Sandbox Code Playgroud) 有没有办法让一个表单使用另一个表单中的事件过程?
例如,我有一个名为PongForm的表单,另一个名为ObstPongForm.PongForm上有一个滚动条,ObstPongForm上有另一个滚动条.是否有可能让ObstPongForm在它自己的'tick'事件中使用PongForm的'tick'事件中的代码?也许让ObstPongForm继承PongForm?
现在,我在过去5年中创建了至少300多种手动创建的表单,我从未见过这个问题.我当然有一个主要形式,然后是一堆较小的儿童形式.这些子表单不是自动创建的,它们是在我的代码中手动声明和创建的.这个项目还为时尚早,这意味着在这个项目中没有那么多我可能会遗漏的东西.但问题是,我所做的只是创建表单,将父表单分配给主表单,并且没有任何代码来显示表单,它无论如何都会显示自己的表单.
FControlPanel:= TfrmControlPanel.Create(nil);
FControlPanel.Parent:= Self;
Run Code Online (Sandbox Code Playgroud)
这就是我创建它的所有代码.绝对没有代码在实际的子窗体中.至少它应该FControlPanel.Show是可见的,但出于某种原因,无论如何它都是可见的.
我确实有预感可能导致这种行为开始.但我不能把两个和两个放在一起.我尝试使用MDI表单功能,将表单保留在主表单中.但在经过多次试验/错误情景后,我放弃并重新设置了我的属性.我改变的唯一属性是FormStyle - 我在fsMDIForm,fsNormal和fsStayOnTop之间切换(用于试验)的主要形式.孩子表单我将它们切换到fsMDIChild.在我放弃之后,我将它们全部切换回默认值fsNormal.在这个"车展"开始发生之后,就是在这之后.
此外,可能是一个重要的注释,这些子表单继承自主表单.这个主表单实际上也没有代码,至少没有代码可以显示它.在我的任何代码中,我都没有告诉它显示这些子表单,但无论如何它都可以.我知道他们不会自动创作.
我能做错什么?
PS - 实现MDI的问题一般是另一个问题,我不是在询问MDI,但它可能是导致这种情况发生的原因,因为已知改变组件的属性会永久性地切换组件的内部属性,例如,在TPanel上,将"ParentBackground"切换为true,然后再次返回false,使其在使用XPMan时正确显示指定的颜色.
TForm1 = class(TForm)
Button1:TButton;
Memo1:TMemo;
end;
Run Code Online (Sandbox Code Playgroud)
这是关于delphi表单的正常代码.
TForm1 = class(TForm)
public
Button1:TButton;
Memo1:TMemo;
end;
Run Code Online (Sandbox Code Playgroud)
只需添加一个公共关键字.
得到运行时错误.
我对此非常困惑.
我试图按照http://docwiki.embarcadero.com/CodeExamples/XE7/en/FMXEmbeddedForm_(Delphi)的例子,但我遇到了TCustomForm的孩子的第一个问题,这显然是只读的,所以我发表了评论说出来,放在ArgForm.Parent:= ArgParent;代替,但我仍然只得到一个空的屏幕并不能看到那些在我的第二个表格的按钮.
我的主要表格的代码是:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, Unit2;
type
TForm1 = class(TForm)
Panel1: TPanel;
procedure FormCreate(Sender: TObject);
procedure EmbedForm(ArgParent : TControl; ArgForm : TCustomForm);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Form2: TForm2;
implementation
{$R *.fmx}
procedure TForm1.FormCreate(Sender: TObject);
begin
Form2:= TForm2.Create(Self);
EmbedForm(Panel1, Form2);
end;
procedure TForm1.EmbedForm(ArgParent: TControl; ArgForm: TCustomForm);
begin
//while ArgForm.ChildrenCount>0 do
//begin
//ArgForm.Children[0]:= ArgParent);
//end; …Run Code Online (Sandbox Code Playgroud) 我听说Delphi应用程序使用"延迟加载",推迟加载表单组件,直到实际引用它们为止.在另一篇文章中提到过- "这就是为什么我们将TPageControl更改为延迟加载 - Delphi IDE的选项对话框加载时间太长了!"
我假设这也适用于使用Delphi创建的应用程序,但是我在VCL源代码中找不到任何延迟加载的提及,这表明如果确实存在,它可能被称为其他东西.
在正常使用情况下,应用程序不经常启动并运行很长时间,可能需要放弃更快的启动时间,并在第一次实际使用时更快地绘制VCL组件.
Delphi程序员是否对此有任何控制权?(LazyLoad := false ;没工作;-)
我最近调试了一个复杂的bug.这是由访问不存在的Form.Handle(带状指针)引起的.这个bug以相当意想不到的方式向我揭示 - 访问Forms会Handle导致调整大小和重新绘制.
我希望Form.Handle通过垃圾指针访问只会返回一些垃圾THandle.期望Handle在表单创建时创建一次并保持相同直到Form被销毁.
为什么会这样,这TForm.Handle不是一个在表单创建时初始化并通过访问的字段
property Handle: Integer read FHandle;
Run Code Online (Sandbox Code Playgroud)
,但是是一个吸气剂
property Handle: Integer read GetHandle;
Run Code Online (Sandbox Code Playgroud)
CreateWnd在第一次访问时创建Handle甚至Window()?
在 Windows 10 上运行的 Delphi 10.4.2 Win32 VCL 应用程序中,在双显示器设置中,当我将 MainForm(或任何其他辅助窗体)设置为通过设置开始最大化时WindowState := wsMaximized,该窗体仅在主监视器上最大化。
如何将表单最大化到整个桌面,以将表单大小设置为包括两个监视器?是否有类的内置方法TForm来实现这一点?
在OnFormShow事件中,我需要(对于一组特定的条件)不显示表单.
像"如果计数器> 15不显示表格"之类的东西.
我当然可以在表单创建上重构和移动很多东西,但这是很多工作,因为这是一种常见的形式,并且涉及太多的变化.
现在我在OnFormShow的末尾关闭表单,但无论如何我看到表单出现了几毫秒.
不幸的是,告诉我不要显示表单的条件是在OnFormShow中决定的.是否有诀窍避免表格显示?
在我的应用程序中,我有两种形式,比如LoginForm和AccountForm
LoginForm被设置为主窗体,它是用户能够从他的帐户登录时的表格(两个TEdits和登录按钮).当用户键入其登录详细信息并进行连接时,将打开一个新表单AccountForm.
如何在不关闭整个应用程序的情况下关闭登录成功的LoginForm?或者用这种语言如何使用下面的代码来关闭登录表单但不关闭应用程序.
if (not IncludeForm.sqlquery1.IsEmpty) and (isblacklisted='0') and (isactivated='1') then
begin // Login Successful *** Show the account window
AccountForm.Show;
LoginFrom.Close; // <----The problem is in this line, using this line causes the whole application to close***}
end;
Run Code Online (Sandbox Code Playgroud)
谢谢