COM Expertise needed: COM Callbacks

Mike B Johnson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri May 5 17:54:54 PDT 2017


I've modified the code and it seems to call GetTypeInfo but the 
values passed seem frivolous. The modified code I'm using is 
below. Maybe we can get this to work? I'm interested in a 
photoshop interop too. Seems like it should be rather trivial to 
get to work but things don't add up ;/






module main;
import std.stdio;

import core.sys.windows.winnt;

import Gen;

string Guid2Str(GUID guid)
{
	import std.conv, std.string, std.algorithm;
	auto bytes = cast(byte[16])guid;
	auto a = to!string(*(cast(DWORD*)(bytes[0..4])), 
16).rightJustify(8, '0');
	auto b = to!string(*(cast(WORD*)(bytes[4..6])), 
16).rightJustify(4, '0');
	auto c = to!string(*(cast(WORD*)(bytes[6..8])), 
16).rightJustify(4, '0');
	auto d = to!string(*(cast(BYTE*)(bytes[8..9])), 
16).rightJustify(1, '0');
	auto e = to!string(*(cast(BYTE*)(bytes[9..10])), 
16).rightJustify(1, '0');
	auto q = bytes[10..16];
	reverse(q);
	auto f = to!string(*(cast(long*)(q)) & 0xFFFFFFFFFFFF, 
16).rightJustify(12, '0');

	auto ret = a~"-"~b~"-"~c~"-"~d~e~"-"~f;
	return ret;
}


// Creates a guid from a guid hex string. e.g., 
"B3C35001-B625-48D7-9D3B-C9D66D9CF5F1" -> {0xC09F153E, 0xDFF7, 
0x4EFF, [0xA5, 0x70, 0xAF, 0x82, 0xC1, 0xA5, 0xA2, 0xA8]}
GUID GuidN(string str)
{
	// 3   2   1        5E5C5D5C5B5A4L4H
	// 4dc0c1dbecc8691b 49af51c5f6655e85
	//DEFINE_GUID(IID_INoMarshal,0xecc8691b,0xc1db,0x4dc0,0x85,0x5e,0x65,0xf6,0xc5,0x51,0xaf,0x49);
	//MIDL_INTERFACE("ecc8691b-c1db-4dc0-855e-65f6c551af49")

	import std.string;
	GUID guid;
	auto bytes = cast(byte*)(cast(void*)&guid);
	if (str == "") return IID.init;
	auto parts = split(str, "-"); auto p3 = parts[3].rightJustify(4, 
'0'); auto p4 = parts[4].rightJustify(12, '0');

	*(cast(long*)(bytes[0..8])) = to!long(parts[2].rightJustify(4, 
'0')~parts[1].rightJustify(4, '0')~parts[0].rightJustify(8, '0'), 
16);	
	*(cast(long*)(bytes[8..16])) = 
to!long(p4[10..$]~p4[8..10]~p4[6..8]~p4[4..6]~p4[2..4]~p4[0..2]~p3[2..$]~p3[0..2], 16);

	return guid;
}

int main(string[] argv)
{
	

	// Issue QueryInterface seems to have the issue(not the same 
behavior as what is returned by the PS COM Interface)
	
	auto x = new cApplication();				
	auto x1 = x.Path();
	auto x2 = x.Name();	
	auto x3 = x.SystemInformation();
	auto x4 = x.Version();
	auto e = x.RecentFiles();
	auto g = x.DisplayDialogs();
	auto x5 = x.Documents();
	auto x6 = x5.Count();	


	auto dd = x.ForegroundColor();
	auto __red = dd.RGB().Red();
	auto __green = dd.RGB().Green();
	auto __blue = dd.RGB().Blue();

	GUID clsID = Guid!("4549DC9D-8A15-46F0-A0ED-7DB9C02FCB18");
	GUID iID = Guid!("45F1195F-3554-4B3F-A00A-E1D189C0DC3E");
	auto rgb1 = dd.RGB();
	auto clsids = Guid2Str(rgb1.clsID);
	auto rgb2 = new icRGBColor();
	rgb2.iDispatch = rgb2;
	//auto rgb = cast(icRGBColor)&rgb2;
	//dd.RGB(cast(cRGBColor)(cast(void*)rgb));
	//dd.RGB(cast(icRGBColor)(cast(void*)rgb));


	cSolidColor.RGBSet = &RGB;
	auto rgb = new icRGBColor();
	//auto rgb = cast(icRGBColor)(cast(void*)dd.RGB());
	dd.RGB(rgb, rgb1);
	//dd.RGB2(rgb1);

     return 0;
}


void RGB(icRGBColor ic, cRGBColor c, cSolidColor s)
{
	GUID clsIDa = Guid!("AEADF007-9EE5-41D7-8CB1-AB5F353D1151");
	GUID iIDa = Guid!("D2D1665E-C1B9-4CA0-8AC9-529F6A3D9002");
	ic.iDispatch = s.iDispatch;
	ic.rgb = c;

	import main;
	EXCEPINFO exception;
	uint argErr = 0;
	auto iidNULL = IID_NULL;
	auto RT = new VARIANT();
	VARIANT[1] paramVars;
	DISPPARAMS params = {rgvarg: paramVars.ptr, cArgs: 1, 
cNamedArgs: 0};
	auto ID = s.COMMethodIDs[`RGB`];
	paramVars[0].punkVal = ic; paramVars[0].vt = 
VARENUM.VT_DISPATCH; scope(exit) VariantClear(&paramVars[0]);
	DISPID mydispid = DISPID_PROPERTYPUT;
	params.rgdispidNamedArgs = &mydispid;
	params.cNamedArgs = 1;
	writeln("-----------");
	auto res = s.iDispatch.Invoke(cast(int)ID, &iidNULL, 0, 
DISPATCH_PROPERTYPUT, &params, cast(VARIANT*)RT, &exception, 
&argErr);
	assert(res == S_OK, `Could not invoke COM Function 
cSolidColor.RGB. Error `~to!string(res, 16));

}






//version = wrap;


import std.conv, core.sys.windows.windows, core.sys.windows.com, 
core.sys.windows.wtypes, core.sys.windows.basetyps, 
core.sys.windows.unknwn, core.sys.windows.oaidl;

public class icRGBColor : IDispatch
{


	import std.conv, core.sys.windows.windows, core.sys.windows.com, 
core.sys.windows.wtypes, core.sys.windows.basetyps, 
core.sys.windows.unknwn, core.sys.windows.oaidl;
	public IDispatch iDispatch = null;
	int RefCount = 0;
	cRGBColor rgb;

version(all)
{
	void printFunc(string S = __FUNCTION__)()
	{		
		writeln(S);	
	}

	double Red()
	{ 	
		
		printFunc();
		version(wrap)
			return rgb.Red();
		return 0;
	}

	void Red(double rhs)
	{
		printFunc();
		version(wrap)
			rgb.Red(rhs);
	}

	double Green()
	{

		printFunc();
		version(wrap)
			return rgb.Green();
		return 0;
	}

	void Green(double rhs)
	{


		printFunc();
		version(wrap)
			rgb.Green(rhs);
	}

	double Blue()
	{


		printFunc();
		version(wrap)
			return rgb.Blue();
		return 0;
	}

	void Blue(double rhs)
	{


		printFunc();
		version(wrap)
			rgb.Blue();
	}

	BSTR HexValue()
	{


		printFunc();
		version(wrap)
			return rgb.HexValue();
		return cast(wchar*)(""w.ptr);
	}

	void HexValue(BSTR rhs)
	{


		printFunc();
		version(wrap)
			rgb.HexValue(rhs);
	}

	cApplication Application()
	{

		printFunc();
		return null;
	}
}


/*
	QueryInterface Called: 
00000003-0000-0000-C00-000000000046(GUID), 19F178(Object), 0(Ret)
	QueryInterface Called: 
ECC8691B-C1DB-4DC0-855E-65F6C551AF49(GUID), 19F124(Object), 
80004002(Ret)
	QueryInterface Called: 
00000003-0000-0000-C00-000000000046(GUID), 19EFE8(Object), 0(Ret)

	QueryInterface Called: 
00000003-0000-0000-C00-000000000046(GUID), 19F178(Object)
	main.icRGBColor.GetTypeInfo
*/		

	// IUnknown
	int QueryInterface(const(GUID)* riid, void** pvObject)
	{
		write("QueryInterface Called: ", Guid2Str(*riid), "(GUID), ", 
pvObject, "(Object)");
		version(wrap)
		{			
			auto res = rgb.iDispatch.QueryInterface(riid, pvObject);
			writeln(", ", to!string(res, 16), "(Ret)");
			return res;
		}

		auto guids = [["00000003-0000-0000-C00-000000000046", "0"], 
["ECC8691B-C1DB-4DC0-855E-65F6C551AF49", "0x80004002"]];
		
		foreach(g; guids)
		{
			if (Guid2Str(*riid) == g[0])
			{
				void **pv;
				auto guid = GuidN(g[0]);

				auto x = rgb.iDispatch.QueryInterface(&guid, pv);
				auto res3 = to!int(g[1], 16);
				

				// Always set out parameter to NULL, validating it first.
				if (pvObject is null)
					return E_POINTER;
				*pvObject = null;

				*pvObject = cast(void*)cast(IUnknown)this;

				writeln();
				return res3;

			}
		}

		/*
		auto ress = iDispatch.QueryInterface(riid, pvObject);
		writeln("(", ress, ")");
		return ress;
		*/

		// Always set out parameter to NULL, validating it first.
		if (pvObject is null) return E_POINTER;
		*pvObject = null;

		if (*riid == IID_IUnknown)
		{
			*pvObject = cast(void*)cast(IUnknown)this;
			writeln("\tIUnknown Supported");
		}
		else if (*riid == IID_IDispatch)
		{
			*pvObject = cast(void*)cast(IDispatch)this;
			writeln("\tIDispatch Supported");
		}

	
		// and so on for all interfaces we support
	
		
		if (*pvObject is null)
		{
			writeln("\tNot Supported");
			return E_NOINTERFACE;
		}

		//(cast(IUnknown)this).AddRef();
		return S_OK;

	}


version(all)
{
	uint AddRef()
	{
		
		printFunc();
		version(wrap)
			return rgb.iDispatch.AddRef();
		return ++RefCount;
	}

	uint Release()
	{


		printFunc();
		version(wrap)
			return rgb.iDispatch.Release();
		return --RefCount;
	}



	// IDispatch
	int GetTypeInfoCount(uint* x)
	{

		printFunc();
		auto res = rgb.iDispatch.GetTypeInfoCount(x);
		writeln(res);
		version(wrap)
			return rgb.iDispatch.GetTypeInfoCount(x);
		return res;					
		return 0;
	}
}


	LPTYPEINFO m_ptinfoEnglish;
	LPTYPEINFO m_ptinfoGerman;
	static const auto LCID_ENGLISH = MAKELCID(MAKELANGID(0x09, 
0x01), SORT_DEFAULT);
	static const auto LCID_GERMAN = MAKELCID(MAKELANGID(0x07, 0x01), 
SORT_DEFAULT);

	int GetTypeInfo(uint iTInfo, LCID lcid, LPTYPEINFO* ppTInfo)
	{
		import std.c.stdlib;

		auto xxx = LCID_ENGLISH;
		LPTYPEINFO ptinfo;

		//if (ppTInfo == NULL)
			//return E_INVALIDARG;

//		*ppTInfo = NULL;

//		if(iTInfo != 0)
			//return DISP_E_BADINDEX;

		if(lcid == LOCALE_SYSTEM_DEFAULT || lcid == 0)
			lcid = GetSystemDefaultLCID();

		if(lcid == LOCALE_USER_DEFAULT)
			lcid = GetUserDefaultLCID();

		switch(lcid)
		{
			case LCID_GERMAN:
				ptinfo = m_ptinfoGerman;
				break;

			case LCID_ENGLISH:
				ptinfo = m_ptinfoEnglish;
				break;

			default:
				return DISP_E_UNKNOWNLCID;
		}

		ptinfo.AddRef();
		*ppTInfo = ptinfo;
		return NOERROR;

		//m_ptinfo.AddRef();      // AddRef and return pointer to cached
		// typeinfo for this object.
		//*ppTInfo = m_ptinfo;

		return NOERROR;

		ITypeInfo t;
		auto p = malloc(ITypeInfo.sizeof);
		ppTInfo = &t;
		printFunc();
		//iTInfo  = 0; lcid = 0;
		auto res = rgb.iDispatch.GetTypeInfo(iTInfo, lcid, 
cast(ITypeInfo*)p);
		ppTInfo = cast(ITypeInfo*)p;
		writeln(res);
		version(wrap)
			return rgb.iDispatch.GetTypeInfo(a,b,c);
		return res;
		return 0;
	}

version(all)
{
	int GetIDsOfNames(const(GUID)* a, wchar** b, uint c, uint d, 
int* e)
	{


		printFunc();
		version(wrap)
			return rgb.iDispatch.GetIDsOfNames(a,b,c,d,e);
		return 0;
	}

	int Invoke(int a, const(GUID)* b, uint c, ushort d, DISPPARAMS* 
e, VARIANT* f, EXCEPINFO* g, uint* h)
	{


		printFunc();
		version(wrap)
			return rgb.iDispatch.Invoke(a,b,c,d,e,f,g,h);
		return 0;
	}







	// cRGBColor
	public this()
	{
		printFunc();
	}

}
}






More information about the Digitalmars-d-learn mailing list