Newsgroups : Borland : borland.public.delphi.nativeapi.win32 : 2007 Feb : Blocking calls and system shutdown

www.cryer.info
Managed Newsgroup Archive

Blocking calls and system shutdown

Subject:Blocking calls and system shutdown
Posted by:"Rabusier" (nomail@nospam.com)
Date:14 Feb 2007 12:43:16

Hi,

I'm wondering how a non console app without any window could handle messages while the main thread performs blocking calls. I've a Delphi application (it consists of a single DPR file and don't use Forms.pas) which creates a named pipe and wait for external connections by calling ConnectNamedPipe(). I pass PIPE_WAIT to CreateNamedPipe() so all pipe operations are blocking. The problem I have is that under XP (not Vista, don't know why), on Windows shutdown, as ConnectNamedPipe() does not return the application hangs and prevent the shutdown. I suppose I can use overlapped I/O by using the LPOVERLAPPED parameter, but as I'm not used to use Windows asynchronous API calling concept I searched another simple way to close the app. My first thought was to use SetConsoleCtrlHandler()
in order to handle CTRL_LOGOFF_EVENT and CTRL_SHUTDOWN_EVENT (and just call ExitProcess()), but it seems that the handler is never fired. Quite logic, since my application is not a console app, after all. So I tried to create my own message pump in a separate thread in order to close my app when the WM_QUERYENDSESSION message is received :

var
  BlCatchMessageForm: TWndClass = (
    style: 0;
    lpfnWndProc: @DefWindowProc;
    cbClsExtra: 0;
    cbWndExtra: 0;
    hInstance: 0;
    hIcon: 0;
    hCursor: 0;
    hbrBackground: 0;
    lpszMenuName: nil;
    lpszClassName: 'BlCatchMessageForm');

procedure TPumpThread.Execute;
var
  HWND: Cardinal;
  Msg: tagMSG;
begin
  if RegisterClass(BlCatchMessageForm) > 0 then
  begin
    HWND := CreateWindow(
      'BlCatchMessageForm',
      'BlCatchMessageForm',
      WS_OVERLAPPEDWINDOW,
      GetSystemMetrics(SM_CXSCREEN) div 2,
      GetSystemMetrics(SM_CYSCREEN) div 2,
      0, 0,
      0,
      0,
      HInstance,
      nil);
    while (GetMessage(Msg, HWND, 0, 0)) do
    begin
      TranslateMessage(Msg);
      if Msg.message in [WM_QUIT, WM_QUERYENDSESSION] then
        Break;
      DispatchMessage(Msg);
    end;
    DestroyWindow(HWND);
    ExitProcess(0);
  end;
end;

class procedure TPumpThread.Pump;
begin
  with TPumpThread.Create(True) do
  begin
    FreeOnTerminate := True;
    Resume;
  end;
end;

...but I does not work. Under XP, the application still blocks the system shutdown.

If you have some pieces of code, or some hints, I would really appreciate your suggestions !!

Best regards,

A.R.

Replies:

www.cryer.info
Managed Newsgroup Archive