2009-04-29 73 views
3

我有一個Delphi文檔瀏覽器作爲主窗體的應用程序。當用戶打開一個文檔時,我們打開一個編輯器窗口。我們希望每個編輯器在任務欄上都有一個按鈕,以及主窗體。我已經應用了普通代碼來做到這一點(下面),但是當我在使用編輯器窗口後單擊主窗體時,編輯器仍然處於頂部,而焦點位於主窗體上。我無法弄清楚是什麼導致了這種行爲。多個應用程序窗口激活不能正常工作

舞臺設置:我打開主窗體和文檔窗體。

  1. 點擊其他應用程序,單擊主窗體,主窗體保持專注。 (表現爲預期的。)

  2. 單擊文檔表格上,單擊主窗體上,文件的形式來 後到前,但表現出來的不活躍。 (圖爲結果)

alt text http://www.matthew-jones.com/temp_xfer/titlebarfailure.jpg

第一步,這是德爾福2007年,我在該項目中:

Application.MainFormOnTaskBar := True; 

爲主要形式,我也沒有額外的代碼。

對於文件的形式,我有

procedure TCommonEditForm.CreateParams(var params: TCreateParams); 
begin 
    inherited; 
    params.WndParent := 0; // GetDeskTopWindow; no diff 
end; 

我試圖找出是否有是實現這一點的消息,但無法找到任何合適。我已經在代碼中搜索與「激活」有關的任何內容。線索歡迎!

回答

6

我的應用程序按照您描述的方式工作。這是我採取的方法。我本來希望找到一個更簡單的方法,但從來沒有。

我開始閱讀這些文章。這首先是一個偉大的寫了彼得以下:

http://groups-beta.google.com/group/borland.public.delphi.winapi/msg/e9f75ff48ce960eb?hl=en

其他信息,這裏也發現了,但是這並不能證明是一個有效的解決方案:爲我所用: http://blogs.teamb.com/DeepakShenoy/archive/2005/04/26/4050.aspx

最終這是我結束了。

我的啓動畫面兼作應用程序主窗體。主窗體與應用程序對象有特殊的聯繫。使用所有輔助形式可以使我獲得我一直在尋找的行爲。

在任務欄上的每個表單上,我都會重寫CreateParams。我這樣做對我的編輯形式和用戶所認爲的「主表」

procedure TUaarSalesMain.CreateParams(var Params: TCreateParams); 
begin 
    inherited CreateParams(Params); 
    Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW; 
    Params.WndParent := GetDesktopWindow; 
end; 

我的「主」的形式儘可能德爾福關注負載在其Activitate功能真正的主要形式。我使用一個成員變量來跟蹤第一個激活。然後在函數結束時,我隱藏了飛濺窗體,但不要關閉它。這對我很重要,因爲如果用戶正在編輯文檔並關閉主窗體,我不希望編輯屏幕同時被強制關閉。這樣,所有可見的表單都被視爲相同。

if FFirstActivate = false then 
     exit; 

    FFristActivate := false; 

    /* 
     Main Load code here 
     Update Splash label, repaint 
     Application.CreateForm 
     etc. 
    */ 


    // I can't change visible here but I can change the size of the window 
    Self.Height := 0; 
    Self.Width := 0; 
    Self.Enabled := false; 

    // It is tempting to set Self.Visible := false here but that is not 
    // possible because you can't change the Visible status inside this 
    // function. So we need to send a message instead. 
    ShowWindow(Self.Handle, SW_HIDE); 

    end; 

但仍然存在問題。當所有其他表單關閉時,您需要關閉主窗口。我在父親<> nil的附近例程中有一個額外的檢查,因爲我使用表單作爲插件(形成我的目的,他們比框架更好地工作)。

我真的不喜歡使用空閒事件,但我沒有注意到這是對CPU的拖動。

{ 
    TApplicationManager.ApplicationEventsIdle 
    --------------------------------------------------------------------------- 
} 
procedure TApplicationManager.ApplicationEventsIdle(Sender: TObject; 
    var Done: Boolean); 
begin 

    if Screen.FormCount < 2 then 
    Close; 
end; 

{ 
    TApplicationManager.FormCloseQuery 
    --------------------------------------------------------------------------- 
} 
procedure TApplicationManager.FormCloseQuery(Sender: TObject; 
    var CanClose: Boolean); 
var 
    i: integer; 
begin 

    for i := 0 to Screen.FormCount - 1 do 
    begin 
    if Screen.Forms[i] <> self then 
    begin 
     // Forms that have a parent will be cleaned up by that parent so 
     // ignore them here and only attempt to close the parent forms 
     if Screen.Forms[i].Parent = nil then 
     begin 
     if Screen.Forms[i].CloseQuery = false then 
     begin 
      CanClose := false; 
      break; 
     end; 
     end; 
    end; 
    end; 

end; 

{ 
    TApplicationManager.FormClose 
    --------------------------------------------------------------------------- 
} 
procedure TApplicationManager.FormClose(Sender: TObject; 
    var Action: TCloseAction); 
var 
    i: integer; 
begin 

    for i := Screen.FormCount - 1 downto 0 do 
    begin 
    if Screen.Forms[i] <> self then 
    begin 
     // Forms that have a parent will be cleaned up by that parent so 
     // ignore them here and only attempt to close the parent forms 
     if Screen.Forms[i].Parent = nil then 
     begin 
     Screen.Forms[i].Close; 
     end; 
    end; 
    end; 

end; 

到目前爲止,這已經很好地服務了我。我對Vista做了一些小改動,因爲我的「Main/Splash」屏幕圖標仍然顯示。我不記得那是什麼。我可能不需要設置寬度,高度,啓用,並在啓動畫面上發送隱藏消息。我只是想確保它沒有出現:-)。

處理密切事件是必要的。如果我沒有記錯,當windows發送關閉消息時需要這樣做。我認爲只有主要形式才能得到這個信息。

+0

隱藏的聲音聽起來很可怕,但它實際上也可能解決另一個問題。如果沒有理想出現,這可能是我的目標。謝謝! – mj2008 2009-04-29 15:10:09

0

對不起,如果這真的很愚蠢,但你沒有將formstyle設置爲fsStayOnTop嗎?這將解釋這種行爲。

+0

不好 - 雖然好想法。 FormStyle是fsNormal。 PopupMode是pmNone。 BorderStyle是bsSizeable。 BorderIcons默認。 – mj2008 2009-04-29 13:15:24

0

也許在的CreateParams

Params.ExStyle := Params.ExStyle OR WS_EX_APPWINDOW; 

添加這個或嘗試在這段代碼的任何地方。我首先在表單上使用它.OnCreate事件。

SetWindowLong(Wnd, GWL_EXSTYLE, 
    GetWindowLong(Wnd, GWL_EXSTYLE) or WS_EX_APPWINDOW) ; 

這樣做的缺點是,如果主窗體最小化其他形式的隱藏藏漢,但當主要形式做恢復。

+0

謝謝 - 已經嘗試過,但沒有影響(嗯,不是這個問題)。 (我應該提到它,但是我現在已經研究了一兩天,並且實際上刪除了被註釋掉的那一行)。 – mj2008 2009-04-29 14:11:39

相關問題