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

一个人想着一个人 提交于 2019-12-04 07:36:09

Looking at the VCL code, the only possible way a Find Dialog Box stays on top is, there's already a top-most window when 'Execute' is called. This is how it is coded, the dialog gets owned by a 'TRedirectorWindow' which gets owned by the top window in z-order in the application. If this 'top window' is a top-most window then the find dialog also is.

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

or,

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


The above samples will create a top-most find dialog. But a stay-on-top form possibly wouldn't go unnoticed, so I guess this wouldn't be the source of your problem.

In any case, it is either that or you're somehow changing the styles on the dialog by some other code piece.


BTW, do not bother testing passing various handles to FindDialog1.Execute(), it won't have an effect, see my comment to your question.

edit:

How about this one:

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

The point is, a window does not have to be visible to get enumerated by EnumThreadWindows. So any existing stay-on-top form could cause the find dialog to exhibit this behavior.

Better test and see than to guess. Run the below test just before you launch your Find Dialog. This incorporates the logic 'dialogs.pas' performs to find the dialog a base, and would raise an exception if the dialog would go top-most.

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;


One other test could be to call NormalizeTopMosts of the Application before launching the dialog, but I know with some Delphi versions this method is broken and does not do its job.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!