/******************************************************************************\
*       This is a part of the Microsoft Source Code Samples. 
*       Copyright (C) 1993 Microsoft Corporation.
*       All rights reserved. 
*       This source code is only intended as a supplement to 
*       Microsoft Development Tools and/or WinHelp documentation.
*       See these sources for detailed information regarding the 
*       Microsoft samples programs.
\******************************************************************************/

/*----------------------------------------------------------------------------
|                                                                              |
*|   idisp.cpp    - Windows message spy application                               |
|                                                                              |
\*----------------------------------------------------------------------------*/


#include <windows.h>
#include <ole2.h>
#include <oleauto.h>
#include <tchar.h>
#include <oleacc.h>
#include "hook.h"



// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
//
//    iDispatch interface support.
//
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------


HRESULT Call_accChildren(IDispatch FAR* pdisp, IDispatch FAR** ppdispChildren)
{
	HRESULT hr;
	OLECHAR FAR* szMember = L"accChildren";
	DISPID dispid;
	DISPPARAMS dispparams = {NULL, NULL, 0, 0};
//      VARIANTARG FAR varg[1];
	VARIANTARG varResult;
	UINT uArgErr;
	EXCEPINFO excepinfo;

	PrintDebug("Entered Call_accChildren");

    // Get the id for the member funciton we want to call
	hr = pdisp->GetIDsOfNames(
		IID_NULL, &szMember, 1,
		LOCALE_SYSTEM_DEFAULT, &dispid);
        if (IsHResultError(hr, "GetIDsOfName")) return hr;
	PrintDebug("Member dispid: %lx", dispid);

	// Prepare the params
/*
	VariantInit(varg);
	varg[0].vt = VT_BYREF | VT_DISPATCH;
	varg[0].ppdispVal = ppdispChildren;
	dispparams.rgvarg = varg;
	dispparams.rgdispidNamedArgs = 0;
	dispparams.cArgs = 1;
	dispparams.cNamedArgs = 0;
*/
	// Call member function
	hr = pdisp->Invoke(
		dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
		//DISPATCH_PROPERTYGET, &dispparams, NULL,
		DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dispparams, &varResult,
		&excepinfo, &uArgErr);
        if (IsHResultError(hr, "Invoke")) return hr;
	else 
	{
		if (varResult.vt != VT_DISPATCH) PrintDebug("va != VT_DISPATCH!");
		*ppdispChildren = varResult.pdispVal;
	}

	return hr;
}

HRESULT Call_accName(IDispatch FAR* pdisp, BSTR *pbstr)
{
	HRESULT hr;
	OLECHAR FAR* szMember = L"accName";
	DISPID dispid;
	DISPPARAMS dispparams = {NULL, NULL, 0, 0};
	//VARIANTARG FAR varg[1];
	//BSTR bstr=NULL;
	UINT uArgErr;
	VARIANT varResult;
	EXCEPINFO excepinfo;

	PrintDebug("Entered Call_accName");

    // Get the id for the member funciton we want to call
	hr = pdisp->GetIDsOfNames(
		IID_NULL, &szMember, 1,
		LOCALE_SYSTEM_DEFAULT, &dispid);
        if (IsHResultError(hr, "GetIDsOfName")) return hr;
	PrintDebug("Member dispid: %lx", dispid);

	// Prepare the params
/*
	bstrObjName = SysAllocString(L" ");
	VariantInit(varg);
	varg[0].vt = VT_BYREF | VT_BSTR;
	varg[0].pbstrVal = &bstrObjName;
	dispparams.rgvarg = varg;
	dispparams.rgdispidNamedArgs = 0;
	dispparams.cArgs = 1;
	dispparams.cNamedArgs = 0;
*/
	// Call member function
	hr = pdisp->Invoke(
//              dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
		dispid, IID_NULL, 1033,
//             DISPATCH_PROPERTYGET, &dispparams, NULL,
	       DISPATCH_PROPERTYGET|DISPATCH_METHOD, &dispparams, &varResult,
		&excepinfo, &uArgErr);
        if (IsHResultError(hr, "Invoke")) return hr;
	else
	{
		char buf[64];
		if (varResult .vt != VT_BSTR) PrintDebug("vt != VT_BSTR!");
		*pbstr = varResult.bstrVal;
		BstrToStr(buf, *pbstr);
		PrintDebug("%s", buf);
	}

	return hr;
}

HRESULT Call_accNameStr(IDispatch FAR* pdisp, LPSTR str)
{
	HRESULT hr;
	BSTR bstr;
	hr = Call_accName(pdisp, &bstr);
	BstrToStr(str, bstr);
	SysFreeString(bstr);
	return hr;
}

HRESULT Call_accHelpDescription(IDispatch FAR* pdisp, BSTR *pbstr)
{
	HRESULT hr;
	OLECHAR FAR* szMember = L"accHelpDescription";
	DISPID dispid;
	DISPPARAMS dispparams = {NULL, NULL, 0, 0};
	//VARIANTARG FAR varg[1];
	//BSTR bstr=NULL;
	VARIANTARG varResult;
	UINT uArgErr;
	EXCEPINFO excepinfo;

	PrintDebug("Entered Call_accHelpDescription");

    // Get the id for the member funciton we want to call
	hr = pdisp->GetIDsOfNames(
		IID_NULL, &szMember, 1,
		LOCALE_SYSTEM_DEFAULT, &dispid);
        if (IsHResultError(hr, "GetIDsOfName")) return hr;
	PrintDebug("Member dispid: %lx", dispid);

	// Prepare the params
/*
	bstrHelpDescription = SysAllocString(L" ");
	VariantInit(varg);
	varg[0].vt = VT_BYREF | VT_BSTR;
	varg[0].pbstrVal = &bstrHelpDescription;
	dispparams.rgvarg = varg;
	dispparams.rgdispidNamedArgs = 0;
	dispparams.cArgs = 1;
	dispparams.cNamedArgs = 0;
*/
	// Call member function
	hr = pdisp->Invoke(
		dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
	       DISPATCH_PROPERTYGET, &dispparams, &varResult,
		&excepinfo, &uArgErr);
        if (IsHResultError(hr, "Invoke")) return hr;
	else
	{
		char buf[64];
		*pbstr = varResult.bstrVal;
		BstrToStr(buf, *pbstr);
		PrintDebug("%s", buf);
	}

	return hr;
}

HRESULT Call_accHelpDescriptionStr(IDispatch FAR* pdisp, LPSTR str)
{
	HRESULT hr;
	BSTR bstr;
	hr = Call_accHelpDescription(pdisp, &bstr);
	BstrToStr(str, bstr);
	SysFreeString(bstr);
	return hr;
}

HRESULT Call_accSelection(IDispatch FAR* pdisp, IDispatch FAR** ppdispSelection)
{
	HRESULT hr;
	OLECHAR FAR* szMember = L"accSelection";
	DISPID dispid;                                                                                                          DISPPARAMS dispparams = {NULL, NULL, 0, 0};
	//VARIANTARG FAR varg[1];
	VARIANTARG varResult;
	UINT uArgErr;
	EXCEPINFO excepinfo;

	PrintDebug("Entered Call_accSelection");

    // Get the id for the member funciton we want to call
	hr = pdisp->GetIDsOfNames(
		IID_NULL, &szMember, 1,
		LOCALE_SYSTEM_DEFAULT, &dispid);
        if (IsHResultError(hr, "GetIDsOfName")) return hr;
	PrintDebug("Member dispid: %lx", dispid);

	// Prepare the params
/*
	VariantInit(varg);
	varg[0].vt = VT_BYREF | VT_DISPATCH;
	varg[0].ppdispVal = ppdispSelection;
	dispparams.rgvarg = varg;
	dispparams.rgdispidNamedArgs = 0;
	dispparams.cArgs = 1;
	dispparams.cNamedArgs = 0;
*/
	// Call member function
	hr = pdisp->Invoke(
		dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
//              DISPATCH_PROPERTYGET, &dispparams, NULL,
	       DISPATCH_PROPERTYGET, &dispparams, &varResult,
		&excepinfo, &uArgErr);
        if (IsHResultError(hr, "Invoke")) return hr;
	{
		if (varResult.vt != VT_DISPATCH) PrintDebug("va != VT_DISPATCH!");
		*ppdispSelection = varResult.pdispVal;
	}


	return hr;
}

HRESULT Call_accKeyboardFocus(IDispatch FAR* pdisp, IDispatch FAR** ppdispKeyboardFocus)
{
	HRESULT hr;
	OLECHAR FAR* szMember = L"accKeyboardFocus";
	DISPID dispid;
	DISPPARAMS dispparams = {NULL, NULL, 0, 0};
	//VARIANTARG FAR varg[1];
	VARIANTARG varResult;
	UINT uArgErr;
	EXCEPINFO excepinfo;

	PrintDebug("Entered Call_accKeyboardFocus");

    // Get the id for the member funciton we want to call
	hr = pdisp->GetIDsOfNames(
		IID_NULL, &szMember, 1,
		LOCALE_SYSTEM_DEFAULT, &dispid);
        if (IsHResultError(hr, "GetIDsOfName")) return hr;
	PrintDebug("Member dispid: %lx", dispid);

	// Prepare the params
/*
	VariantInit(varg);
	varg[0].vt = VT_BYREF | VT_DISPATCH;
	varg[0].ppdispVal = ppdispKeyboardFocus;
	dispparams.rgvarg = varg;
	dispparams.rgdispidNamedArgs = 0;
	dispparams.cArgs = 1;
	dispparams.cNamedArgs = 0;
*/
	// Call member function
	hr = pdisp->Invoke(
		dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
//              DISPATCH_PROPERTYGET, &dispparams, NULL,
	       DISPATCH_PROPERTYGET, &dispparams, &varResult,
		&excepinfo, &uArgErr);
        if (IsHResultError(hr, "Invoke")) return hr;
	{
		if (varResult.vt != VT_DISPATCH) PrintDebug("va != VT_DISPATCH!");
		*ppdispKeyboardFocus = varResult.pdispVal;
	}

	return hr;
}

HRESULT Call_accRoles(IDispatch FAR* pdisp, BSTR *pbstr)
{
	HRESULT hr;
	OLECHAR FAR* szMember = L"accRoles";
	DISPID dispid;
	DISPPARAMS dispparams = {NULL, NULL, 0, 0};
	//VARIANTARG FAR varg[1];
	//BSTR bstr=NULL;
	VARIANTARG varResult;
	UINT uArgErr;
	EXCEPINFO excepinfo;

	PrintDebug("Entered Call_accRoles");

    // Get the id for the member funciton we want to call
	hr = pdisp->GetIDsOfNames(
		IID_NULL, &szMember, 1,
		LOCALE_SYSTEM_DEFAULT, &dispid);
        if (IsHResultError(hr, "GetIDsOfName")) return hr;
	PrintDebug("Member dispid: %lx", dispid);

	// Prepare the params
/*
	bstrRoles = SysAllocString(L" ");
	VariantInit(varg);
	varg[0].vt = VT_BYREF | VT_BSTR;
	varg[0].pbstrVal = &bstrRoles;
	dispparams.rgvarg = varg;
	dispparams.rgdispidNamedArgs = 0;
	dispparams.cArgs = 1;
	dispparams.cNamedArgs = 0;
*/
	// Call member function
	hr = pdisp->Invoke(
		dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
	       DISPATCH_PROPERTYGET, &dispparams, &varResult,
		&excepinfo, &uArgErr);
        if (IsHResultError(hr, "Invoke")) return hr;
	else
	{
		char buf[64];
		*pbstr = varResult.bstrVal;
		BstrToStr(buf, *pbstr);
		PrintDebug("%s", buf);
	}

	return hr;
}

HRESULT Call_accRolesStr(IDispatch FAR* pdisp, LPSTR str)
{
	HRESULT hr;
	BSTR bstr;
	hr = Call_accRoles(pdisp, &bstr);
	BstrToStr(str, bstr);
	SysFreeString(bstr);
	return hr;
}

HRESULT Call_accPosition(IDispatch FAR* pdisp, 
	long *pxLeft, long *pyTop, long *pxWidth, long *pyHight)
{
	HRESULT hr;
	OLECHAR FAR* szMember = L"accPosition";
	DISPID dispid;
	DISPPARAMS dispparams = {NULL, NULL, 0, 0};
	VARIANTARG FAR varg[4];

	PrintDebug("Entered Call_accPosition");

    // Get the id for the member funciton we want to call
	hr = pdisp->GetIDsOfNames(
		IID_NULL, &szMember, 1,
		LOCALE_SYSTEM_DEFAULT, &dispid);
        if (IsHResultError(hr, "GetIDsOfName")) return hr;
	PrintDebug("Member dispid: %lx", dispid);

	// Prepare the params
	VariantInit(varg);
	varg[0].vt = VT_BYREF | VT_I4; varg[0].plVal = (long*)pyHight;
	varg[1].vt = VT_BYREF | VT_I4; varg[1].plVal = (long*)pxWidth;
	varg[2].vt = VT_BYREF | VT_I4; varg[2].plVal = (long*)pyTop;
	varg[3].vt = VT_BYREF | VT_I4; varg[3].plVal = (long*)pxLeft;

	dispparams.rgvarg = varg;
	dispparams.rgdispidNamedArgs = 0;
	dispparams.cArgs = 4;
	dispparams.cNamedArgs = 0;

	// Call member function
	hr = pdisp->Invoke(
		dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
		DISPATCH_METHOD, &dispparams, NULL,
		NULL, NULL);
        if (IsHResultError(hr, "Invoke")) return hr;

	return hr;
}

HRESULT dispGetObjectInfo(IDispatch FAR* pdisp, OACOBJINFO *poi)
{
    HRESULT hr=S_OK;

    if (!pdisp || !poi) {PrintDebug("Invalid params"); return E_INVALIDARG;}

    hr = Call_accChildren(pdisp, &poi->pdispChildren);
    if (hr == S_OK) poi->pdispChildren->Release;
    else goto EXIT1;

    hr = Call_accNameStr(pdisp, poi->szObjName);
    if (hr != S_OK) goto EXIT1;

    hr = Call_accHelpDescriptionStr(pdisp, poi->szHelp);
    if (hr != S_OK) goto EXIT1;

    hr = Call_accSelection(pdisp, &poi->pdispSelection);
    if (hr == S_OK) poi->pdispSelection->Release;
    else goto EXIT1;

    hr = Call_accKeyboardFocus(pdisp, &poi->pdispKeyboardFocus);
    if (hr == S_OK) poi->pdispKeyboardFocus->Release;
    else goto EXIT1;

    hr = Call_accRolesStr(pdisp, poi->szRole);
    if (hr != S_OK) goto EXIT1;

    hr = Call_accPosition(pdisp, &poi->xLeft, &poi->yTop, &poi->xWidth, &poi->yHight);
    if (hr != S_OK) goto EXIT1;

EXIT1:
    if (hr == S_OK)
    {
        PrintDebug("xLeft %lu, yTop %lu, xWidth %lu, yHight %lu",
        poi->xLeft, poi->yTop, poi->xWidth, poi->yHight);
    }

    PrintDebug("GetObjectInfo exit");

    return hr;
}




