簡體   English   中英

如何讓FindDialog保持最佳狀態(Delphi)?

[英]How Can I Keep the FindDialog from Staying on Top (Delphi)?

在Delphi 2009中,我做了一個簡單的事情:

FindDialog.Execute;

FindDialog窗口保持在程序主窗口的頂部。

但是,如果我在我自己的程序窗口中打開來自其他程序的另一個窗口,則FindDialog窗口仍然位於另一個窗口的頂部。

如果我嘗試使用其他程序(例如記事本)的FindDialog,則不會發生這種情況。 在記事本和其FindDialog上打開另一個程序窗口將覆蓋Notepad和FindDialog窗口。 這似乎是正確和預期的行為。

這是我做錯了還是Delphi實現FindDialog的問題? 有什么我可以做到使記事本的方式工作?


謝謝大家的評論。 您無法重現我的問題的事實已經是一個線索,它是導致這種情況的其他原因。 這將有助於我追蹤它。 當我發現一些東西時,我會再研究一下並發布更多信息。


很有意思。 我的PrintDialog不會保持領先。 仍然不知道為什么我的FindDialog會這樣做。 還在研究......


我將調用更改為:FindDialog.Execute(Handle); 還是排在最前面。


我在我的主窗體中添加了另一個FindDialog(這次是FindDialog1),並在程序啟動時執行它。 它具有相同的保持最佳行為。 這至少表明它與我的FindDialog或我用它做的自定義沒有任何關系。 所以它必須是我主要形式的設置。


看起來我不是唯一一個遇到過這種情況的人。 請參閱: 資源調優器:版本歷史似乎是一個Delphi應用程序,在版本1.99下它指出:“修正:切換到另一個應用程序時,(搜索)對話框預覽窗口保持在頂部。” 我可能會嘗試聯系他們,看看他們是否記得他們的修復方法。


我在表單中添加了一些新的對話框,並將這些調用放在一個地方:

FindDialog1.Execute();
PrintDialog1.Execute();
ReplaceDialog1.Execute();
FontDialog1.Execute();

FindDialog和ReplaceDialog保持在其他窗口的頂部。 PrintDialog和FontDialog不會保持最佳狀態並且可以正常工作。

那么兩組對話框之間的區別是什么讓前兩個對話框出錯?


此外,這個問題發生在我的程序的舊版本,使用Delphi 4編譯 。哎呀。 現在我發現在我使用Delphi 4的舊版本中沒有發生這個問題。

並且是用戶報告了這個問題。 他使用的是Windows XP,而我正在開發Vista,所以它發生在不同的操作系統下。


確認:是的,我創建了一個新表單並在其上添加了FindDialog。 FindDialog沒有問題。 這表明我的程序中的某些東西導致FindDialog保持在最頂層。 現在,我必須找出那是什么。 還有什么想法嗎? 如果有人給我一個答案,甚至給我一個幫助我解決這個問題的線索,那么他們將得到接受的答案。


解決方案:Sertac對他的回答的編輯給了我解決方法:

  Application.NormalizeTopMosts;
  FindDialog.Execute();
  Application.RestoreTopMosts;

這樣做可以防止FindDialog在應用程序不是TopMost時成為TopMost。

...但我仍然真的不理解這一點(Delphi幫助NormalizeTopMosts)非常混亂,並沒有表明它應該這樣做。

希望這個“修復”不會引起其他問題。

查看VCL代碼,查找對話框保持最佳狀態的唯一可能方式是,在調用“執行”時,已經存在最頂層的窗口。 這是它的編碼方式,對話框由'TRedirectorWindow'擁有,后者在應用程序中以z順序由頂部窗口擁有。 如果這個“頂部窗口”是最頂層的窗口,那么查找對話框也是。

procedure TForm1.Button1Click(Sender: TObject);
var
  f: TForm;
begin
  f := TForm.CreateNew(Self);
  f.FormStyle := fsStayOnTop;
  f.Show;
  FindDialog1.Execute;
end;

要么,

procedure TForm1.Button1Click(Sender: TObject);
begin
  FormStyle := fsStayOnTop;
  FindDialog1.Execute;
  FormStyle := fsNormal;
end;


上面的示例將創建一個最頂層的查找對話框。 但是一個保持頂級的形式可能不會被忽視,所以我想這不會是你的問題的根源。

在任何情況下,它或者你是以某種方式通過其他代碼片段改變對話框上的樣式。


順便說一句,不要費心測試將各種句柄傳遞給FindDialog1.Execute() ,它不會有效果,請看我對你的問題的評論。

編輯:

這個怎么樣:

procedure TForm1.Button4Click(Sender: TObject);
var
  f: TForm;
begin
  f := TForm.CreateNew(Self);
  f.FormStyle := fsStayOnTop;
  f.Show;
  f.Hide;
  FindDialog1.Execute;
end;

關鍵是, EnumThreadWindows枚舉的窗口不一定是可見的。 因此,任何現有的stay-on-top表單都可能導致查找對話框顯示此行為。

更好的測試和看到比猜測。 在啟動“查找”對話框之前運行以下測試。 這包含邏輯'dialogs.pas'執行以查找對話框作為基礎,並且如果對話框將最頂層,則會引發異常。

function EnumThreadWndProc(hwnd: HWND; var lParam: LPARAM): Bool; stdcall;
var
  Window: TWinControl;
begin
  Result := True;
  Window := FindControl(hwnd);
  if Assigned(Window) and (Window is TForm) then begin
    Result := False;
    lParam := Longint(Window);
  end;
end;

procedure TForm1.Button6Click(Sender: TObject);
var
  OnTopForm: Longint;
begin
  OnTopForm := 0;
  EnumThreadWindows(GetCurrentThreadId, @EnumThreadWndProc, LPARAM(@OnTopForm));
//  if (OnTopForm <> 0) and (TForm(OnTopForm).FormStyle = fsStayOnTop) then
  if (OnTopForm <> 0) and (GetWindowLong(TForm(OnTopForm).Handle,
                            GWL_EXSTYLE) and WS_EX_TOPMOST = WS_EX_TOPMOST) then
    raise Exception.Create('darn! got one: ' + TForm(OnTopForm).Name);
end;


另一個測試可能是在啟動對話框之前調用應用程序的NormalizeTopMosts ,但我知道在某些Delphi版本中,這種方法已被破壞而且無法正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM