Solved

Detecting Signal/System Messages in Windows and Linux

Posted on 2003-10-31
10
241 Views
Last Modified: 2010-04-05
I'm writing a console app which will be run in both windows and linux environment. I have now run in to a slight problem.

When I close the application the destructors of some objects are not called. So alot of data is just left in the memory.

The console app looks something like this:

begin
   dmMain := TdmMain.Create(nil);
   try
         dmMain.Run;
   finally
      dmMain.Destroy;
   end;
end.

The run method is just a dummy which contains a loop so that the application doesnt exit.

Would it be possible to listen for system signals to the program... and when the program recieves kill signals or the user closes the console window or presses control-c?

I would be greatful if someone had two code examples of this... one for windows and one for linux.

Thank you!
0
Comment
Question by:svenneman
10 Comments
 
LVL 17

Accepted Solution

by:
geobul earned 84 total points
ID: 9661432
Console applications do not receive messages from Windows. They are not event driven apps and have no message loop.

dmMain.Free; is the correct statement. (what is dmMain btw?. It isn't a form, is it?)

Regards, Geo
0
 
LVL 5

Assisted Solution

by:DeerBear
DeerBear earned 83 total points
ID: 9661676
Hi,

As nicely stated above, console applications don't receive Windows
messages. BUT:

You can AllocateWnd so that *you* can receive messages <g>.

Try that out!

HTH,

Andrew
0
 

Author Comment

by:svenneman
ID: 9662472
dmMain is a DataModule...

AllocateWnd isnt a delphi function from what I can see... it doesnt show up in the delphi help...

can you give me a code example.


and I would need something that listen for signals on linux aswell
0
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 
LVL 33

Assisted Solution

by:Slick812
Slick812 earned 83 total points
ID: 9665024
hello svenneman, , not sure what you are asking for, some have already said that a console app is NOT in the windows message comunications, and even if you create anothe window and get it in the message comunication, it will not get any event "Messages" that the system is using for the console window (like when the user ckicks the X caption "Close" button)
I will also say that this referes to the "Windows" system and I do NOT have any knowledge of the Linix API. .  
Since the .DPR Program code page does NOT have a finalization clause, I have had to use of a couple of of alternatives, first there is the

ExitProc

which you can set in the DPR file to have code processed before the process is terminated

var
PExitSave: Pointer;

procedure MyExit;
begin
  ExitProc := PExitSave;  // restore old proc first
// do and memory freeing or object release here
end;

begin //  *  *  *  *  *  *  * Main Program begin
PExitSave := ExitProc;
ExitProc := @MyExit;
//other code here
end;

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

if you have the SysUtils in your uses clause then you might try the

procedure AddTerminateProc(TermProc: TTerminateProc);

to add a Procedure to the list of procedures called at termination
0
 

Author Comment

by:svenneman
ID: 9665277
will try that
0
 

Author Comment

by:svenneman
ID: 9672453
none of the above suggestions worked in an console app I'm afraid =(
0
 
LVL 33

Expert Comment

by:Slick812
ID: 9683800
I tried some things, and it seems that with a console app, if the user clicks the  X  caption Close button, you will get that standard "Lose Information" Yes, No, Dialog box, and if the user clicks Yes button, the console process is Terminated, without anything  furthur being done, or any message or event or warning to the console process. . . Here is some code that I at least got a warning if the Ctrl-Break or Ctrl-C  keys were pressed, which closes a Console App , , with the
SetConsoleCtrlHandler(@HandlerFunc, True);


program EventCondsole;
{$APPTYPE CONSOLE}

uses Windows, SysUtils;

var
ConStr, CommandStr: String;
hStdOut, i: Integer;
ScreenBufInfo: TConsoleScreenBufferInfo;
Cord1: TCoord;

procedure FreeAndRelease;
begin
// I do not have anything that needs to be Freed, so I do a MessageBeep
WriteLn('FreeAndRelease');
MessageBeep(MB_ICONERROR);
end;

function HandlerFunc(CtrlType: Cardinal): Bool; stdcall;
begin
{This function should be called for any of the "Events" listed
If you set the Result to "True" then it should NOT Close}
Result := False;
case CtrlType of
  CTRL_C_EVENT: begin
    MessageBeep(MB_ICONQUESTION);
    // a True will keep it from closing on a Ctrl-C key press
    Result := True;
    end;
  CTRL_CLOSE_EVENT: FreeAndRelease;
  CTRL_BREAK_EVENT: begin
    FreeAndRelease;
    WriteLn('I''m Gone');
    end;
  CTRL_LOGOFF_EVENT: FreeAndRelease;
  CTRL_SHUTDOWN_EVENT: FreeAndRelease;
  end;
end;

procedure CStrCount(Str1: String);
begin
WriteLn('Character Count is '+IntToStr(Length(Str1)));
end;


begin // / / MAIN BEGIN / /
hStdOut := GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTitle('The Command Console');
SetConsoleCtrlHandler(@HandlerFunc, True);
WriteLn('Hello to you');
WriteLn(' ');
WriteLn('Commands for this are "quit", "exit", "Clear", "Count" and "Repeat"');
WriteLn('Type in the command "quit"  or "exit" to exit this program.');
WriteLn('Type in the command "Clear" to Clear the text from this console');
WriteLn('Type in "Count" and then a space, and then the charaters you want to count');
WriteLn('Type in "Repeat" and then a space, and the charaters you want to be displayed');

while True do
  begin
  ReadLn(ConStr);
  if (LowerCase(ConStr) = 'quit') or
    (LowerCase(ConStr) = 'exit') then Break;
  CommandStr := Copy(ConStr,1,6);
  CommandStr := LowerCase(CommandStr);
  if CommandStr = 'repeat' then
    begin
    CommandStr := Copy(ConStr,8,512);
    WriteLn(CommandStr);
    Continue;
    end;

  Delete(CommandStr,6, 1);
  if CommandStr = 'count' then
    begin
    CommandStr := Copy(ConStr,7,512);
    CStrCount(CommandStr);
    end else
  if CommandStr = 'clear' then
    begin
    GetConsoleScreenBufferInfo(hStdOut, ScreenBufInfo);
    for i := 0 to ScreenBufInfo.dwSize.Y do
    WriteLn('');
    Cord1.X := 0;
    Cord1.Y := 0;
    SetConsoleCursorPosition (hStdOut, Cord1);
    WriteLn('Commands for this are "quit", "exit", "Clear", "Count" and "Repeat"');
    end else
    WriteLn('Command is NOT recognized');
  end;
MessageBeep(MB_ICONERROR);
end.

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

Like you said, even the ExitProc is NOT called if the X close button is used
you might consider a
while True do
loop

to at least let your user have the option of exiting you program
0
 
LVL 33

Expert Comment

by:Slick812
ID: 9683806
I am not sure that console Apps were meant to have any memory objects that need to be freeded, like Fonts, brushes or bitmaps, so you may need to use a GUI interface
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
delphi exception 7 64
indy Tmemory stream non latin charcter issue 2 110
Delphi - replicating a form 8 74
Controlled Assessment GCSE - desperate help needed 4 84
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…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

770 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