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

This forum is for questions / discussions regarding development of addons / tweaks for MediaMonkey for Windows 4.

Moderators: Gurus, Addon Administrators

emilles
Posts: 16
Joined: Tue Apr 11, 2006 9:01 pm
Contact:

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

Post by emilles »

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;
Remote Speakers output plug-in
Stream audio from MediaMonkey to any AirPlay device
Scottes
Posts: 150
Joined: Sat Mar 21, 2009 6:51 am

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

Post by Scottes »

Did you add a reference to the MM COM object?
emilles
Posts: 16
Joined: Tue Apr 11, 2006 9:01 pm
Contact:

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

Post by emilles »

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++.
Remote Speakers output plug-in
Stream audio from MediaMonkey to any AirPlay device
emilles
Posts: 16
Joined: Tue Apr 11, 2006 9:01 pm
Contact:

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

Post by emilles »

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
Remote Speakers output plug-in
Stream audio from MediaMonkey to any AirPlay device
Peke
Posts: 17457
Joined: Tue Jun 10, 2003 7:21 pm
Location: Earth
Contact:

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

Post by Peke »

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
Best regards,
Peke
MediaMonkey Team lead QA/Tech Support guru
Admin of Free MediaMonkey addon Site HappyMonkeying
Image
Image
Image
How to attach PICTURE/SCREENSHOTS to forum posts
Peke
Posts: 17457
Joined: Tue Jun 10, 2003 7:21 pm
Location: Earth
Contact:

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

Post by Peke »

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?
Best regards,
Peke
MediaMonkey Team lead QA/Tech Support guru
Admin of Free MediaMonkey addon Site HappyMonkeying
Image
Image
Image
How to attach PICTURE/SCREENSHOTS to forum posts
emilles
Posts: 16
Joined: Tue Apr 11, 2006 9:01 pm
Contact:

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

Post by emilles »

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.
Remote Speakers output plug-in
Stream audio from MediaMonkey to any AirPlay device
emilles
Posts: 16
Joined: Tue Apr 11, 2006 9:01 pm
Contact:

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

Post by emilles »

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.
Remote Speakers output plug-in
Stream audio from MediaMonkey to any AirPlay device
Peke
Posts: 17457
Joined: Tue Jun 10, 2003 7:21 pm
Location: Earth
Contact:

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

Post by Peke »

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;
Best regards,
Peke
MediaMonkey Team lead QA/Tech Support guru
Admin of Free MediaMonkey addon Site HappyMonkeying
Image
Image
Image
How to attach PICTURE/SCREENSHOTS to forum posts
Post Reply