Solved

Detecting Windows shutdown

Posted on 2000-03-04
10
612 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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
 
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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Unique identifier on a terminal server (rdp) 4 74
how can i search if string exist in array ? 3 69
DBGrid or StringGrid ? 6 120
Broadcast a message using ICS 2 23
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

749 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