2

The application I am now trying to support (a former creation of mine) is a complete mess, and so I programmed an extension to it as a separate executable which I then launch, call application.minimize; and WaitForSingleObject (the recently created process). Right after that I call application.restore to get me back to where I left off.

application.Minimize;
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
Application.Restore;
Application.BringToFront;
BringToFront; //the topmost form which was used to launch the app
Show;

I can then see (Win XP), how to describe it?, the frame of the app jump up from the task bar and do as if the app was restoring itself to screen but it does not actually show. As you can see, I am quite desperate and combined app.restore, app.bringtofront,form.bringtofront,form.show... but I think I need some sort of application.show, activate, focus... can't seem to find those.

Also, why is this not enough?

application.Minimize;
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
Application.Restore;

EDIT

The main form is wsMaximized, this calls anotherform.showmodal; which then eventually tries to minimize the app, launch the other process, and restore the app. I think the trick is with the MODALity of the topmost form.

sample code for the other (topmost) form that is shown as modal:

function ExecAndWait(const FileName, Params: string;
  WindowState: Word): Boolean;
var
  SUInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CmdLine: string;
begin
  { Enclose filename in quotes to take care of
    long filenames with spaces. }
  CmdLine := '"' + FileName + '" ' + Params;
  FillChar(SUInfo, SizeOf(SUInfo), #0);
  with SUInfo do
  begin
    cb := SizeOf(SUInfo);
    dwFlags := STARTF_USESHOWWINDOW;
    wShowWindow := WindowState;
  end;
  Result := CreateProcess(nil, PChar(CmdLine), nil, nil, False,
    CREATE_NEW_CONSOLE or
    NORMAL_PRIORITY_CLASS, nil,
    PChar(ExtractFilePath(FileName)),
    SUInfo, ProcInfo);
  { Wait for it to finish. }
  if Result then
  begin
    application.Minimize;
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
    Application.Restore;
    Application.BringToFront;
  end;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  ExecAndWait('C:\Windows\system32\mspaint.exe' , '' , SW_NORMAL);
end;
Community
  • 1
  • 1
Peter Perháč
  • 20,434
  • 21
  • 120
  • 152
  • Just minimize followed by restore works for me. Have you tried Application.ProcessMessages? – Lieven Keersmaekers Jan 29 '10 at 13:46
  • And you have no way to debug? – Lieven Keersmaekers Jan 29 '10 at 13:49
  • Well, the debugger kind of makes it even harder. If I placed a breakpoint there, Delphi would activate itself exactly in the place where I would desire my app to activate. Debugger gets in the way. I am trying running the app without debugger and just trying to find the right command that would actually display the application once it's been restored. – Peter Perháč Jan 29 '10 at 13:54
  • 1
    Can you reproduce this in a tiny app and post the code here? – Jeroen Wiert Pluimers Jan 29 '10 at 13:56
  • @Jeroen, I tried and I could reproduce this quite easily. New VCL Forms app, button on the form. New form. button on form1 calls form2.showmodal. Button on form2, this button then calls app.minimize, creates process, app.restore and it doesn't work. Code for form2 is in the question. – Peter Perháč Jan 29 '10 at 14:05
  • @MasterPeter - I can't reproduce this on WinXp with Delphi5. The mspaint is in Winnt folder. The Application.Minimize doesn't get run until mspaint is closed. If I first minimize the application, then create mspaint, close and restore it, the only "fluke" is see on my second monitor is that the application doesn't minimize at all. – Lieven Keersmaekers Jan 29 '10 at 14:26
  • 1
    Perhaps you're bitten by Windows Ghosting as here http://social.msdn.microsoft.com/Forums/en-US/windowsuidevelopment/thread/4cc0426d-571e-4dc2-b51d-7700890fefaf and here http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_23358991.html – Lieven Keersmaekers Jan 29 '10 at 14:30

1 Answers1

6

ShowModal causes all the forms of the application to be disabled, except the modal form. You cannot minimize, restore a disabled window at will. Try sth. like;

  if Result then
  begin
    EnableWindow(Application.MainForm.Handle, True);
    application.Minimize;
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
    Application.Restore;
    EnableWindow(Application.MainForm.Handle, False);
    Application.BringToFront;
  end;
Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
  • thanks for an answer, there were too many comments piling up below the question. I'll try this now. – Peter Perháč Jan 29 '10 at 14:42
  • superb! This did the trick! I didn't know that "ShowModal causes all the forms of the application to be disabled". This is a pretty useful insight. ta – Peter Perháč Jan 29 '10 at 14:44
  • You're welcome! To prevent a misunderstanding, rather than a cause, ShowModal disables the forms (by calling DisableTaskWindows). Anyway, what is being done here is somewhat against the TApplication design, so you'd be watching for anomaly, for instance if there are more forms. – Sertac Akyuz Jan 29 '10 at 15:33