Solved

Detecting Signal/System Messages in Windows and Linux

Posted on 2003-10-31
10
239 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
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

 

Author Comment

by:svenneman
Comment Utility
will try that
0
 

Author Comment

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

Expert Comment

by:Slick812
Comment Utility
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
Comment Utility
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

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
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…
This video discusses moving either the default database or any database to a new volume.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

763 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

13 Experts available now in Live!

Get 1:1 Help Now