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
 

Some videos you may like

Excel Facts

Enter current date or time
Ctrl+: enters current time. Ctrl+; enters current date. Use Ctrl+: Ctrl+; Enter for current date & time.

Leith Ross

Well-known Member
Joined
Mar 17, 2008
Messages
1,874
Office Version
2010, 2007
Platform
Windows
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
 

Leith Ross

Well-known Member
Joined
Mar 17, 2008
Messages
1,874
Office Version
2010, 2007
Platform
Windows
Hello Roger,You're welcome. Glad I could help.
 

Roger Sutcliffe

New Member
Joined
Sep 21, 2017
Messages
6

ADVERTISEMENT

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
 

Leith Ross

Well-known Member
Joined
Mar 17, 2008
Messages
1,874
Office Version
2010, 2007
Platform
Windows
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]
 

Roger Sutcliffe

New Member
Joined
Sep 21, 2017
Messages
6

ADVERTISEMENT

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]'
 

Leith Ross

Well-known Member
Joined
Mar 17, 2008
Messages
1,874
Office Version
2010, 2007
Platform
Windows
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?
 

Roger Sutcliffe

New Member
Joined
Sep 21, 2017
Messages
6
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
 

Roger Sutcliffe

New Member
Joined
Sep 21, 2017
Messages
6
Ross,
for the avoidance of doubt: PowerPoint 365 uses PPTFrameClass as its application window class
Thanks
Roger
 

Subscribe on YouTube

Watch MrExcel Video

Forum statistics

Threads
1,106,100
Messages
5,509,237
Members
408,716
Latest member
GreedySheedy

This Week's Hot Topics

  • Turn fraction around
    Hello I need to turn a fraction around, for example I have 1/3 but I need to present as 3/1
  • TIme Clock record reformatting to ???
    Hello All, I'd like some help formatting this (Tbl-A)(Loaded via Power Query) [ATTACH type="full" width="511px" alt="PQdata.png"]22252[/ATTACH]...
  • TextBox Match
    hi, I am having a few issues with my code below, what I need it to do is when they enter a value in textbox8 (QTY) either 1,2 or 3 the 3 textboxes...
  • Using Large function based on Multiple Criteria
    Hello, I can't seem to get a Large formula to work based on two criteria's. I can easily get a oldest value based one value, but I'm struggling...
  • Can you check my code please
    Hi, Im going round in circles with a Compil Error End With Without With Here is the code [CODE=rich] Private Sub...
  • Combining 2 pivot tables into 1 chart
    Hello everyone, My question sounds simple but I do not know the answer. I have 2 pivot tables and 2 charts that go with this. However I want to...
Top