Given the HWND values for several application windows, how to use vba to return each window as an object?

Roger Sutcliffe

New Member
Joined
Sep 21, 2017
Messages
6
I use an API, run in excel, that returns: Parent window handles, classes and text. for ANY excel, non-Excel/non-office app.

'source: http://www.markrowlinson.co.uk/articles.php?id=4


The handle (HWND), 'text' and 'class' variables enable the identification of each Application window


Using the HWND value, and vba, which functions do I use to obtain the window OBJECT for each Application window?


KelvinRiver
 

Excel Facts

How to fill five years of quarters?
Type 1Q-2023 in a cell. Grab the fill handle and drag down or right. After 4Q-2023, Excel will jump to 1Q-2024. Dash can be any character.
Hello,

This code contains a macro that will return the Excel Application object from the window hWnd handle. This API code is written for Windows Vista and later.

Copy this code to a new VBA Module in your workbook.

Code:
' Written:  September 21, 2017
' Author:   Leith Ross


Private Const OBJID_NATIVEOM As Long = &HFFFFFFF0


Type GUID
    lData1 As Long
    iData2 As Integer
    iData3 As Integer
    aBData4(0 To 7) As Byte
End Type


Private Declare PtrSafe Function IIDFromString _
    Lib "ole32.dll" _
        (ByVal lpszIID As String, _
         ByRef lpIID As GUID) _
    As Long


Private Declare PtrSafe Function FindWindowEx _
    Lib "user32.dll" Alias "FindWindowExA" _
        (ByVal hWnd1 As LongPtr, _
         ByVal hWnd2 As LongPtr, _
         ByVal lpsz1 As String, _
         ByVal lpsz2 As String) _
    As LongPtr
    
Private Declare PtrSafe Function AccessibleObjectFromWindow _
    Lib "oleacc.dll" _
      (ByVal hWnd As LongPtr, _
       ByVal dwId As Long, _
       ByRef riid As GUID, _
       ByRef ppvObject As Object) _
    As Long
    
Public Function GetExcelObject(ByVal xlHwnd As LongPtr) As Object


    Dim CLSID   As String
    Dim IDisp   As GUID
    Dim ret     As Long
    Dim xlDesk  As LongPtr
    Dim xlWkb   As LongPtr
    Dim Wnd     As Object
    
        CLSID = StrConv("{00020400-0000-0000-C000-000000000046}", vbUnicode)
        ret = IIDFromString(CLSID, IDisp)
        
            xlDesk = FindWindowEx(xlHwnd, 0&, "XLDESK", vbNullString)
            xlWkb = FindWindowEx(xlDesk, 0&, "EXCEL7", vbNullString)
            
            If xlWkb <> 0 Then
                ret = AccessibleObjectFromWindow(xlWkb, OBJID_NATIVEOM, IDisp, Wnd)
                If ret = 0 Then
                    Set GetExcelObject = Wnd.Parent.Parent
                End If
            End If
                
End Function


Here is an example of how to use the code...
Code:
Sub TestIt()


    Dim Wkb     As Workbook
    Dim XLapp   As Object
        
        Set XLapp = GetExcelObject(Application.hWnd)
        Set Wkb = XLapp.Windows(1).ActiveSheet.Parent
        MsgBox Wkb.Name
        
End Sub
 
Upvote 0
Hello Roger,You're welcome. Glad I could help.
 
Upvote 0
Hello, Leith.
I have used your code to change the windows.state of Excel (xlMaximized <--> xlMinimized), as a pilot for my first aim, which is to change App window state for selected Apps including Powerpoint and Acrobat (.pdf)

I have some Spy++ like code (http://www.markrowlinson.co.uk/articles.php?id=4) to chase down Application window API className for the applications for PowerPoint and Acrobat (.pdf), which I think are PPTFrameClass and AcrobatSDIWindow, respectively.

But, I dont know how to construct the equivalent of your Function: GetExcelObject

What I really want to do is to get the pathname for the file open in powerpoint or acrobat, using API call to get the Application object.

Can you advise.

with thanks,
Roger Sutcliffe
 
Upvote 0
Hello Roger,

For PowerPoint you want to get the hWnd for the "[FONT=&quot]paneClassDC". As for Adobe, I am not sure how you can access the IDispatch pointer.[/FONT]
 
Upvote 0
Thank you... this is beyond my experience to pursue.

https://blogs.msdn.microsoft.com/gsmyth/2013/12/21/whats-in-a-window/ discussed this topic from the standpoint of Visual Studio.

he confirmsed 'For PowerPoint you want to get the hWnd for the "paneClassDC"', and adds:
'
the chain for PowerPoint 2013 is “PPTFrameClass” “MDIClient” “mdiClass” but is “PPTFrameClass” “MDIClient” “mdiClass” “paneClassDC” for PowerPoint 2010, and something else again for PowerPoint 2007).'

he concludesd '[FONT=WOL_Reg]VSTO gives you a good insider view of an application, and AccessibleObjectFromWindow can link that to the outsider view, so that you can make something associated with the window on the screen react to the contents of the document shown in that window.[/FONT]'
 
Upvote 0
Hello Roger,

I spent the past couple of days working with the API to find some solutions. Drilling down from the Application window to the IDispatch window is a bit involved. There are several methods to accomplish this. The easiest is knowing the Classes for the version of PowerPoint you are using. Will you be using various versions PowerPoint?
 
Upvote 0
Hello Ross,
Thanks for your interest!
I wont accept Powerpoint files before 2010. I'd like to accept files from 2010 onwards, but I would accept 2013 onwards (my personal PC uses Powerpoint 365)

Kind regards
Roger
 
Upvote 0

Forum statistics

Threads
1,214,784
Messages
6,121,535
Members
449,037
Latest member
tmmotairi

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top