首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ATL COM - EnumWindows回调函数不使用IDis修补程序::Invoke

ATL COM - EnumWindows回调函数不使用IDis修补程序::Invoke
EN

Stack Overflow用户
提问于 2017-07-29 04:05:26
回答 1查看 112关注 0票数 1

我正在尝试实现一个包装器函数,以便将EnumWindows API函数包含在我的包装dll中,因此它可以与许多脚本语言一起使用。

首先,我必须使用VBScript测试它。在我有用的研究的帮助下,我为EnumWindows实现了一个包装函数和一个回调函数,但它并不像我想要的那样工作。

下面是我目前的代码:

用于EnumWindowsEnumWindowsProc回调的包装函数:

代码语言:javascript
复制
BOOL CALLBACK EnumWindowsProc(__in HWND hWnd, __in LPARAM lParam) {

    LPENUMWINDOWSPARAMS pewParams;
    VARIANT vhWnd, vResult; HRESULT HR = S_OK;

    VariantInit(&vhWnd);
    VariantInit(&vResult);

    vhWnd.vt = VT_I4;
    vhWnd.lVal = (LONG)(LONG_PTR)hWnd;

    pewParams = reinterpret_cast<LPENUMWINDOWSPARAMS>(lParam);
    // ^ PASSING MY PARAMETERS THROUGH LPARAM

    CComVariant varArgs[2] = { &vResult, &vhWnd };
    DISPPARAMS Parameters = { &varArgs[0], NULL, 2, 0 };

    pewParams->DISPATCH->Invoke(0, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &Parameters, &vResult, NULL, NULL);
    // ^ I SUSPECT SOMETHING IS WRONG WITH THIS INVOKE METHOD. BUT IT RETURNS S_OK.

    if (vResult.vt != VT_BOOL) { HR = DISP_E_TYPEMISMATCH; }

    pewParams->CallbackResult.vt = VT_ERROR;
    pewParams->CallbackResult.scode = HR;

    if (HR == S_OK)
        return (vResult.boolVal == VARIANT_TRUE ? TRUE : FALSE);
    else
        return FALSE;
}

STDMETHODIMP CWinAPI::WinAPI_EnumWindows(VARIANT EnumFunc, int lParam, int *Result) {

    ENUMWINDOWSPARAMS ewParams; HRESULT HR = S_OK;

    switch (EnumFunc.vt)
    {
        case VT_DISPATCH:
            ewParams.DISPATCH = EnumFunc.pdispVal;
            break;

        case VT_VARIANT | VT_BYREF:
            if (EnumFunc.pvarVal->vt == VT_DISPATCH) { ewParams.DISPATCH = EnumFunc.pvarVal->pdispVal; }
            break;

        default: return DISP_E_TYPEMISMATCH;
    }

    ewParams.lParam = reinterpret_cast<LPVARIANT>(&lParam);

    *Result = (int)EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&ewParams));

    HR = ewParams.CallbackResult.scode;

    return HR;
}

ENUMWINDOWSPARAMS结构:

代码语言:javascript
复制
typedef struct tagENUMWINDOWSPARAMS {
    LPDISPATCH DISPATCH;
    LPVARIANT lParam;
    VARIANT CallbackResult;
} ENUMWINDOWSPARAMS, *PENUMWINDOWSPARAMS, *LPENUMWINDOWSPARAMS;

下面是我目前正在使用的测试VBScript:

代码语言:javascript
复制
Dim WINAPI: Set WINAPI = WScript.CreateObject("WinAPIWrapperLib.WINAPI")

Function EnumWindowsProc(HWND, lParam)
    WScript.Echo "Handle to the window: 0x" + CStr(UCase(Hex(HWND)))
    EnumWindowsProc = True
End Function

Dim Result: Result = WINAPI.WinAPI_EnumWindows(GetRef("EnumWindowsProc"), 0)
WScript.Echo "EnumWindows returned " + CStr(Result)

有一件事是可行的,EnumWindows正在返回True。但是,与我所期望的相反,我并没有得到窗口的回响。当我调用GetLastError时,它返回ERROR_SUCCESS

提前感谢您的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-29 04:56:19

我解决了这个问题,没做什么特别的事情,只是一个小小的改变:

varArgs的类型从CComVariant改为VARIANT如下:

代码语言:javascript
复制
VARIANT varArgs[2] = { vResult, vhWnd };

更改了DISPPARAMS如下:

代码语言:javascript
复制
DISPPARAMS Parameters = {};
Parameters.cArgs = 2;
Parameters.rgvarg = varArgs;

Invoke方法仍然相同:

代码语言:javascript
复制
pewParams->DISPATCH->Invoke(0, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &Parameters, &vResult, NULL, NULL);

任何好的建议都将得到进一步的感谢。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45385131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档