2017-07-29 19 views
1

EnumWindowsラッパー関数にラッパー関数を実装しようとしていますので、多くのスクリプト言語で使用できます。ATL COM - EnumWindowsコールバック関数がIDispatch :: Invokeと連携しない

まず、VBScriptを使用してテストする必要がありました。私は有用な研究の助けを借りてEnumWindowsのラッパー関数とコールバック関数を実装しましたが、私が望むようには機能しません。 EnumWindowsEnumWindowsProcコールバックの

ラッパー機能:

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構造:

typedef struct tagENUMWINDOWSPARAMS { 
    LPDISPATCH DISPATCH; 
    LPVARIANT lParam; 
    VARIANT CallbackResult; 
} ENUMWINDOWSPARAMS, *PENUMWINDOWSPARAMS, *LPENUMWINDOWSPARAMS; 

ここでのテストのVBScriptです。ここ

は、私が現在持っているコードがあります私は現在使用:

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) 

一つの作品を、EnumWindowsTrueを返しています。 しかし、私が期待するものの代わりに、私は窓のハンドルをエコーし​​ていません。 GetLastErrorと呼ぶとERROR_SUCCESSを返します。

ご協力いただきありがとうございます。

はこのようVARIANTCComVariantからvarArgsの種類を変更::

VARIANT varArgs[2] = { vResult, vhWnd }; 

は、以下のようにDISPPARAMSを変更:

答えて

1

は、私はそれが唯一の小さな変更だ、行って問題、何も特別な固定しました
DISPPARAMS Parameters = {}; 
Parameters.cArgs = 2; 
Parameters.rgvarg = varArgs; 

Invokeの方法はまだ同じです:

pewParams->DISPATCH->Invoke(0, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &Parameters, &vResult, NULL, NULL); 

さらに良い提案があります。

関連する問題