Newsgroups : Borland : borland.public.delphi.nativeapi.win32 : 2007 Feb : 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.