Return COM 接口中一个函数的多个值
Return multiple values from a function in COM Interfaces
我做了一项研究并为 GetWindowRect
API 实现了一个包装函数,它运行良好。但它目前只能通过 SAFEARRAY
return window 坐标。但是我在想我怎样才能 return 它的实际 return 值。
我是这样声明的:
[id(10)] HRESULT WinAPI_GetWindowRect([in] VARIANT hWnd, [out, retval] SAFEARRAY(VARIANT) *lpRect);
STDMETHOD(WinAPI_GetWindowRect)(VARIANT hWnd, SAFEARRAY **lpRect);
和实现:
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
{ ... }
}
但是,正如我所知,不能有多个 [out, retval]
值,因此非常感谢任何关于如何 return 这个值 (Result
) 的建议。
更新
当我尝试 return 时,它是这样的:
[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);
分配如下:
Result->intVal = (int)GetWindowRect(VariantToHWND(hWnd), &Rect);
我在尝试使用它时在 VBScript 行下方收到 Type mismatch
错误:
Dim lpRect, Result: Result = WINAPI.WinAPI_GetWindowRect(AutoItX3.WinGetHandle("[CLASS:ConsoleWindowClass]"), lpRect)
我希望这个 SAFEARRAY
成为 [out]
参数,Result
成为 return 值。
我通过使用 VARIANT
作为 [out]
参数在一定程度上解决了这个问题:
[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);
新实现:
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
{...}
}
已使用以下 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))
但是,我仍然不能将 SAFEARRAY
用作仅 [out]
参数,将其用作 [out]
仅参数并将 Result
用作 [out, retval]
成员通过以下方式:
[id(10)] HRESULT WinAPI_GetWindowRect([in] VARIANT hWnd, [out] SAFEARRAY(VARIANT) *lpRect, [out, retval] VARIANT *Result);
仍然会导致 Type mismatch
错误。
我做了一项研究并为 GetWindowRect
API 实现了一个包装函数,它运行良好。但它目前只能通过 SAFEARRAY
return window 坐标。但是我在想我怎样才能 return 它的实际 return 值。
我是这样声明的:
[id(10)] HRESULT WinAPI_GetWindowRect([in] VARIANT hWnd, [out, retval] SAFEARRAY(VARIANT) *lpRect);
STDMETHOD(WinAPI_GetWindowRect)(VARIANT hWnd, SAFEARRAY **lpRect);
和实现:
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
{ ... }
}
但是,正如我所知,不能有多个 [out, retval]
值,因此非常感谢任何关于如何 return 这个值 (Result
) 的建议。
更新
当我尝试 return 时,它是这样的:
[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);
分配如下:
Result->intVal = (int)GetWindowRect(VariantToHWND(hWnd), &Rect);
我在尝试使用它时在 VBScript 行下方收到 Type mismatch
错误:
Dim lpRect, Result: Result = WINAPI.WinAPI_GetWindowRect(AutoItX3.WinGetHandle("[CLASS:ConsoleWindowClass]"), lpRect)
我希望这个 SAFEARRAY
成为 [out]
参数,Result
成为 return 值。
我通过使用 VARIANT
作为 [out]
参数在一定程度上解决了这个问题:
[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);
新实现:
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
{...}
}
已使用以下 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))
但是,我仍然不能将 SAFEARRAY
用作仅 [out]
参数,将其用作 [out]
仅参数并将 Result
用作 [out, retval]
成员通过以下方式:
[id(10)] HRESULT WinAPI_GetWindowRect([in] VARIANT hWnd, [out] SAFEARRAY(VARIANT) *lpRect, [out, retval] VARIANT *Result);
仍然会导致 Type mismatch
错误。