• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 31784
  • Last Modified:

Get window handle from process ID

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
carceri
Asked:
carceri
  • 10
  • 6
  • 2
1 Solution
 
viktornetCommented:
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
 
carceriAuthor Commented:
I'll try this... It might take a while, since I'm sitting at a UNIX system right now :-)
0
 
carceriAuthor Commented:
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
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

 
viktornetCommented:
Yes, of course .... Try it out, and it is suppose to be working...

Viktor
0
 
carceriAuthor Commented:
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
 
viktornetCommented:
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
 
viktornetCommented:
Oh, forgot....... Use StrPas(Name); after the GetWindowsText()

Viktor
0
 
viktornetCommented:
And don;t forget to change in your callback function the lparam : DWORD to lparam : LPARAM

Bye...

Viktor
0
 
carceriAuthor Commented:
Thanks... The only thing I was missing was the stdcall after the callback function. The other stuff I have worked out myself
0
 
viktornetCommented:
How did you work out that problem?? I'm curious to know since I didn't succeed.

Cheers,
Viktor
0
 
viktornetCommented:
By the way... I saw your profile... How old are you??? 14/15/16 ????

Cheers,
Viktor
0
 
carceriAuthor Commented:
I'll post the source code here ASAP

I'm 19 years old, and has just begun studying computer science and mathemathics
0
 
viktornetCommented:
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
 
jayc75Commented:
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
 
jayc75Commented:
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
 
viktornetCommented:
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
 
carceriAuthor Commented:
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
 
viktornetCommented:
hehe, so did I ;-)
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.

Join & Write a Comment

Featured Post

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.

  • 10
  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now