Solved

handle and createprocess/2

Posted on 2000-03-01
10
249 Views
Last Modified: 2010-04-04
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


 
0
Comment
Question by:titz
  • 3
  • 3
  • 3
  • +1
10 Comments
 
LVL 17

Expert Comment

by:inthe
ID: 2573792
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
 
LVL 17

Accepted Solution

by:
inthe earned 50 total points
ID: 2574074
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
 
LVL 1

Expert Comment

by:wmckie
ID: 2575797
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: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 20

Expert Comment

by:Madshi
ID: 2576679
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
 
LVL 1

Author Comment

by:titz
ID: 2577354
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
 
LVL 17

Expert Comment

by:inthe
ID: 2577463
ok cheers but do remember to make that clasname unique
(hehe look at microsofts examples)
0
 
LVL 20

Expert Comment

by:Madshi
ID: 2579288
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
 
LVL 1

Author Comment

by:titz
ID: 2580961
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
 
LVL 20

Expert Comment

by:Madshi
ID: 2582006
So I guess, app1 can't run twice at the same time, either? Then it's alright.
0
 
LVL 1

Author Comment

by:titz
ID: 2592942
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

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

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

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question