Using the COM interface from C++ on Win7 [#9508]

Post a reply

Smilies
:D :) :( :o :-? 8) :lol: :x :P :oops: :cry: :evil: :roll: :wink:

BBCode is ON
[img] is ON
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: Using the COM interface from C++ on Win7 [#9508]

Re: Using the COM interface from C++ on Win7 [#9508]

by Peke » Wed Jul 23, 2014 4:25 pm

Hi,
Do not import structure use it as variant /ole variant and force structure than you should not need idl but unless you know exactly what you are doing you will end with error or like you said it is unstable.

I used same approach in last.fm plugin 1.1 and it works great even in full portable. Here is some piece of code.

Code: Select all

uses Windows, ActiveX;

const
     GPPHDR_VER = $10;

const
  CLSID_StdGlobalInterfaceTable : TGUID =
  '{00000323-0000-0000-C000-000000000046}';

type
  IGlobalInterfaceTable = interface(IUnknown)
    ['{00000146-0000-0000-C000-000000000046}']
    function RegisterInterfaceInGlobal (pUnk : IUnknown; const riid: TIID;
      out dwCookie : DWORD): HResult; stdcall;
    function RevokeInterfaceFromGlobal (dwCookie: DWORD): HResult; stdcall;
    function GetInterfaceFromGlobal (dwCookie: DWORD; const riid: TIID;
      out ppv): HResult; stdcall;
  end;
Var
  SDB : Variant;

Code: Select all

function GIT : IGlobalInterfaceTable;
const
  cGIT : IGlobalInterfaceTable = NIL;
var
  mGIT : IGlobalInterfaceTable;
begin
  mGIT := cGIT;
  if (mGIT = NIL) then
    CoCreateInstance (CLSID_StdGlobalInterfaceTable, NIL, CLSCTX_ALL,
      IGlobalInterfaceTable, mGIT);
  Result := mGIT;
end;

procedure MMSetInterfaceCookie( MMInterfCookie : cardinal); cdecl;
var
  intf : IDispatch;

begin
  MMCookie := MMInterfCookie;
  if not PluginInitialized then
  begin
    PluginInitialized := true;
    GIT.GetInterfaceFromGlobal( MMCookie, IDispatch, intf);
    SDB := intf;
  end;
end;

Re: Using the COM interface from C++ on Win7 [#9508]

by emilles » Mon Jul 21, 2014 7:12 pm

Okay, so I took a few leaps of faith from the example (Delphi) general-purpose plug-in and I think I have the new callback implemented correctly:

Code: Select all

static DWORD mmCookie = 0;
extern "C" __declspec(dllexport)
void MMSetInterfaceCookie(DWORD cookie)
{
	mmCookie = cookie;
}

...

	if (mmCookie > 0)
	{
		CComPtr<IGlobalInterfaceTable> pGIT;
		pGIT.CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER);
		pGIT->GetInterfaceFromGlobal(mmCookie, IID_ISDBApplication, (LPVOID*) &sdbApplication);
When MM has registered its COM objects with the local server, this works 100% of the time. However, when MM has not registered (or I forcibly unregister) its objects, the GetInterfaceFromGlobal fails when called as part of the Open() sequence of the output plug-in. But does succeed in other circumstances.

Any ideas as to why this call is spotty when MM is fully portable? That is the case this callback business is supposed to be helping.

Re: Using the COM interface from C++ on Win7 [#9508]

by emilles » Sun Jul 20, 2014 4:31 pm

How would I go about updating the MM IDL that I am using? I got it from http://www.mediamonkey.com/sw/MediaMonkey.idl and it appears unchanged.

Re: Using the COM interface from C++ on Win7 [#9508]

by Peke » Mon Oct 28, 2013 5:56 pm

FYI http://www.ventismedia.com/mantis/view.php?id=9508 is implemented and tested by me so you should be able to easily update your plugin to use it.

Let me know if you wish to make MMIP installation Package?

Re: Using the COM interface from C++ on Win7

by Peke » Fri Oct 11, 2013 8:13 pm

I added OUT_ and IN_ support to http://www.ventismedia.com/mantis/view.php?id=9508 which should help you a lot to make similar thing to my General Plugin Example in http://www.mediamonkey.com/forum/viewto ... 19&t=73936

EDIT: I would Suggest that You update your IDL along with mm_h.c and mm_h.h

Re: Using the COM interface from C++ on Win7

by emilles » Thu Aug 29, 2013 2:50 pm

I managed to figure out the issue with some searching and trial-and-error. It turns out that I have been using the portable installation of MediaMonkey on Windows 7, whereas I have a standard install on my XP machine. The full install registers the MM COM objects with Windows as expected; the portable install does not -- since its portable. Instead of running the full install, I found that the necessary registry additions can be triggered using the portable exe (found deep in a thread on this very forum):

Code: Select all

MediaMonkey.exe /elevate /regcomserver

Re: Using the COM interface from C++ on Win7

by emilles » Mon Aug 26, 2013 10:06 pm

I'm not sure what that means exactly. I import the mm_h.c and mm_h.h files generated from the idl file. But other than that, I am only running the code below as far as COM goes. I should also mention that the result from CoCreateInstance is E_NOINTERFACE. Again, this all works on XP; same code same compiled DLL.

When I right-click on the Visual Studio C++ project file, under Common Properties > Frameworks and References, clicking Add New Reference... only seems to allow me to add project references. I don't see any of the other options that MSDN makes reference to. Note that I am not writing a .NET project. It is native C++.

Re: Using the COM interface from C++ on Win7

by Scottes » Sun Aug 25, 2013 12:02 pm

Did you add a reference to the MM COM object?

Using the COM interface from C++ on Win7 [#9508]

by emilles » Sun Aug 25, 2013 10:30 am

I have been running the following snippet from within an output plug-in for some time now. It works to this day in MM 4.0.7 on Win XP. However on Win 7, it fails to get access to the SDBApplication COM object. Anyone know how to get access to the MM COM interface on Win 7?

Code: Select all

	if (FindWindow(L"TFMainWindow", NULL))
	{
		ISDBApplication* sdbApplication = NULL;
		int result = CoInitialize(NULL);
		try
		{
			result = CoCreateInstance(CLSID_SDBApplication, NULL,
				CLSCTX_LOCAL_SERVER, IID_ISDBApplication, (LPVOID*) &sdbApplication);
			if (result != S_OK) throw result;

Top