I'm calling another Program which only displays a webpage like this :
Problem : if I Create a Process with the Button , and while the Created Process is open , I click on a Checkbox on the calling form , I close the created process the Checkbox is checked .
I tried to use the DisableTaskWindows(0) as seen in the .ShowModal function . But it does not work as I expected. While it does disable the form . But after I enable it , it seems like the form processes the click event anyway. Kinda like if it has a message queue or something .
Can anyone tell me what is it that I am doing wrong here?
procedure TForm1.Button1Click(Sender: TObject);
var
StartupInfo : TStartupInfo;
ProcessInfo : TProcessInformation;
ProcessCreated : Boolean;
CommandLine : string;
WindowList: TTaskWindowList;
begin
WindowList := DisableTaskWindows(0);
CommandLine:='webmodule.exe';
uniqueString(CommandLine);
ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
StartupInfo.cb := SizeOf(StartupInfo);
ProcessCreated := CreateProcess(PChar(nil), PChar(CommandLine), nil, nil, false, 0, nil, nil, StartupInfo, ProcessInfo);
if ProcessCreated then
WaitForSingleObject(ProcessInfo.hProcess, INFINITE)
else
ShowMessage('Error : could not execute!');
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
EnableTaskWindows(WindowList);
end;
UPDATE
unfortunately I am not sure how one uses the RegisterWaitForSingleObject function ... I tried this , but is not working . I am missing the CallBack maybe ? But I have no idea how to use it.
if ProcessCreated then
begin
// WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
while (RegisterWaitForSingleObject(ProcessInfo.hProcess,ProcessInfo.hProcess,nil,nil,INFINITE,0) = false) do
begin
Form1.Color:=RGB(random(255),random(255),random(255));
Application.ProcessMessages;
end;
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end
else
ShowMessage('Error : could not execute!');
UPDATE 2 :
I think I might have solved it , I removed the Enable Disable for the Form . Instead I do this after I executed the Process .
while PeekMessage(Msg, 0, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE or PM_NOYIELD) do;
while PeekMessage(Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE or PM_NOYIELD) do;
The problem is that you are blocking your app's main message loop while waiting for the spawned process to exit, so you are not allowing your app to process user input until after that process ends. You need to let your app process messages normally, don't block them. If you disable your Form while the spawned process is running, user input will automatically be discarded for you.
Try something more like this:
procedure TForm1.Button1Click(Sender: TObject);
var
StartupInfo : TStartupInfo;
ProcessInfo : TProcessInformation;
CommandLine : string;
begin
CommandLine := 'webmodule.exe';
UniqueString(CommandLine);
ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
StartupInfo.cb := SizeOf(StartupInfo);
if not CreateProcess(PChar(nil), PChar(CommandLine), nil, nil, FALSE, 0, nil, nil, StartupInfo, ProcessInfo) then
begin
ShowMessage('Error : could not execute!');
Exit;
end;
CloseHandle(ProcessInfo.hThread);
Enabled := False;
repeat
case MsgWaitForMultipleObjects(1, ProcessInfo.hProcess, FALSE, INFINITE, QS_ALLINPUT) of
WAIT_OBJECT_0: Break;
WAIT_OBJECT_0+1: Application.ProcessMessages;
else
begin
ShowMessage('Error : could not wait!');
Break;
end;
end;
until False;
CloseHandle(ProcessInfo.hProcess);
Enabled := True;
end;
Or this:
type
TForm1 = class(ToFrm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
...
private
hWaitObj, hWaitProcess: THandle;
procedure WaitFinished;
...
end;
...
procedure WaitCallback(lpParameter: Pointer; WaitFired: Boolean); stdcall;
begin
TThread.Queue(nil, TForm1(lpParameter).WaitFinished);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
StartupInfo : TStartupInfo;
ProcessInfo : TProcessInformation;
CommandLine : string;
begin
CommandLine := 'webmodule.exe';
UniqueString(CommandLine);
ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
StartupInfo.cb := SizeOf(StartupInfo);
if not CreateProcess(PChar(nil), PChar(CommandLine), nil, nil, FALSE, 0, nil, nil, StartupInfo, ProcessInfo) then
begin
ShowMessage('Error : could not execute!');
Exit;
end;
CloseHandle(ProcessInfo.hThread);
if not RegisterWaitForSingleObject(hWaitObj, ProcessInfo.hProcess, WaitCallback, Self, INFINITE, WT_EXECUTELONGFUNCTION or WT_EXECUTEONLYONCE) then
begin
CloseHandle(ProcessInfo.hProcess);
ShowMessage('Error : could not wait!');
Exit;
end;
hWaitProcess := ProcessInfo.hProcess;
Enabled := False;
end;
procedure TForm1.WaitFinished;
begin
UnregisterWait(hWaitObj);
CloseHandle(hWaitProcess);
Enabled := True;
end;