2012-01-19 90 views
7

我有一个主窗体和其他窗体的项目。 当应用程序加载时,它需要执行一些任务并以主窗体顶部的模式形式显示结果。 我的问题是,如果我把调用的功能做任务/创建和在主窗体onshow事件中显示模态窗体模态窗体出现,但主窗体不会直到模态窗体关闭,这是我期望发生的事情。为了解决这个问题,我在主窗体中添加了一个计时器,并在主窗体的onshow事件上启动计时器,计时器调用该函数执行任务/创建并显示模态窗体。所以现在主窗体出现在模态窗体之前。Delphi onshow主窗体/模态窗体

但是我看不到这是最好的解决方案,并想知道是否有人可以提供更好的解决方案。

我用Delphi 7

科林

+1

使用PostMessage。 http://stackoverflow.com/questions/7094873/visibility-of-form-in-delphi – SimaWB

+0

抱歉,为什么这个问题在主题问题列表中显示“模糊”? – kobik

+0

@ kobik:当他们有一个你忽略的标签,并且他们的投票得分超过某个限制时,AFAIK问题会变暗。顺便提一下关于SO工作方式的问题,最好在元网站上提问(请参阅主导航栏中的链接)。 –

回答

9

一个常用的选项是张贴自己在形式的OnShow的消息。像这样:

const 
    WM_SHOWMYOTHERFORM = WM_USER + 0; 

type 
    TMyMainForm = class(TForm) 
    procedure FormShow(Sender: TObject); 
    protected 
    procedure WMShowMyOtherForm(var Message: TMessage); message WM_SHOWMYOTHERFORM; 
    end; 

... 


procedure TMyMainForm.FormShow(Sender: TObject); 
begin 
    PostMessage(Handle, WM_SHOWMYOTHERFORM, 0, 0); 
end; 

procedure TMyMainForm.WMShowMyOtherForm(var Message: TMessage); 
begin 
    inherited; 
    with TMyOtherForm.Create(nil) do begin 
    try 
     ShowModal; 
    finally 
     Free; 
    end; 
    end; 
end; 
+2

尽管这是解决方案的正确思路,但它的实现并不是很好。 :)使用自定义消息,并实现该特定消息的处理程序,而不是替换整个WndProc。只需在表单的类型声明之前声明自定义消息,并添加'procedure UMShowMyOtherForm(var Message:TMessage);消息UM_SHOWMYOTHERFORM;'。那么唯一中断WndProc正常流程的是你的自定义消息。 –

+0

@Ken的确如此。我习惯于处理在运行时分配的消息ID –

+0

这就是我以前的人员处理这个问题的方式,所以我一直这样做,因为它可以工作。如果你有他们,一些技术细节会很好。 –

2

为什么不使用MainForm OnActivate这样的事件?

procedure TMyMainForm.FormActivate(Sender: TObject); 
begin 
    //Only execute this event once ... 
    OnActivate := nil; 

    //and then using the code David Heffernan offered ... 
    with TMyOtherForm.Create(nil) do begin 
    try 
     ShowModal; 
    finally 
     Free; 
    end; 
end; 

将事件设置为零将确保此代码仅在启动时运行一次。

0

在调用Windows API函数ShowWindow之前立即触发OnShow事件。这是对ShowWindow的调用,实际上会导致窗口出现在屏幕上。

所以你理想的情况下需要在ShowWindow的电话后立即运行。事实证明,驱动所有这些的VCL代码在消息处理程序中为CM_SHOWINGCHANGED。该消息处理程序触发OnShow事件,然后调用ShowWindow。所以一个优秀的解决方案是在CM_SHOWINGCHANGED运行处理程序后立即显示您的模态窗体。像这样:

type 
    TMyMainForm = class(TForm) 
    private 
    FMyOtherFormHasBeenShown: Boolean; 
    protected 
    procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED; 
    end; 

..... 

procedure TMyMainForm.CMShowingChanged(var Message: TMessage); 
begin 
    inherited; 
    if Showing and not FMyOtherFormHasBeenShown then begin 
    FMyOtherFormHasBeenShown := True; 
    with TMyOtherForm.Create(nil) do begin 
     try 
     ShowModal; 
     finally 
     Free; 
     end; 
    end; 
    end; 
end;