handle and createprocess/2

hi,

under D3/WIN98 i start an app, which starts another app (by using createprocess).
i want to send messages from app1 to app2 (not in the other direction)
by the POSTMESSAGE-call.
but how can i get the handle if the window of app2 ?
because createprocess only gives a handle for the process not for the window!
i am looking for something like the reversal of GETWINDOWTHREADPROCESSID. But i did not find it.
FINDWINDOW can not be used, for the title of the app2 can be different or changed.

any idea ?

cheers
titz


 
LVL 1
titzAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
intheConnect With a Mentor Commented:
var
  Form1: TForm1;
   pi: TProcessInformation;
implementation

{$R *.DFM}
function CreateProcessSimple(Filename : string ): string;
  var
   si: TStartupInfo;
  begin
   FillMemory( @si, sizeof( si ), 0 );
   si.cb := sizeof( si );
    CreateProcess(Nil, PChar( Filename ),
                  Nil, Nil, False, NORMAL_PRIORITY_CLASS,
                  Nil, Nil, si, pi );
   //WaitForSingleObject(pi.hProcess,1000);
   //use above to wait for it to finish
   CloseHandle( pi.hProcess );
  end;

Procedure WriteToNotepad(what:string);
var h : thandle;
begin
h := 0;
repeat
h:=FindWindow('notepad',nil);
until h <> 0;
h:=FindWindowex(h,0,'edit',nil);
if h<>0 then SendMessage(h,wm_setText,0,Integer(what))
        else showmessage('Error writing to notepad!');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
CreateProcessSimple('notepad.exe');
Writetonotepad('hello im some text in notepad');
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
TerminateProcess(OpenProcess(PROCESS_TERMINATE,false,pi.dwProcessId),1);
CloseHandle( pi.hThread );
end;


if you have winsight that comes with delphi then use that to get the classnames or use a free program called sinfo from here:
http://lcpx07.lc.ehu.es/JMA/win95.html
0
 
intheCommented:
hi,
why not use findwindow using the classname instead of caption ?
i have example of this with sending message.(well starting notepad and sending text to it.)
0
 
wmckieCommented:
This is what I do to get a window handle after using CreateProcess:

In the Process_Information structure returned by CreateProcess you have a field which is the ProcessID use this
as follows with EnumWindows an the following callback:

EnumWindows(@FindProcessWindow, ProcessID);

function FindProcessWindow(Window: hWnd; ProcessID: lParam): boolean; stdcall;
var
  PID: dword;
  Rect: TRect;
begin
  Result := true; { Continue enumeration }
  GetWindowRect(Window, Rect);
  if (not IsWindowVisible(Window)) or     { Ignore invisible windows }
     (not IsWindow(Window)) or            { Ignore non windows !!! }
     (GetParent(Window) <> 0) or          { Ignore windows with parents }
     (GetWindowTextLength(Window) = 0) or { Ignore windows with no text }
     (Rect.Left = Rect.Right) or          { Ignore windows with no width }
     (Rect.Top = Rect.Bottom)             { Ignore windows with no depth }
    then Exit;
  GetWindowThreadProcessID(Window, @PID); { Get the process ID }
  if PID = dword(ProcessID)
    then
      begin
        WindowHandle := Window;
        Result := false; { Found a window so stop }
      end;
end;

I used to use FindWindows but during testing with Notepad.exe I found that if there was already an instance running and I started another thenI could get the handle of the wrong window.

I also found that if the app that has just been started takes a while to present a window then you need to put the EnumWindows in a loop till a satifactory result is obtained.

Cheers - Walter McKie
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
MadshiCommented:
Walter's suggestion looks alright to me, except one thing (WHY DO ALL PEOPLE MAKE THIS ERROR???):

function FindProcessWindow(Window: hWnd; ProcessID: lParam): BOOL; stdcall;

The result type must be a BOOL (= 4 bytes long), not a boolean (= 1 byte long).

Regards, Madshi.
0
 
titzAuthor Commented:
hi inthe,

i will do your way: the class for app2 will have a unique name, so that only this app can ahve this class. then the use of findwindow will be easy.

thanks to all,
titz
0
 
intheCommented:
ok cheers but do remember to make that clasname unique
(hehe look at microsofts examples)
0
 
MadshiCommented:
What if app2 is already running before you run app1? Then you have 2 instances of app2 running at the same time. The chance is then 50:50, that you'll get the wrong window handle.
0
 
titzAuthor Commented:
hi madshi,

this is not possible.
because app2 is only (and this is sure!) started from app1. And if app1 closes (for what reason ever) always app2 is closed automatically.

thanks
titz

0
 
MadshiCommented:
So I guess, app1 can't run twice at the same time, either? Then it's alright.
0
 
titzAuthor Commented:
Hi madshi,
correct : app1 can only run once. If it is always running, and a second instance will bestarted this one(=the second) will close immidiatly.

thanks for the hint !
titz
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.