0

Can you explain why the last line is not the same as the previous two lines and doesn't work? (it doesn't find any window)

Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr

Working =    FindWindowEx(hWnd2, 0&, "EXCEL7", vbNullString)
Working =    FindWindowEx(hWnd2, 0&, "EXCEL7", CStr(vbNullString))
NotWorking = FindWindowEx(hWnd2, 0&, "EXCEL7", CStr(IIf(1 = 1, vbNullString, vbNullString)))
6diegodiego9
  • 503
  • 3
  • 14
  • 3
    `IIf` is a [mere function](https://stackoverflow.com/a/13050787/11683), and it returns a `Variant`. It so happens that, when packing the result into the `Variant` it returns, it provides a copy and not the original value, which happens for non-vbnullstrings too. A copy of `vbNullString` is a zero-length string at a non-null address, which is [not equivalent](https://stackoverflow.com/a/20909528/11683) to `vbNullString` as you have found out. It is equivalent only as far as the VB's `=` comparison goes. – GSerg Dec 20 '22 at 18:38

1 Answers1

4

I experimented a bit. First: I can confirm the behavior.

Then I had a closer look to the difference. I used an intermediate variable to store the 4th parameter and dumped some information. My conclusion: vbNullString returns a null pointer (and CStr(vbNullString)).

However, the IIF-function will not return a null pointer: It needs to copy the content of either the if or the else branch to a new location (a new memory address). The content at this location is again an empty string, but it seems that FindWindowEx does something with it (I am not really familiar with that function).

Const Windowname = "IrfanView"  ' Had to change that
Dim res
Dim hWnd2 As LongPtr
Dim nullStr As String

nullStr = vbNullString
res = FindWindowEx(hWnd2, 0&, Windowname, nullStr)
Debug.Print VarType(res), res, VarType(nullStr), StrPtr(nullStr)

nullStr = CStr(vbNullString)
res = FindWindowEx(hWnd2, 0&, Windowname, nullStr)
Debug.Print VarType(res), res, VarType(nullStr), StrPtr(nullStr) 

nullStr = IIf(1 = 1, vbNullString, vbNullString)
res = FindWindowEx(hWnd2, 0&, Windowname, nullStr)
Debug.Print VarType(res), res, VarType(nullStr), StrPtr(nullStr)

Output:

 20            4134988       8             0 
 20            4134988       8             0 
 20            0             8             2346722344360
FunThomas
  • 23,043
  • 3
  • 18
  • 34
  • 1
    `seems that FindWindowEx does something with it` - yes, it [compares it](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowexa#parameters) to the window captions, thus looking for a window with an empty caption, which is different from looking for a window with any caption. – GSerg Dec 20 '22 at 18:41
  • You miss the "CStr(IIf..." test, that is what I'm surprised to see that doesn't work – 6diegodiego9 Dec 20 '22 at 19:28
  • 2
    @6diegodiego9 The `CStr` does not change the outcome of the `IIf`. – GSerg Dec 20 '22 at 19:30
  • Ok I completely understood the dynamics now, thanks @Greg and @FunThomas! – 6diegodiego9 Dec 20 '22 at 20:08