Process handle from a CreateObject in VBA

Using the following line of VBA code
Set objPwrPnt = CreateObject("Powerpoint.application")

Open in new window

How do I determine the HANDLE of the newly created process (objPwrPnt) ?

I require a HANDLE for some calls into the windows API.
LVL 45
AndyAinscowFreelance programmer / ConsultantAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

aikimarkCommented:
Do you need an hwnd value or something else?
Have you tried using 0 for the handle?

In what VBA run-time environment are you doing this?
0
AndyAinscowFreelance programmer / ConsultantAuthor Commented:
Ideally a HWND, but the HANDLE of the process ID attached to the object I should be able to convert into a HWND of the main app window of that process.

In the above example I want to get the HWND of the main powerpoint window.  The VBA is an Access 2013 environment.


ps.  I can use FindWindow and so on with the window caption but that seems rather a long way round.
0
aikimarkCommented:
Try this:
objPwrPnt.hwnd

Open in new window

0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

Nick67Commented:
I can use FindWindow and so on with the window caption but that seems rather a long way round.
Myself, I don't know any other way around it.  Unless...
You DON'T use VBA to do the CreateObject.
If you have the facility to write something more WinAPIish-C++ish-C#ish to create PowerPoint so that you have it's handle immediately, and then GetObject in VBA to pick up the existing object.

But maybe its not so long a ways around.
Have a look here
http://www.vb-helper.com/howto_shell_get_hwnd.html

But the caveat seems to be that it no linger plays nicely in A2002+
0
Nick67Commented:
Poking at aikimark's suggestion, Access has the hWndAccessApp method for returning the hwnd of the main window.
One wonders if PowerPoint has something similar?

But I think ShellExecute will be your winner
http://www.suodenjoki.dk/us/productions/articles/vbashellexecute.htm
0
AndyAinscowFreelance programmer / ConsultantAuthor Commented:
Thanks for the responses.

I have no problem creating the powerpoint object in VBA.

I **need** that object because of the automation code being run on that object in the ensuing VBA code.  Code that has been running for years with stability, now on changing to new PC's with new versions of office and newer operating system  the code works on my development PC but fails intermittently in the real life situation.  I want to get at the newly running instance and use some windows API calls to check some things.

Unfortunately there does not seem to be a process instance handle or HWND of the app made available - at least I haven't found it yet.  (Unlike numbers of examples on the internet using an internetexplorer object, which does expose a hwnd member, for doing what I wanted.  Or as already mentioned the hWndAccessApp exposed in Access.)

Using the window caption and class name of the powerpoint app I have been able to get what I wanted, but it still could theoretically not get the correct instance as well as being like using a sledgehammer to crack a nut.  It surprises me such information is not exposed simply in the object I use for the automation.
0
Nick67Commented:
The return value of ShellExecute is the hwnd.
0
aikimarkCommented:
My apologies.  I had done a quick test with Excel and the automation object had an hwnd property.  I assumed that all the Office automation objects would share a common set of properties.
0
AndyAinscowFreelance programmer / ConsultantAuthor Commented:
I tested before asking the question:
SNAG-0006.bmp
>>I assumed that all the Office automation objects would share a common set of properties.
To much to hope for, it has only been around, what 20 years or so.
0
AndyAinscowFreelance programmer / ConsultantAuthor Commented:
I've requested that this question be deleted for the following reason:

Looks like there isn't a simple way for powerpoint after all.
0
aikimarkCommented:
Microsoft recommends using the FindWindow API using the window class for powerpoint:
Example:
' PP12FrameClass for PowerPoint 2007
' PP11FrameClass for PowerPoint 2003

reference: http://support.microsoft.com/kb/258511

===========
Alternatively, I would anticipate that you could use WMI to get the process.  This would be an alternative to the API, probably even wrapping the API under the covers.
0
Nick67Commented:
~40 lines of code, total
Sample attached.
Check if ppt is open, bail if it is
API code to open ppt and return the hwnd
GetObject to automate it within VBA
Very odd things would have to occur to screw this up.

16 lines of WinAPI code
Alter as required
FirePPT.mdb
0
aikimarkCommented:
I must agree with Nick.  There are ways to get the handle, but not directly from the Powerpoint automation object.
0
Nick67Commented:
How do I determine the HANDLE of the newly created process (objPwrPnt)
I think my sample has that licked.
But I'll definitely agrees with
It surprises me such information is not exposed simply in the object I use for the automation.
>>I assumed that all the Office automation objects would share a common set of properties.
Too much to hope for, it has only been around, what 20 years or so.


MS hasn't really done much with the VBA-powered platforms since O2003
They've been busy chasing their SharePoint/Azure/Cloud tails.
The numbers trumpeted for O365 sound soooooooooooooooo impressive
Until you realize there's a billion Windows machines in the world.
And then you know it's the dead cat bounce.

Hopefully they wake up and start working on the platform that matters, instead of the niche products that most of us could care less about.
0
AndyAinscowFreelance programmer / ConsultantAuthor Commented:
>>I think my sample has that licked.

I'd disagree.  I've had a quick look.  It doesn't take an existing powerpoint object and find the handle or hwnd of that.  It bails out if powerpoint is already running.  I'm not going to discuss anything with the hard coded paths.  It looks to actually open powerpoint twice but I might have not got the logic down correctly.  I'm not too certain of the reliability of the GetForegroundWindow call actually grabbing powerpoint.

As I mentioned rather earlier I can get at the hwnd of an existing powerpoint object with a high degree of certainty, just rather a long winded way.

I had hoped there would be a function that I didn't know that would take an object and return information about it such as the handle or hwnd.
eg.  hwnd = ObjectInfo(objPwrPnt, OI_HWND) or processID = ObjectInfo(objPwrPnt, OI_PID)
0
Nick67Commented:
:)
Now don't go moving the goalposts!  You posted code that created a PPT instance.  I went you one better and posted code that ensures ONLY a newly created PPT would be running and returned the Hwnd of that instance.  That was the Q.  Now, hunting down the Hwnd of a particular instance of multiple PPT's, that's harder to do.

As for the path, ShellExecute will happily take an ppt or pps file path as an argument.  Create a string path to it and you are in business.  One assumes that you have a presentation to manipulate.

It looks to actually open powerpoint twice but I might have not got the logic down correctly.  Since you asked for a new instance, it calls GetObject to see if there's a PPT in existence, first.  If that succeeds, the sub exits and bails.  If that fails, it'll return null and set the Boolean to false.  The code then creates the PPT and calls GetObject to return an object for your use in VBA The very next thing that goes on is the ForeGroundWindow call  Something odd would have to occur that interposed between the call to open PPT and the call to determine the window that some other window would become the foreground object.  It's not impossible, but highly unlikely.
0
Nick67Commented:
And please don't delete this question.
Learning about ShellExecute and the fact that it'll take a filepath was incredibly useful.
I wish I had known the implications of that a long time ago.
It strikes me as convenient to open a file and then get the automation object, rather than firing up the automation object and then opening the file.

Firing up a Word document for example
  Dim oApp As Object
   Set oApp = CreateObject(Class:="Word.Application")
   oApp.Visible = True
   'Open the Document
    oApp.Documents.Open SomeValidPath


Have ShellExecute on the go, though and
Call ShellExecute(0, "open", SomeValidPath, "", "", 3)
will get it done

There's something to be said for that.
0
AndyAinscowFreelance programmer / ConsultantAuthor Commented:
>>Now don't go moving the goalposts!

I don't recall setting the goalposts you refer to.  
I did specifically ask for getting the handle from an existing automation object.  It seems like that is not possible directly.  (I did indicate earlier I could already accomplish that with a FindWindow based technique).

As you want to keep the question for the code/comments you later posted I'll change the delete request to an accept of this comment here.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Nick67Commented:
Maybe what you wrote and what you had in mind had some discordance

Using the following line of VBA code
Set objPwrPnt = CreateObject("Powerpoint.application")                                
 How do I determine the HANDLE of the newly created process (objPwrPnt) ?


Perhaps you meant that as 'I am going to create a PowerPoint automation object, and I'd like to get the Hwnd of that object at some point afterwards.'

I ran with 'newly created'
I read it as 'I want to create a PowerPoint automation object and immediately know its Hwnd for use with WinAPI code'

'Newly created' is fairly simple and I've demo'd that.
 'some point afterwards' is not simple at all -- and if multiple applications of a class are running, its basically impossible to tell which Hwnd corresponds to the automation object.

And that isn't telling you anything you didn't already know.

It was an interesting question.
Sorry that what I've given you isn't what you wanted.

Nick67
0
AndyAinscowFreelance programmer / ConsultantAuthor Commented:
Ah, now I see where your goalposts came from.

Any apologies ought to be from Microsoft - the Windows API uses HANDLEs and HWNDs but they don't provide an easy way to obtain them from an automation object.  


>>and if multiple applications of a class are running, its basically impossible to tell which Hwnd corresponds to the automation object.
Using the caption and class one an have a pretty good stab at it - not absolutely certain but very likely to be a match.
0
Nick67Commented:
Using the caption and class one an have a pretty good stab at it - not absolutely certain but very likely to be a match.
:D

I set the bar pretty high when it comes to that.  There's possible (99% certainty that it'll work correctly) and impossible.
Users will forgive a 1 in 100 error rate.  Start going lower than that and they start getting grumpy.

Now, I haven't been happy with MS's neglect of the VBA platform for quite some time already, but in their defense:  How often is anybody using automation and WinAPI with Word and PowerPoint?  It has probably never been a high priority.
In terms of 'where is all the VBA code' its
Access --> Excel --> Outlook --> Word --> PowerPoint.
What's available in Access is pretty close to the full enchilada available in VB6.
It starts going downhill from there.

What really upsets me is that while Access and VB6 were closely related, absolutely NOTHING substantive has been done to bring the .Net platforms and VBA closer together.
0
AndyAinscowFreelance programmer / ConsultantAuthor Commented:
There is neglect and there is lack of consistency.
Some office apps do this and others not.  I've asked another question recently and the same object exposes different methods depending on which office app it is embedded in - wow!
0
AndyAinscowFreelance programmer / ConsultantAuthor Commented:
To keep this thread available for future users.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Access

From novice to tech pro — start learning today.

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.