Solved

Get window handle from process ID

Posted on 1998-10-17
18
30,530 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
[X]
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
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

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…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

749 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