Solved

Detecting Signal/System Messages in Windows and Linux

Posted on 2003-10-31
10
242 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
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 34

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 34

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 34

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

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Making delphi communicate with a c# service 16 111
Firemonkey DbLookupComboBox equivalent ? 2 55
Graphics32 under Delphi 10.1 Berlin 2 99
Multi-layered image in FireMonkey 9 48
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
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…

856 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