Paul,
> Thanks for your reply Harley.
You're welcome.
> I do use CreateProcess.
> I was wondering if anyone has had experience in using
> EnumThreadWindows to track all of the windows that were
> loaded using the process.
Here's sample code that puts the text/caption and class name of
the windows owned by the current thread in a memo:
function MyEnumThreadWndProc(aHWND: HWND; aParam: LongInt): Boolean;
stdcall; // <- IMPORTANT
var
lTempLength: Integer;
lTempText: String;
lTempClass: String;
begin
lTempLength := GetWindowTextLength(aHWND)+1;
if lTempLength > 1 then
begin
SetLength(lTempText, lTempLength);
GetWindowText(aHWND, PChar(lTempText), lTempLength);
SetLength(lTempText, lTempLength-1);
SetLength(lTempClass, 255);
if GetClassName(aHWND, PChar(lTempClass), 255) <> 0 then
lTempClass := 'Class not found';
TMemo(aParam).Lines.Add(lTempText + ': ' + lTempClass);
end;
result := True; // <- IMPORTANT
end;
procedure TForm1.Button7Click(Sender: TObject);
begin
Memo2.Lines.Clear;
EnumThreadWindows(GetCurrentThreadId, @MyEnumThreadWndProc,
LongInt(Memo2));
end;
I would assume you can use the dwThreadId field of the PROCESS_INFORMATION
structure returned by CreateProcess in place of GetCurrentThreadId in the
example above to get what you're looking for.
> Any help would be greatly appreciated. I can't find any
> reference to this in the Delphi 5 help.
Typing EnumThreadWindows in the Delphi editor and hitting F1
gets the help for me.
Hope this helps,
Harley Pebley
*************************************************************************************
> I was looking
> at the posts and came across one about stopping 2 or more copies of a
> program being loaded at the same time.
A much better way of doing this is:
The following was posted to this list by Bjarne a while ago:
***************** START PROJECT FILE EXAMPLE ****************
program Project1;
uses
Forms,
Windows, // necessary for the THandle and CreateMutex
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
var
AppMutex : THandle;
begin
AppMutex := CreateMutex(nil, true, 'MY_APP_MUTEX_NAME');
if GetLastError <> ERROR_ALREADY_EXISTS then begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
end.
***************** END PROJECT FILE EXAMPLE ****************
Regards,
Anthony Richardson
Sage Automation
anthony_r@sageautomation.com
_______________________________________________
Delphi mailing list -> Delphi@elists.org
http://elists.org/mailman/listinfo/delphi
**************************************************************************
[KILL NETWORK PROCESS]
> I need to check to see if a process is still running by using the process
> id. Then I will need to check if a process is running on a remote compoute
> on the network.
> Does anyone have an idea on how to do this or where I can look for
> information on doing this?
Richard,
This routine, courtesy of Richard Watson, may help you:
procedure KillIfPreviousInstance(cAppName: string);
var
hWndHandle: integer;
hPopup: HWND;
MyClassName: string;
begin
SetLength(MyClassName, 255);
GetClassName(Application.Handle, PChar(MyClassName), 255);
hWndHandle := FindWindow(PChar(MyClassName), PChar(cAppName));
if hWndHandle <> 0 then begin
ShowMessage('An instance of this application is already loaded and
will be activated.'#13#10
+ 'Look on the Start Bar or Icon Tray.');
hPopup := GetLastActivePopup(hWndHandle);
if IsIconic(hPopup) then
ShowWindow(hPopup, SW_RESTORE);
SetForeGroundWindow(GetTopWindow(hPopup));
Halt(0);
end; { if }
end;
Jerry
***********************************************************************************
{----------------------------------------------------------------------------------
Description : attempts to exetute an application. Returns True if succeeds
Parameters :
FileName : app's full path
Params : command line parameters
iCmdShow : desired starting visibility for the app
dwWait : wait or not for the app to finish its job - see Notes
Error checking : YES
Target : Delphi 2, 3, 4
Example call : btCreateProcess('C:\WINDOWS\NOTEPAD.EXE', SW_SHOW, W_NOT)
Author : Theo Bebekis,
Notes :
1. Define these constants to use it with the iWait parameter
const
W_NOT = 0;
W_INFINITE = 1;
W_PROCESSING = 2;
if the dwWait is different than the above integer the function
waits dwWait milliseconds for the app to finish what is doing
2. uses Windows, SysUtils, Forms
3. If you call the function with W_PROCESSING you'll not be able to
terminate the calling application while the invoked application
is still running.
-----------------------------------------------------------------------------------}
function btCreateProcess(const FileName, Params: string; iCmdShow: integer; dwWait: DWORD): boolean;
const
W_NOT = 0;
W_INFINITE = 1;
W_PROCESSING = 2;
var
pCmdLine : array[0..2 * MAX_PATH - 1] of char;
SI : TStartupInfo;
PI : TProcessInformation;
iStatus : DWORD ;
begin
Result := False;
{ check for apps existence }
if not FileExists(FileName) then
raise Exception.CreateFmt('Unable to find %s', [ExtractFileName(FileName)]);
StrPCopy(pCmdLine, FileName + ' ' + Params);
{ prepare the TStartupInfo structure appropriately }
FillChar(SI, SizeOf(SI), #0);
SI.cb := SizeOf(SI);
SI.dwFlags := STARTF_USESHOWWINDOW; { need to set this in order to set wShowWindow }
SI.wShowWindow := iCmdShow;
Result := CreateProcess(nil, pCmdLine, nil, nil, False, NORMAL_PRIORITY_CLASS, nil, nil, SI, PI);
if not Result then
{$IFDEF VER90} { Delphi 2.0 }
raise Exception.Create('CreateProcess failed');
{$ELSE} { Delphi 2 up }
Win32Check(Result);
{$ENDIF}
{ wait status }
case dwWait of
W_NOT : { do not wait };
W_INFINITE : WaitForSingleObject(PI.hProcess, INFINITE);
W_PROCESSING : begin
WaitForSingleObject(PI.hProcess, 50);
GetExitCodeProcess(PI.hProcess, iStatus);
while (iStatus = STILL_ACTIVE) do
begin
Application.ProcessMessages;
WaitForSingleObject(PI.hProcess, 50);
GetExitCodeProcess(PI.hProcess, iStatus);
end;
end;
else WaitForSingleObject(PI.hProcess, dwWait);
end;
{ close the handles
Kernel objects, like the process we have created in this case,
are maintained by a usage count.
For cleaning up purposes we have to close the handles
to inform the system that we don't need the objects anymore }
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread );
end;
-----------------------------------
Theo Bebekis
Thessaloniki, Greece
bebekis@otenet.gr