Link to home
Start Free TrialLog in
Avatar of PaulP
PaulPFlag for Canada

asked on

OpenDialog on top


I have an application with multiple forms that need to stay on top
Using help from otehrs here I got it to work...
See this thread ... https://www.experts-exchange.com/questions/21274097/Stay-On-Top-application-with-multiple-forms.html

But now I discovered a problem and can't find a solution

If I have a form that use
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited;
  with Params do begin
     ExStyle := ExStyle or WS_EX_TOPMOST;
    WndParent := GetDesktopwindow;
  end;
end;

and I open a Dialog such as TOpenDialog , the first time it works well and show on top, but if I close the dialog and re-open it, then it show under the other form...

I've try to do this but it won't help

procedure TForm1r.OpenDialog1Show(Sender: TObject);
begin
      SetWindowPos(OpenDialog1.handle,HWND_TOPMOST, 0,0,0,0, SWP_NOSIZE or SWP_NOMOVE);
End;

Thanks for your help!
Avatar of geobul
geobul

Hi,

Try this way:

    with Application do begin
         NormalizeTopMosts; // or NormalizeAllTopMosts;
         // your code for opening the dialog here
         if OpenDialog1.Execute then begin
           ...
         end;
         RestoreTopMosts;
      end;

Regards, Geo
Avatar of PaulP

ASKER

Humm that doesn't work... in factm now the dialog alwasy show at the back even on the first time....

It  seems that this
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited;
  with Params do begin
     ExStyle := ExStyle or WS_EX_TOPMOST;
    WndParent := GetDesktopwindow;
  end;
end;

Solve one main issue I had, but cause some other issue...

ASKER CERTIFIED SOLUTION
Avatar of Member_2_248744
Member_2_248744
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of PaulP

ASKER

Hello Slick!

Thanks for this Open/Save dialog code... workls well!

But I need an example on how to use the MultiSelect...

I'm not sure on the best method to extract the filename... from the MultiResult.fname

Thanks!
OK, the OpenMultiSel( ) function returns a TMultiResult, with a #0 delimited text string in  fNames, and the fOffSet will have the offset to the first file name,. You will need to transverse through all the file names and extract them, using PChar methods is the best way I think, as in this code -

procedure DoMultiFile;
var
MultiRe: TMultiResult;
filePath: String;
pFileName: PChar;
begin
{the OpenMultiSel function uses a Multi-Selection dialog, the Result
 string is different than a normal open dialog, it has null #0 delimited
 file path and names}
MultiRe := OpenMultiSel(hForm1, 'C:\Stuff', 'Text files  .TXT'#0'*.txt'+
              #0'All files'#0'*.*'#0#0,'Open more than One File, Multi-Select');
{a TMultiResult is the result form a OpenMultiSel, the fOffSet will be
 -1 if it fails, or the File-Name charater offset if it succeeds}
if MultiRe.fOffSet <> -1 then
  begin
  // I list the file name in the hListBox1 List Box
  SendMessage(hListBox1, LB_RESETCONTENT, Zero, Zero);
  SetString(filePath, PChar(MultiRe.fNames), MultiRe.fOffSet-1);
  { the Folder path is in the first section of the MultiRe.fNames
   MultiRe.fNames is several #0 delimited only if more than one file
   I use SetString( ) with the MultiRe.fOffSet-1 number to know it's length

   if there is only ONE file name, the result string will not have #0
   delimters, I test for the #0 delimter at MultiRe.fOffSet}
  if MultiRe.fNames[MultiRe.fOffSet] <> #0 then // true if single file name
    begin
    SendMessage(hListBox1, LB_ADDSTRING, Zero,
                Integer(@MultiRe.fNames[MultiRe.fOffSet+1]));
    // the list box will add single string above using the file name offset
    end else
    begin
    pFileName := StrEnd(PChar(MultiRe.fNames));
    // StrEnd will get the #0 delimiter
    Inc(pFileName); // move to character after #0
    while pFileName^ <> #0 do // loop until there are two #0
      begin
      // add #0 terminated file name to list box
      SendMessage(hListBox1, LB_ADDSTRING, Zero, Integer(pFileName));
      pFileName := StrEnd(pFileName);
      Inc(pFileName);
      end;
    end;
  end else filePath := 'User Canceled or Error'; // MultiRe.fOffSet = -1
end;


 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

if you need to use delphi methods, you can change

 SendMessage(hListBox1, LB_ADDSTRING, Zero, Integer(pFileName));

to ( using a TStringList as StringList1)

StringList1.Add(pFileName);
for the  OpenDlgOpt( ) function -


var
DlgSetUp1: TDlgSetUp;

with DlgSetUp1 do
  begin
  hOwner := Form23.Handle;
  iniDirPath := 'C:\Stuff';
  iniFileName := 'NewFile1.txt';
  Filter := 'Text files  .TXT'#0'*.txt'#0'New Text files,+
            ' NewFile.TXT'#0'NewFile?.txt;NewFile??.txt'#0+
            'All files'#0'*.*'#0#0;
  Title := 'Save Something Else';
  DefExt := '.txt';
  Options := [doSave,doPathExist,doOverWrite,doCusFilter];
  end;
fName := OpenDlgOpt(DlgSetUp1, 2);
if fName <> '' then
  Showmessage(fName);