Solved

Closing a showmodal myself

Posted on 1997-11-20
20
671 Views
Last Modified: 2010-04-04
I want to show a form like a showmodal but close it myself and not have the user close it. I have experimneted with setting ModalResult myself to no avail. Once you do a ShowModal I can't get it to not wait for the user to respond. How can I achieve this?

Thanks, Tom.
0
Comment
Question by:tomcorcoran
  • 10
  • 8
  • 2
20 Comments
 
LVL 8

Expert Comment

by:ZifNab
ID: 1351118
Why don't you just use the Close?
0
 

Author Comment

by:tomcorcoran
ID: 1351119
Thanks for your replies. I guess I am not expressing myself very well as you are asking what seem 'obvious' quetions to me. If you do a ShowModal the next line of code won't be run until after the form is closed so how do you call close?
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1351120
Is this what you want?

 button click on form 1 ->
 starts timer -> end timer -> close form2

Timer1.Enabled has to be false (design)

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
 Form2.ShowModal;
end;

end.


unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls;

type
  TForm2 = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.DFM}

procedure TForm2.Timer1Timer(Sender: TObject);
begin
 showmessage('time up, close form2');
 timer1.Enabled := false;
 Form2.close;
end;

procedure TForm2.FormActivate(Sender: TObject);
begin
 showmessage('Begin Timer');
 Timer1.Enabled := true;
end;

end.

0
 

Author Comment

by:tomcorcoran
ID: 1351121
So you are using a timer to show the form for a specified time. Precisely whay I want is I am updating tables and show a progress meter on a form showing the progress. Right now this form is how so I can close it when the processing is finished. However, this means that the suer can click on the main form in the background, which I don't want. Thanks, Tom.
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1351122
I don't get it. If you put form2.close at the end of the progress everything will work fine. Just what you want, isn't this? If not, please explain me more briefly what you want.
0
 

Author Comment

by:tomcorcoran
ID: 1351123
Zifnab,

Maybe I am going crazy (wouldn't be the first time), let me do some testing and I will get back to you. Also, i just tried installing the TLinkLabel component and it says file not found windows.dcu. I'm running D1. Any ideas?

Thanks.

Tom.


0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1351124
Maybe it's this :
Windows was in earlier versions of delphi WinTypes and Winprocs. So change windows (uses list) in WinTypes and Winprocs and hopefully that works.
0
 

Author Comment

by:tomcorcoran
ID: 1351125
As regards Closing, it is as I thought:

procedure TfrmOrgTime.PackTables;
var
   wTbl: TwwTable;
   i: integer;
   frmGauge: TfrmGauge;

   procedure DoPack;
   var
      returnMsg, fileName: string;
   begin
      if not CheckBtnClicked(frmGauge.btnCancel) then begin
         fileName := Concat(wTbl.DatabaseName, wTbl.TableName, dbExt);
         if FileExists(fileName) then begin
            frmGauge.SetPackLbl(fileName);
            { sets returnMsg }
            if not wTbl.Pack(returnMsg) then
               MsgError(Format('Packing of table ''%s'' failed with ' +
                               'message: %s', [fileName, returnMsg]));
            Application.ProcessMessages;
         end;
      end;
   end;
begin
   wTbl := TwwTable.Create(Self);
   try
      frmGauge := TFrmGauge.Create(Self, 'Packing Tables');
{      frmGauge.ShowModal;}
      frmGauge.Show;
      Application.ProcessMessages;

      { pack company specific tables }
      SetupTable(wTbl, '', unDict.GetCompPath);
      for i := Low(compTbls) to High(compTbls) do begin
         wTbl.TableName := compTbls[i].tbl;
         DoPack;
      end;

      { pack system specific tables }
      SetupTable(wTbl, '', unDict.GetPath);
      for i := Low(sysTbls) to High(sysTbls) do begin
         wTbl.TableName := sysTbls[i].tbl;
         DoPack;
      end;
   finally
      wTbl.Free;
      {frmGauge.Close;}
      frmGauge.Free;
   end;
end;

If I include the frmGauge.ShowModal; then it will never get to the nest line Application.ProcessMessages; untile the user closes the other form.

The WinType, WinProcs substitution worked. Now I have a problem with:

procedure TLinkLabel.WMClick(var Msg:TMessage);
begin
   ShellExecute(GetDesktopWindow,'open',PChar(FLinkTo),nil,nil,
   SW_SHOWNORMAL);
end;

It gives an invalid typecast on PChar(FLickTo). I'lll look into it.

Thanks,

Tom.
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1351126
Why don't you put you gauge process in TFrmGauge? And apply your ProcessMessages from there?
This is a stupid solution, but I think it can work also. Put everything on TFrmOrgTime on a Panel and then if TFrmGauge is activated change the Panel.Enabled property to false.
0
 

Author Comment

by:tomcorcoran
ID: 1351127
Put gauge process in tfrmgauge? That's where it is isn't it? Putting the progress meter on tfrmOrgTime is not an option. Thanks, Tom.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 8

Expert Comment

by:ZifNab
ID: 1351128
What if you put Application.ProcessMessages in the TFrmGauge.Activate method?
0
 

Author Comment

by:tomcorcoran
ID: 1351129
I just tried it, but it makes no difference, like I said nothing will hapen until the showmodal is processed. Form the on-line help <<The ShowModal method makes a form the active form, just like Show, but also makes the form modal; therefore the user must put the form away before the application can continue to run.>>

Tom.

0
 
LVL 3

Expert Comment

by:Pegasus100397
ID: 1351130
Tom,

I'm confused as to why so many answers and comments, yet this problem (should be easy) is not "solved" yet. I have a form that displays progress, just like yours. When the progress bar (and a % complete label) indicates 100% then I simply close the form.

For example, from Form1:

Application.CreateForm(TfrmShowProgress, frmShowProgress);
frmShowProgress.ShowModal;
other lines <----- this does NOT execute until the frmShowProgress form completes it's stuff

In frmProgress in the OnActivate Event I do my processing, displaying merrily along, updating the progress bar, etc. When all my code and processing is complete then I issue

frmShowProgress.Close;

and this closes the progress form and the code picks up where it left off in form one.

(Note that in my OnClose event for frmShowProgress I have the action defined as Action := caFree to release it's instance, not relevent to your question, but good practice :)

Anyways, hope this helps & good luck with your project!
Pegasus
0
 

Author Comment

by:tomcorcoran
ID: 1351131
I would like to be able to grade but keep a question open, but it doesn't seem possible. Your solution would work Pegasus, however I use the frmgauge many time for other progress reporting and would like to keep the processing out of that unit. I know I coukd assign differnt OnActivates in constructors but like I said I don't want to do the processing in that unit. Thnks for your reply. Tom.
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1351132
Yes, Pegasus, exactly what I wanted to explain in my second last comment (why don't you put gauge process in TfrmGauge). But I must admit, this is much better explained. Hope this question is solved now.
0
 

Author Comment

by:tomcorcoran
ID: 1351133
Well, like I said it's a solution but not one I want. I'm looking for a way to force a form to show like a shoemodla but still allow processing. Thanks, Tom.

0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1351134
Hey, what about just hiding TfrmOrgTime?
0
 

Author Comment

by:tomcorcoran
ID: 1351135
Zifnab, not an option, I have thought of stuff like this. I know precisely waht needs to be done <<I'm looking for a way to force a form to show like a shoemodla but still allow processing>>, it's just a question of if it's possible, it doesn't look like it. Maybe other experts have feedback? Thanks a lot, Tom.
0
 
LVL 3

Accepted Solution

by:
Pegasus100397 earned 50 total points
ID: 1351136
Okay, okay, then let's toss a variation on the same theme out there. Basicly your trying to control frmGauges "action" and making it appear modal while keeping the main form out of "reach" of the user right? Let's hack a little :)

from Form1:

Application.CreateForm(TfrmGauge, frmGauge);
frmMain.Enabled := False;
frmfrmGauge.Show;   {NON-Modal, but appears so because form1 is "disabled" }
. . .
processing done here like:
frmGauge.ProgressMeter1.Position := blah blah
. . .
frmGauge.Close;
frmMain.Enabled := True;

This will make it appear as if the progress form is Modal because the "calling" forms Enabled property has been set to false (not hidden, just disabled) but meanwhile the code still executes.

I'll be interested to see the solution to this one, sounds like a different approach should be considered :P Seeya!
Pegasus
0
 

Author Comment

by:tomcorcoran
ID: 1351137
Superb lateral thinking dude. Thanks a lot, Tom.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now