I did a research and implemented a wrapper function for GetWindowRect
API, and it works fine. But it can currently only return window coordinates via a SAFEARRAY
. But I am thinking about how can I also return its actual return value.
I declared it like this:
[id(10)] HRESULT WinAPI_GetWindowRect([in] VARIANT hWnd, [out, retval] SAFEARRAY(VARIANT) *lpRect);
STDMETHOD(WinAPI_GetWindowRect)(VARIANT hWnd, SAFEARRAY **lpRect);
And implementation:
STDMETHODIMP CWinAPI::WinAPI_GetWindowRect(VARIANT hWnd, SAFEARRAY **lpRect {
CComSafeArray<VARIANT> CCSA_RECT;
RECT Rect;
HRESULT HResult;
if (!lpRect) { return E_INVALIDARG; }
*lpRect = nullptr;
int Result = (int)GetWindowRect(VariantToHWND(hWnd), &Rect);
// ^ I ALSO WANT TO RETURN THIS RESULT TOO
if (Result != 0)
{
HResult = CCSA_RECT.Create(4, 0);
assert(HResult == S_OK);
CCSA_RECT[0] = Rect.left;
CCSA_RECT[1] = Rect.top;
...
}
else
{ ... }
}
But, as I already know, there cannot be multiple [out, retval]
values, so any suggestions on how to return this value (Result
) are highly appreciated.
UPDATE
When I try to return it like this:
[id(10)] HRESULT WinAPI_GetWindowRect([in] VARIANT hWnd, [out] SAFEARRAY(VARIANT) *lpRect, [out, retval] VARIANT *Result);
STDMETHOD(WinAPI_GetWindowRect)(VARIANT hWnd, SAFEARRAY **lpRect, VARIANT *Result);
Assigning it like:
Result->intVal = (int)GetWindowRect(VariantToHWND(hWnd), &Rect);
I am getting a Type mismatch
error in below VBScript line when try to use it:
Dim lpRect, Result: Result = WINAPI.WinAPI_GetWindowRect(AutoItX3.WinGetHandle("[CLASS:ConsoleWindowClass]"), lpRect)
I want this SAFEARRAY
to be [out]
parameter and Result
to be return value.
I solved the problem to a some extent by using a VARIANT
as [out]
parameter like this:
[id(10)] HRESULT WinAPI_GetWindowRect([in] VARIANT hWnd, [out] VARIANT *Result, [out, retval] SAFEARRAY(VARIANT) *lpRect);
STDMETHOD(WinAPI_GetWindowRect)(VARIANT hWnd, VARIANT *Result, SAFEARRAY **lpRect);
New implementation:
STDMETHODIMP CWinAPI::WinAPI_GetWindowRect(VARIANT hWnd, VARIANT *Result, SAFEARRAY **lpRect) {
CComSafeArray<VARIANT> CCSA_RECT;
RECT Rect;
HRESULT HResult;
if (!lpRect) { return E_INVALIDARG; }
*lpRect = nullptr;
VariantInit(Result);
Result->vt = VT_I2;
Result->intVal = (int)GetWindowRect(VariantToHWND(hWnd), &Rect);
if (Result->intVal != 0)
{...}
else
{...}
}
This has been tested using the following VBScript:
Dim AutoItX3: Set AutoItX3 = WScript.CreateObject("AutoItX3.Control")
Dim WINAPI: Set WINAPI = WScript.CreateObject("WinAPIWrapperLib.WINAPI")
Dim lpRect, Result: lpRect = WINAPI.WinAPI_GetWindowRect(AutoItX3.WinGetHandle("[CLASS:ConsoleWindowClass]"), Result)
WScript.Echo "GetWindowRect returned: " + CStr(Result)
If CInt(Result) <> 0 Then
For iNum = 0 To UBound(lpRect)
WScript.Echo CStr(lpRect(iNum))
Next
End If
WScript.Echo(CStr(WINAPI.WinAPI_GetLastErrorMessage))
But, I still cannot use SAFEARRAY
as an [out]
only parameter, using it as [out]
only parameter and using Result
as [out, retval]
member in following way:
[id(10)] HRESULT WinAPI_GetWindowRect([in] VARIANT hWnd, [out] SAFEARRAY(VARIANT) *lpRect, [out, retval] VARIANT *Result);
still causes the Type mismatch
error.