3

I need to obtain the Excel 2013 x64 window handle from 64 bit VBA code running in a spreadsheet. There are a couple of options to do this:

    Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
           ByVal lpClassName As String, _
           ByVal lpWindowName As String) As LongPtr

The problem is that Application.Hwnd returns a Long, i.e. 32 bits (I've verified this with MsgBox TypeName(Application.Hwnd) within a 64 bit environment), whereas FindWindow returns a LongPtr, which is 64 bits long in Office x64.

Does this mean that the Application.Hwnd property can't be trusted to always be correct in a 64 bit environment?

Community
  • 1
  • 1
R Hoffmann
  • 67
  • 3
  • 7

1 Answers1

5

Does this mean that the Application.Hwnd property can't be trusted to always be correct in a 64 bit environment?

No that is not true. The LongPtr is just a variable data type which is a 4-bytes data type on 32-bit versions and an 8-byte data type on 64-bit versions of Office 2010.

You can read more about LongPtr Here

In case the above link dies...

LongPtr (Long integer on 32-bit systems, LongLong integer on 64-bit systems) variables are stored as signed 32-bit (4-byte) numbers ranging in value from -2,147,483,648 to 2,147,483,647 on 32-bit systems; and signed 64-bit (8-byte) numbers ranging in value from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 on 64-bit systems.

Note

LongPtr is not a true data type because it transforms to a Long in 32-bit environments, or a LongLong in 64-bit environments. Using LongPtr enables writing portable code that can run in both 32-bit and 64-bit environments. Use LongPtr for pointers and handles.

Suggested for further Reading:

Compatibility Between the 32-bit and 64-bit Versions of Office 2010

Followup from comments

However, I'm worried that since FindWindow can return a larger value, a window handle may exceed 32 bits at some stage. And if that's true, then Application.Hwnd would be unable to return the correct value. Or are you saying that a window handle will never exceed 32 bits?

The following link explains it beautifully. Interprocess Communication Between 32-bit and 64-bit Applications

Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250
  • Thanks very much for your answer. Let me just make sure we're on the same page: `FindWindow` returns 64 bits, suggesting that window handles can exceed 32 bits of value. However, `Application.Hwnd` only returns 32 bits. So if a window handle can exceed the maximum value possible with 32 bits, what happens to `Application.Hwnd`? – R Hoffmann May 22 '15 at 13:14
  • I am not sure if I understand you. If the application `hwnd` is say `11872538` then `Findwindow` would return the same value. You can also use Spy++ to check that. `Findwindow` in 64 bit uses `LongPtr`for compatibility as some application may have bigger `hwnds` – Siddharth Rout May 22 '15 at 13:24
  • Thanks for your reply. I understand that if the handle is a value between -2,147,483,648 and 2,147,483,647, then both ways would return the same value. However, I'm worried that since FindWindow _can_ return a larger value, a window handle _may_ exceed 32 bits at some stage. And if that's true, then `Application.Hwnd` would be unable to return the correct value. Or are you saying that a window handle will never exceed 32 bits? – R Hoffmann May 22 '15 at 13:27
  • `Or are you saying that a window handle will never exceed 32 bits?` I am not sure of this so I will refrain from commenting this. What I can say for sure is that `Findwindow` and `Application.Hwnd` will never give you different values for the same window. This can be verified using Spy++ as well – Siddharth Rout May 22 '15 at 13:30
  • Just found [This](https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx) link. – Siddharth Rout May 22 '15 at 13:32
  • 1
    @siddharth-rout - Good answer, but I have no idea what Microsoft actually did with PtrSafe declarations and the LongPtr data type in the compiler, in addition to putting in runtime checks for 32- and 64-bit interoperability: I would speculate that LongPtr addresses and memory do not get garbage-collected in the same way as plain-vanilla integers, as the 'safe pointer' concept is more than just a 32-bit compatibility implementation. – Nigel Heffernan Sep 14 '16 at 10:19