The slowest process related function in the world

Everything else that doesn't fall into one of the other PB categories.
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

The slowest process related function in the world

Post by SFSxOI »

While searching through the forums today for something I saw a question posted in a thread from 2003 (http://www.purebasic.fr/english/viewtop ... t=testhwnd) about retrieving a window handle from a processID. The question also involved some VB code, the VB code is:

Code: Select all

Function InstanceToWnd(ByVal target_pid As Long) As Long
    Dim test_hwnd As Long, test_pid As Long, test_thread_id As Long
    'Find the first window
    test_hwnd = FindWindow(ByVal 0&, ByVal 0&)
    Do While test_hwnd <> 0
        'Check if the window isn't a child
        If GetParent(test_hwnd) = 0 Then
            'Get the window's thread
            test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)
            If test_pid = target_pid Then
                InstanceToWnd = test_hwnd
                Exit Do
            End If
        End If
        'retrieve the next window
        test_hwnd = GetWindow(test_hwnd, #GW_HWNDNEXT)
    Loop
End Function
Private
Anyway, I got curious if it would work in PB so I did this real quick:

Code: Select all

Global test_hwnd.l, test_pid.l, test_thread_id.l

Procedure InstanceToWnd(target_pid.l)
; Dim test_hwnd.l
; Dim test_pid.l
; Dim test_thread_id.l

;Find the first window
test_hwnd = FindWindow_(0,0)

While test_hwnd <> 0
  ;Check If the window isn't a child
        If GetParent_(test_hwnd) = 0 ;Then
          ;Get the window's thread
            test_thread_id = GetWindowThreadProcessId_(test_hwnd, test_pid)
              If test_pid = target_pid ;Then
                InstanceToWnd = test_hwnd
                Break ;Exit Do
              EndIf
        EndIf
        ;retrieve the Next window
        test_hwnd = GetWindow_(test_hwnd, GW_HWNDNEXT)
Wend

ProcedureReturn test_hwnd

EndProcedure
I fed it a PID with a quick droopy lib function with a

Code: Select all

Debug InstanceToWnd(GetPidProcess("notepad.exe"))
(BTW, the above will always return 0, although i understand that in VB it actually returns something)

This has got to be one of the slowest things in the world, I had time to make a picture of iced tea and a sandwich before it finished. Anyway, it begs the question as to how to retrieve a window handle from a processID when all you know is the processID. So if you have the processID and nothing else (no window titles or anything and its not a window you made), how can you get the hWnd in a painless way from the processID (I know there can be many processes associated with an executable - maybe this is why it would be difficult?). Seems difficult if not impossible to do, I guess you could enum everything but this takes time too. Any one have any ideas?
Last edited by SFSxOI on Sat Jan 27, 2007 8:18 pm, edited 2 times in total.
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Post by Pupil »

Maybe you could change the following line:

Code: Select all

test_thread_id = GetWindowThreadProcessId_(test_hwnd, test_pid)
To this instead:

Code: Select all

test_thread_id = GetWindowThreadProcessId_(test_hwnd, @test_pid)
Because the test following this line is rather useless if you don't have a proper return value to test against..
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

Thanks Pupil;

That did the trick! Duh! I hadn't even noticed that. Thank You :)

It works. However, if an application is running more then one thread (explorer for example) then it grabs something else and maybe not return the hWnd you expect (which is what I expected it to do with things that run multiple threads), the handle of the first thread i it finds for that PID I guess, maybe, don't know. But for things that only run a single thread it returns the correct window handle.
Post Reply