Solved

Detecting Windows shutdown

Posted on 2000-03-04
10
599 Views
Last Modified: 2010-04-04
Hi!

On Windows shutdown I'd like to terminate an Delphi application which has opened an MS-DOS Window. How can I detect the Windows shutdown, and how can i unconditionally close the MS-DOS window?

Thanx
0
Comment
Question by:janez
10 Comments
 
LVL 1

Expert Comment

by:XAN
ID: 2582944
The system sends the WM_QUERYENDSESSION message to each window. So you can hook it and do what do you want ;)
If you know handle to the process you need terminate, you can use the next
BOOL TerminateProcess(
  HANDLE hProcess, // handle to the process
  UINT uExitCode   // exit code for the process
);
0
 

Author Comment

by:janez
ID: 2583534
Hi XAN!

Since I'm almost a beginner in Delphi, could you please tell me how to use these handles to terminate a process(application). I would be very grateful to you.
By the way...Is the procedure to close an MS-DOS window the same as the one to close an windows application and if not do you maybe know how does it look like?

Thanx
0
 
LVL 17

Expert Comment

by:inthe
ID: 2583853
Hi
this is example of terminate process.
nte you need to know the window handle of the dos window (or its caption instead as in this example)

procedure TForm1.Button2Click(Sender: TObject);
var
ProcessID,cpid : Cardinal;
h : thandle;
//h := findwindow('some dos box handle',nil);
//or
h := findwindow(nil,'some dos box caption');
begin
ProcessID := GetWindowThreadProcessID(h,@cpid);
TerminateProcess(OpenProcess(PROCESS_TERMINATE,false,cpid),1);
end;


do you need example of wm_query..?
i am unsure if your application is of type console or type forms/windows
do you start the dos program from a normal delphi app?

console apps do not get or use wm_query... they use CTRL_SHUTDOWN_EVENT instead so if your app is a console app that is the function you need example for..
Regards Barry
0
 

Author Comment

by:janez
ID: 2583946
Hi inthe!

Well, my delphi application has some forms, but a dos program also starts from it. So i guess it's a kind of mix between the two types. I would be very grateful to you, if you could give me an example of how to detect the windows shutdown (now even more because you said that there are different types of messages).

Thanx
0
 
LVL 17

Expert Comment

by:inthe
ID: 2583964
Hi Janez,
oh good im glad you have forms :o) so you can use normal windows wm_query.. message for shutdown.
ok here demo ,note the global boolean "ok_to_close " ,you can probably skip using it, but its handy to have this extra functionality .when we get the query message we check state of boolean and if true then we can let windows shutdown ,else we can stop windows from shuting down by setting it too false;
by the sound of your app i would set ok_to_close to true on form create then when you execute the dos box set ok_to_close to false.when the query message is recieved and you have checke k_to_clsoe state if its false then means dos box is running so you do your terminateprocess stuff then let window continue shuttong down..
ive commented out a couple of lines that i normally use and added where roughly your code would go to check and close dos window:

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
   procedure WMQueryEndSession(var Msg: TWMQueryEndSession) ; message WM_QUERYENDSESSION ;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  ok_to_close : boolean;

implementation

{$R *.DFM}

procedure TForm1.WMQueryEndSession(var Msg: TWMQueryEndSession);
const
  CAN_SHUTDOWN = 0 ;
  DONT_SHUTDOWN = 1 ;
begin
  inherited ;
  if ok_to_close then {ok_to_close is the global boolean}
  Msg.Result := CAN_SHUTDOWN
  else
 begin
  // terminate dos window code then;
  Msg.Result := CAN_SHUTDOWN;
 end;
//else
//  Msg.Result := DONT_SHUTDOWN ;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ok_to_close := true;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
//execute the dos window;
ok_to_close := false;
end;

Regards Barry
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 17

Expert Comment

by:inthe
ID: 2583980
mmm.. i have idea that may be better for closing dos box
 (note it is untested but i am confident it may work)

add another global var and use this function to
start the dos process keeping the handle of this
 process in var h
then can try closing using sendmessage instead of
 terminate process..


var
tform1 : tform;
h : thandle;

implementation

function CreateDosProcess(filename : string ): string;
  var
   p : TProcessInformation;
   s : TStartupInfo;
 begin
   FillMemory( @s, sizeof(s), 0 );
   s.cb := sizeof(s);
    CreateProcess(Nil,PChar(filename ),
                  Nil,Nil,False,NORMAL_PRIORITY_CLASS,
                  Nil,Nil,s,p);
  h := p.hProcess;
  end;


now on formclose event and in wmquery.. message handler if
 ok_to_close = false do:

SendMessage(h,WM_DESTROY,0,0);
// or WM_CLOSE or even WM_QUIT be better
CloseHandle( p.hProcess ); //close handles to clean up
CloseHandle( p.hThread ); // and again..


id be interested in wether this works or not,so let me know results if you do test it.
cheers Barry ;-)
0
 
LVL 2

Expert Comment

by:craig_capel
ID: 2584017
hmm, confident?... understatement, if he ever answers any of mine questions, i dont even bother (anymore) testing his code, hes a true expert.... :)

well his code looks good..... god i am bored today

Craig C. (not to mentiom the 1 1/2 liters of wine i have had to drink)
0
 

Author Comment

by:janez
ID: 2584879
Hi inthe!

Your code works fine. I used the first procedure you gave me and the WMQueryEndSession procedure...it worked ok. I have also quickly tried your second method for closing a ms-dos window, but it didn't work. Maybe i've done something wrong. Anyway, would you like that i evaluate your answer?

Thanx a lot
0
 
LVL 17

Accepted Solution

by:
inthe earned 50 total points
ID: 2585116
cheers ;-)

shame about the second method i was sure it might work but it was untested ..maybe i test it more when fre time allows :o)
0
 
LVL 17

Expert Comment

by:inthe
ID: 2585117
ps
craig stop drinking it bad for your heath .. hic ..
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

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…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

746 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

12 Experts available now in Live!

Get 1:1 Help Now