Solved

Detecting Signal/System Messages in Windows and Linux

Posted on 2003-10-31
10
240 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
 
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
my activex application give System Error.  Code: 5.  Access is denied 16 113
delphi prevent click fast 2 189
LAN or WAN ? 11 81
Press three keys together and trigger a function 3 50
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

911 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

20 Experts available now in Live!

Get 1:1 Help Now