Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Get window handle from process ID

Posted on 1998-10-17
18
30,431 Views
Last Modified: 2008-03-06
From a newsgroup I got hold on this piece of sourcecode, which is supposed to get me the window handle from a processID. Well my question is in fact quite simple. It doesn't work, but whats wrong. I know that the if statement in the callback function EnumProc() never equals true, so no handle can be returned. Unfortunatly I can't seem to udnerstand exactly what is going on. Please help

Type
  TEnumData = Record
    hW: HWND;
    pID: DWORD;
  End;

Function EnumProc( hw: HWND; Var data: TEnumData ): Bool; stdcall;
  Var
    pID: DWORD;
  Begin
    Result := True;
    If (GetWindowLong(hw, GWL_HWNDPARENT) = 0) and
       (IsWindowVisible( hw ) or IsIconic(hw)) and
       ((GetWindowLong(hw, GWL_EXSTYLE) and WS_EX_APPWINDOW) <> 0)
    Then Begin
      GetWindowThreadProcessID( hw, @pID );
      If pID = data.pID Then Begin
        data.hW := hW;
        Result := False;
      End; { If }
    End; { If }
  End; { EnumProc }

Function WindowFromProcessID( pID: DWORD ): HWND;
  Var
    data: TEnumData;
  Begin
    data.pID := pID;
    data.hW := 0;
    EnumWindows( @EnumProc, longint(@data) );
    Result := data.hW;
  End; { WindowFromProcessID }

0
Comment
Question by:carceri
  • 10
  • 6
  • 2
18 Comments
 
LVL 10

Accepted Solution

by:
viktornet earned 130 total points
ID: 1343243
How about this code???

var
  DaHandle : HWND;
function GetHwnd(Handle : HWND; lParam : LPARAM) : Boolean;stdcall;
begin
  DaHandle := Handle;
  Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Name : array [0..MAX_PATH] of char;
begin
  if EnumThreadWindows(GetCurrentThreadId, @GetHwnd, 0) then begin
    GetWindowText(DaHandle, Name, SizeOf(Name));//YOu can comment out this
    Button1.Caption := StrPas(Name);//and this
    //and use the DaHandle that has been returned by the EnumThreadWindows()
  end;
end;

0
 

Author Comment

by:carceri
ID: 1343244
I'll try this... It might take a while, since I'm sitting at a UNIX system right now :-)
0
 

Author Comment

by:carceri
ID: 1343245
Well.. I think there is a problem! The process ID I'm looking for it not from my own app, but from an external app. Will it be sufficient to replace GetCurrentThreadId with the processID from the other app ?
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.

 
LVL 10

Expert Comment

by:viktornet
ID: 1343246
Yes, of course .... Try it out, and it is suppose to be working...

Viktor
0
 

Author Comment

by:carceri
ID: 1343247
I think there's a difference between threadid and processid. When I find the process ID using WinSight32 and insert in instead of GetCurrentThreadId, the returned handle is 0, but if I leave GetCUrrentThreadId, then I get a handle (of cource not the one I want)

One other thing... I am having problems using a callback function. When I call EnumWindows(@EnumProc, 0) where EnumProc is:

function EmunProc(app_hnd : HWND; lparam : DWORD) : boolean;
begin
  // some stuff here
  Form1.Memo1.Lines.Add(IntToStr(app_hnd));
end;

The memo component gets filled with the same handle a lot of times. Isn't EnumWIndows suppored to pass the handle of all top level windows in turn to the CallBack function. What am I doing wrong ??
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343248
No you need to specify which windows..... Here is an example...

function GetWinProc(Handle : HWND;  lParam : LPARAM):Boolean;stdcall;
var
  Name : array[0..MAX_PATH] of char;
begin
  if IsWindowVisible(Handle) then begin
    GetWindowText(Handle, Name, SizeOf(Name));
    if not(Name = '') then
      Form1.Listbox1.Items.Add(Name);
    Result := true;
  end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  ListBox1.Items.Clear; //Just to clean the listbox so it clears it before filling it again..
  EnumWindows(@GetWinProc,0);
end;

This will get all visible windows, not the one that don't have names like popup menus and similar....

Hoe this helps a bit!

btw- I don't know why the processID isn't working... Gotta try it on my Delphi, and will get back to you soon.///

Regards,
Viktor Ivanov
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343249
Oh, forgot....... Use StrPas(Name); after the GetWindowsText()

Viktor
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343250
And don;t forget to change in your callback function the lparam : DWORD to lparam : LPARAM

Bye...

Viktor
0
 

Author Comment

by:carceri
ID: 1343251
Thanks... The only thing I was missing was the stdcall after the callback function. The other stuff I have worked out myself
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343252
How did you work out that problem?? I'm curious to know since I didn't succeed.

Cheers,
Viktor
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343253
By the way... I saw your profile... How old are you??? 14/15/16 ????

Cheers,
Viktor
0
 

Author Comment

by:carceri
ID: 1343254
I'll post the source code here ASAP

I'm 19 years old, and has just begun studying computer science and mathemathics
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343255
Oh, ok.... Cool... You said you were going to a High School so I though were still there... But what I missed was that I didn't see you registered in 97 :-|  Sorry... Anyway, I'm 16 and really like programming in Delphi. Actually it's my first programming language and I started programming in it a bit more than 3 months...maybe 4 months.... ago. I've learned a little C/C++ and I'm learning assmbler right now :-)

btw- What kind of stuff do you study in Computer Science....????

Regards,
Viktor Ivanov
0
 

Expert Comment

by:jayc75
ID: 4896102
Hi there maybe you can help too,
i was trynig to shell an applictaion and get it's HWND, can your code help me do that, i tried ShellExecute but it does't return the HWND it returns HINST which i don't know how to convert to HWND...if you know how please post your answere here. thanks
0
 

Expert Comment

by:jayc75
ID: 4896105
Hi there maybe you can help too,
i was trynig to shell an applictaion and get it's HWND, can your code help me do that, i tried ShellExecute but it does't return the HWND it returns HINST which i don't know how to convert to HWND...if you know how please post your answere here. thanks
0
 
LVL 10

Expert Comment

by:viktornet
ID: 4902543
Wow, it's been 2 years since I posted to this question, and there's a comment waiting for me now. Anyways, I don't really have time to write any code for you, but here is the principle.

You can use ShellExecute() to execute your application, and then you can use FindWindow() to track down the handle of your window. There are other more complex   methods to do it, but I don't have the time, as I previously mentioned.

Regards,
Viktor
0
 

Author Comment

by:carceri
ID: 4903385
Wov, I got pretty confused when I saw this. It was first when I saw that the question was 2 years old I remembered what it was about :-)
0
 
LVL 10

Expert Comment

by:viktornet
ID: 4910523
hehe, so did I ;-)
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

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

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

791 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