I have a handle to a window in a seperate process, I know the window is a VB form. Does anybody know a way to turn that handle into a Form object so that I can invoke methods from my own process?
Printable View
I have a handle to a window in a seperate process, I know the window is a VB form. Does anybody know a way to turn that handle into a Form object so that I can invoke methods from my own process?
Finding the handle of a running window is easy. What, specifically, do you want to do with it after you have it?
COM objects (like forms) expose an interface to the client. - It is mapped into the client process memory space. And it is just the interface (vtable). In theory, I suppose, you could use QueryVirtualEx or some other api function to read memory from the other process until you found the interface (vtable), then try to make calls to it.
But you wouldn't be able to make any calls to it, unless you could find a way to modify the user stack for the other process.
That's abstract theory. Practice is: no way in hell. Code like Form1.Left=100 in VB just isn't going to work from an external process.
Just use the hWnd to SendMessage to the form. Sorry.
Short answer: no way :D
Well, :D
my subclassing control uses some techniques to get a object reference from a handle. :)
- more threory -
As the Win32 API refers to a window with a handle, COM (or VB) uses object references to refer to a window. That object knows the handle, and all functions/properties in the object are internally using Win32 API's to modify the window.
- Now the trick -
Using the ObjPtr() function, you can get the memory location of a object. (a long number). Use the SetProp() API to store that number somewhere at the window, like SetProp(Form1.hWnd, "my_reference", ObjPtr(Form1))
Somewhere else in your code, you can use GetProp to get the property. Converting that back into a real reference is tricky.
If the object doesn't exist at that location, the code properly fails!
VB Code:
Public Function GetObjectByPtr(ByVal ObjectPointer As Long) As Object Dim TheObj As Object Dim Holder As Object ' Maybe I confused ByVal and ByRef somewhere, ' check it, and please be careful with using this. Call CopyMemory(ByVal ObjectPointer, Holder, 4) ' Illegal Reference!! Set TheObj = Holder ' Make the reference legal (calls the addref method for the COM object) Call CopyMemory(Holder, ByVal 0, 4) ' Destroy illegal reference Set GetObjectByPtr = TheObj End Function
Thanks guys,
Yapp. Your code is actually the techique I was using but had all sorts of problems with, Jim's comments expained why.
Back to the drawing board.