Solved

Get window handle from process ID

Posted on 1998-10-17
18
30,710 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
Technology Partners: 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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

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.

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…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

690 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