The following code minimally demonstrates the problem. In a background thread, I create a valid handle array and pass it to WaitForMultipleObjects and this successfully waits on the objects.
When passing the exact same array to MsgWaitForMultipleObjects, however, the function call fails (WAIT_FAILED) with ERROR_INVALID_HANDLE.
What am I doing wrong?
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows, SyncObjs, Classes;
type
TMyThread = class(TThread)
protected
procedure Execute; override;
end;
procedure TMyThread.Execute;
var
LEvent : TEvent;
LWaitHandles : TWOHandleArray;
LPWaitHandles : PWOHandleArray;
LWaitResult : Cardinal;
begin
LEvent := TEvent.Create;
LWaitHandles[0] := LEvent.Handle;
LPWaitHandles := @LWaitHandles;
while not Terminated do begin
{Works -> LWaitResult := WaitForMultipleObjects(1, LPWaitHandles, false, INFINITE);}
{Fails ->} LWaitResult := MsgWaitForMultipleObjects(1, LPWaitHandles, false, INFINITE, QS_ALLINPUT);
case LWaitResult of
WAIT_OBJECT_0: WriteLn('Event 1 Signaled');
{ etc... }
WAIT_FAILED : WriteLn(SysErrorMessage(GetLastError));
end;
end;
end;
var
lt : TMyThread;
begin
lt := TMyThread.Create(false);
ReadLn;
end.
Although the WinAPI signature for the handles parameter is identical for these two calls :
_In_ const HANDLE *pHandles,
the RTL nevertheless wraps these functions in different ways. WaitForMultipleObjects uses the pointer type:
lpHandles: PWOHandleArray;
while MsgWaitForMultipleObjects uses an untyped var parameter:
var pHandles;
The handle array must therefore be passed directly to MsgWaitForMultipleObjects.
ie:
LWaitResult := MsgWaitForMultipleObjects(1, LWaitHandles, false, INFINITE, QS_ALLINPUT);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With