delphi等窗口完全显示后执行一段代码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi等窗口完全显示后执行一段代码相关的知识,希望对你有一定的参考价值。

参考技术A 分类: 电脑/网络 >> 程序设计 >> 其他编程语言
问题描述:

如题,我有个程序首先是启动页面等主窗口载入之后就退出启动页面进入主窗口但我现在主窗口在会连接网页,此时如果用户的网速慢或网页打不开,启动页面置留的时间就很长请问怎么样可以让主窗口完全显示以后再去连接网页,

解析:

你说的或意思是不是像WORD 启动时效果

巧用Delphi制作溅射屏幕

(作者:施路)

精心编写的WINDOWS程序显示启动注意事项,称之为溅射屏幕(splash screen)。利用一点儿小小的内容,即可给程序的显示添加不少色彩。

由于工程本身创建程序的主窗口,且启动溅射屏幕必须在创建主窗口之前出现,所以工程文件必须创建自己的启动屏幕。这意味着用户必须修改源代码来创建工程文件,而这通常在DELPHI编程中是不需要的。下面的过程介绍了溅射屏幕的建立过程。

1、开始一个新的工程。将窗体命名为MainForm,同时将其Caption属性设置为SplashinDemo。把这个工程保存在一个目录中,如C:\Projects\Splashin。把MainForm的单元命名为Main,把工程文件命名为Splashin。

2、在MainForm中插入一个Button组件。将Button的Name属性改为ExitButton,而将其Caption属性改为Exit。为ExitButton的OnClick事件创建一个处理器,在过程的begin和end关键词之间插入Close;语句。

3、选取File|New Form命令,或者单击New Form速度按钮。添加一个新的窗体。

4、将这个窗体的Name属性改变为SplashForm,删除其Caption属性。此外,将其BorderStyle属性改变为bsnone,同时将BorderIcons下的三个子值设置为False。

5、保存这个工程。当Delphi提示读者提供单元文件名时,要确信当前目录为正确的目录。为SplashForm的单元文件名输入Splash。

6、将SplashForm的Enabled属性设置为False。这里不想让用户能够给窗口提供键盘和鼠标命令,这是极少见的情况之一。在这个例子中,我们想让程序对SplashForm的显示拥有完全的控制权。

7、由于窗口没有轮廓,所以从Additional组件类中插入一个Bevel组件对象。这有助于定义窗口的边缘。将Bevel1的Align属性设置为alClient。同时,将对象的Shape属性改变为bsFrame,将其Style属性改变为bsRaised。这些值由使用者来确定。

8、在SplashForm中插入想使用的组件,在这里不要插入任何按钮或者其他相互作用的控件。应用程序本身显示和去除启动溅射对话框。

9、选择Project菜单。高亮显示Splash工程个弹出式菜单。选择Options命令。在所产生的Project Options对话框中,选取Forms页标签。注意,MainForm和SplashForm位于自动创建的窗体列表中。高亮显示每个窗体并单击鼠标右按钮来将其移动到Available窗体。所有的Delphi窗体在运行时都是在内存中自动创建的,这要消耗内存和系统资源。在这样的一个案例中,程序是在运行时创建窗体的,读者应该从自动创建的列表中删除窗体。关闭ProjectOptions窗口。

10、接下来,修改工程的源代码,以便在显示主窗口之前显示溅射对话框。这里需要在工程文件中插入语句,以便与Splash.dpr工程文件相匹配。工程源代码如下:

program Project3;

uses

Forms,

main in 'main.pas' MainForm,

splash in 'splash.pas' SplashForm;

$R *.RES

begin

SplashForm:=TSplashForm.Create(Application);

SplashForm.Show;

SplashForm.Update;

Application.CreateForm(TMainForm,MainForm);

SplashForm.Close;

Application.Run;

end.

11、如果这时编译和运行程序,它就非常快速地显示和去除启动溅射对话框,以至用户可能没机会见到它。为了强迫对话框保持几秒钟的可见时间,请选取程序的MainForm。为窗体的OnCreate命令创建一个处理器。在关键词的前面添加一个名为stopTime的长整型变量。在begin和end之间插入两个语句:一个为对Windows GetTickCount函数的调用。来将stopTime设置为Windows已在运行的秒数;另一个语句为while语句,这个语句另外延迟2秒钟。程序清单如下:

unit main;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls;

type

TMainForm = class(TForm)

Exitbutton: TButton;

procedure ExitbuttonClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

private

Private declarations

public

Public declarations

end;

var

MainForm: TMainForm;

implementation

$R *.DFM

procedure TMainForm.ExitbuttonClick(Sender: TObject);

begin

close;

end;

procedure TMainForm.FormCreate(Sender: TObject);

var

stopTime:LongInt;

begin

stopTime:=GetTickCount div 1000;

while ((GetTickCount div 1000)<(stopTime+2)) do

Sleep(1);

end;

end.

12、按F9编译、运行程序。

用于Delphi的铬嵌入 - 当显示模态窗口时,不会触发TChromiumOSR.OnPaint

我在dcef3包中使用了屏幕外渲染组件TChromiumOSR - Chromium-embedded库的Delphi包装器。

Situation

FormA包含TChromiumOSR并绘制输出。 Modal FormB通过对js执行一些FormA.TChromiumOSR代码来修改网页。

Issue

TChromiumOSR.OnPaint事件(在FormA)直到FormB.ShowModal返回才触发。

Notes

  • 在上述具有标准TChromium控制的情况下(在模态形式下)没有这样的问题。

我假设``TForm.ShowModal'方法只阻止背景形式的输入,而不是绘画?

或者它是由cef3的内部工作引起的?

无论如何,如何解决?谢谢。

dcef3 master branch is here

答案

我已成功使用从模态窗体调用的ExecuteJavaScript方法更新HTML元素。但你可能也使用CEF V8(这是我没有测试过的)。对于需要手动使当前视图无效的情况,可以调用Invalidate

MyChromiumOSR.Browser.Host.Invalidate(PET_VIEW);

但这是解决方法而不是解决方案。 CEF引擎应该为您发生相关元素的无效。如果您想出MCVE,我可以更多地调查您的具体问题。

另一答案

好吧,我发现了问题的根源 - 它不是cef3或dcef3中的错误,而是由于我不正确地使用Delphi Event Bus引起的,以下是重现问题的步骤:

  1. 在一个'delphi event bus'处理程序中,程序显示一个模态形式,此时主线程的执行被阻止。
  2. 在模态表单的顶部,执行某些操作的用户将启动后台线程,后者又将向主线程发送消息,主线程又将调用“delphi事件总线”以发布另一个新事件,将执行一些js代码来更新dcef3内的网页,这反过来将触发一些dcef3事件(在主线程中),这里是程序卡住的地方 - 因为TEventBus.Post()方法被TCriticalSection锁定。

解决方案:在步骤#1中,不要直接调用ShowModal,而是使用PostMessage winapi等技术来“延迟”执行ShowModal

我不确定我是否清楚地描述了它......

以上是关于delphi等窗口完全显示后执行一段代码的主要内容,如果未能解决你的问题,请参考以下文章

Delphi中有关窗口绘制

VC++如何实现 弹出窗口,然后等窗口关闭后再执行剩下的代码?

delphi如何关闭启动窗体

c# 怎么在窗体完全显示出来后执行某个方法?

delphi程序中为啥运行后程序窗口不显示,进程中有

用于Delphi的铬嵌入 - 当显示模态窗口时,不会触发TChromiumOSR.OnPaint