INTERACT FORUM

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1]   Go Down

Author Topic: How to write an interface plugin in C++  (Read 13704 times)

sime_george

  • Regular Member
  • Recent member
  • *
  • Posts: 11
  • Change this by choosing profile
How to write an interface plugin in C++
« on: August 05, 2004, 09:29:12 am »

Hi - as a newbie I couldn't find too much info about how to go about writing an interface plugin for MC.  As a result, I've put together a small howto showing how I got it to work.  Let me know if it's useful or just plain wrong !

S

------------------

How to make a Media Center Interface Plugin
===========================================

This assumes the use of Microsoft Visual Studio .NET 2003

First, create the project
-------------------------

Use the Visual Studio new project wizard (File->New->Project)
to create an "ATL Project" (this can be found under
"Visual C++ Projects->ATL" in the wizard). The default Application
Settings (DLL, etc) are fine.

I will assume the project is called "TestATL" - please bear this in
mind when I refer to this as your project will probably be called
something more sensible !

Now add the control
-------------------

This control will the the one visible in Media Center when you click
on your plugin.  Click on Project->Add Class to open the wizard.
Select the ATL Control icon and press Open.  Type in a name for your
control in the Short Name box - Visual Studio will fill in the other
boxes automatically.

I will assume your control is called "Test" - please bear this in mind
as you will probably give your control a better name

Before pressing Finish, click on the Options menu on the left.  From
this page, select Composite Control - this will allow your control
to host other controls. All the other settings are fine so now click
on Finish.

Tell Media Center about your plugin
-----------------------------------

This is done in the DllRegisterServer() method.  By default, this will
be implemented for you so you now have to override it.  Go to the main
project file (in the case of this example, TestATL.cpp).  You will see
a class called CTestATLModule - put the following code in the
"Override CAtlDllModuleT members" part of the public section.

HRESULT   DllRegisterServer()
{
   // Register with Media Center

   TCHAR   cRegistryPath[1024];
   HKEY   hk;
   DWORD   dwDisp;

   wsprintf( cRegistryPath, _T("%s%s"), REGISTRY_PATH_MJ_PLUGINS_INTERFACE, _T("Test") );

   if ( RegCreateKeyEx( HKEY_LOCAL_MACHINE, cRegistryPath,
                  0, NULL, REG_OPTION_NON_VOLATILE,
                  KEY_WRITE, NULL, &hk, &dwDisp ) == ERROR_SUCCESS )
   {
      DWORD   nIVersion    = 1;
      DWORD   nPluginMode    = 1;
      TCHAR*  strCompany   = _T( "Your Company" );
      TCHAR*  strVersion   = _T( "1.0.0" );
      TCHAR*  strURL       = _T( "http://www.yourcompany.com" );
      TCHAR*  strCopyright = _T( "Copyright (c) 2004, You" );
      LPWSTR  strID;

      StringFromCLSID( CLSID_CTest, &strID );

      RegSetValueExW( hk, _T("IVersion"),   0, REG_DWORD, (LPBYTE)&nIVersion,   sizeof(DWORD) );
      RegSetValueExW( hk, _T("PluginMode"), 0, REG_DWORD, (LPBYTE)&nPluginMode, sizeof(DWORD) );

      RegSetValueExW( hk, _T("CLSID"),     0, REG_SZ, (LPBYTE)strID,        _tcslen(strID)*sizeof(TCHAR) );
      RegSetValueExW( hk, _T("Company"),   0, REG_SZ, (LPBYTE)strCompany,   _tcslen(strCompany)*sizeof(TCHAR) );
      RegSetValueExW( hk, _T("Version"),   0, REG_SZ, (LPBYTE)strVersion,   _tcslen(strVersion)*sizeof(TCHAR) );
      RegSetValueExW( hk, _T("URL"),       0, REG_SZ, (LPBYTE)strURL,       _tcslen(strURL)*sizeof(TCHAR) );
      RegSetValueExW( hk, _T("Copyright"), 0, REG_SZ, (LPBYTE)strCopyright, _tcslen(strCopyright)*sizeof(TCHAR) );
   }   

   // Make sure we call the CAtlDllModuleT implementation

   return __super::DllRegisterServer();
}

Of course if your control is called something other than Test then please change the
above accordingly - specifically the CLSID_CTest bit.

Before this code will compile, you'll need to add the following lines to the file.

  // The automatically generated file containing the GUID definitions

  #include "_TestATL_i.c"

  // The Media Center Plugin registry key

  static const TCHAR*   REGISTRY_PATH_MJ_PLUGINS_INTERFACE = _T("Software\\JRiver\\Media Jukebox\\Plugins\\Interface\\");

Additionally, for the above code to compile you will need to setup your project to use
Unicode.  Do this by going to Project->TestATL Properties and changing "Character Set" to
"Use Unicode Character Set" in the General menu.

Implement the Media Center interface
------------------------------------

We're almost done with setting up the plugin.  All that's is that we implement the Init()
interface that Media Center requires all interface plugins to provide.  To do this,
switch to "Class View" in the Visual Studio project window at the top right.  From here,
right click on the ITest interface and choose Add->Add Method.  Enter "Init" for the
method name, check the "in" parameter attribute and select IDispatch* as the parameter
type.  Call the parameter what you want and click Finish.

Compile and see your plugin in Media Center
-------------------------------------------

Hit F7 to build the solution.  If all goes well, Visual Studio will build and then register
your ATL control (have a look in the registry to make sure).  Then start Media Center, go to
Tools->Plugin Manager and then select Interface.  You should see your plugin !  Click on it
and you should see the information you entered in DllRegisterServer().  Just to make sure,
exit the Plugin Manager and select Plugins from the main tree display on the left.  You
should see your plugin !  Clicking on it will show a blank window - but that's because we
haven't actually got our plugin to do anything yet - that's up to you :)

Logged

mediajunkie

  • Regular Member
  • Member
  • *
  • Posts: 1
  • Change this by choosing profile
Re:How to write an interface plugin in C++
« Reply #1 on: August 18, 2004, 09:30:54 am »

I will have to try this out, but do you have any idea what language Media Center is even written in.
Logged

Matt

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 42372
  • Shoes gone again!
Re:How to write an interface plugin in C++
« Reply #2 on: September 10, 2004, 04:52:12 pm »

Thanks for the tutorial.

The source code for the Sleep Timer plugin is available here, which may also be helpful for people: http://www.musicex.com/mediacenter/devzone.html

Thanks again.

(p.s. MC is written in C++ (with a little MMX assembly scattered around))
Logged
Matt Ashland, JRiver Media Center

DaleC21

  • Regular Member
  • Recent member
  • *
  • Posts: 5
  • Change this by choosing profile
Re:How to write an interface plugin in C++
« Reply #3 on: October 20, 2004, 10:20:43 pm »

help George  ;D

c:\Documents and Settings\dcounts\My Documents\Visual Studio Projects\testatl\testatl\testatl.cpp(58): error C2864: 'REGISTRY_PATH_MJ_PLUGINS_INTERFACE' : only const static integral data members can be initialized inside a class or struct

this is where I get the error
from instructions .. and what I put in

____________________________
Before this code will compile, you'll need to add the following lines to the file.

  // The automatically generated file containing the GUID definitions

  #include "_TestATL_i.c"

  // The Media Center Plugin registry key

  static const TCHAR*   REGISTRY_PATH_MJ_PLUGINS_INTERFACE = _T("Software\\JRiver\\Media Jukebox\\Plugins\\Interface\\");

__________________________

it cant include  #include "_TestATL_i.c"

because it doesnt exist .. makes sense
I created it , then it gives the above stat const   error

I have tried and tried .. obvoiously I am missing some critical part
but cant seem to find my error

I am a newbie ... but I have read and reread and tried

any help at all appreciated .. even just a RTFM  ;)

thanks
Dale
Logged
..Dale

sime_george

  • Regular Member
  • Recent member
  • *
  • Posts: 11
  • Change this by choosing profile
Re:How to write an interface plugin in C++
« Reply #4 on: November 06, 2004, 07:41:06 am »

Seems like you are putting the "static const TCHAR* ..." line inside a class - C++ won't let you do this.  Put it in global scope (ie. at the file level rather than inside a class) and it should be fine.
Logged

aseiden

  • Regular Member
  • Recent member
  • *
  • Posts: 8
Re:How to write an interface plugin in C++
« Reply #5 on: November 11, 2004, 12:09:45 am »

Hi there,

thanks very much for the useful tutorial!

I think that I am having the same problem as the other person was.  My 'static const' declare is at global scope, so it isn't complaining about that.  It's having trouble finding the included "_AlexATL_i.c" file.

When I compile, I get this error:

Compiling...
AlexATL.cpp
c:\Documents and Settings\Administrator\My Documents\Visual Studio Projects\AlexATL\AlexATL.cpp(7) : fatal error C1083: Cannot open include file: '_AlexATL_i.c': No such file or directory

I'm not sure what the '_AlexATL_i.c' file is.  I see it in my solution browser under 'AlexATLPS\Generated Files' but when that tries to build, I get this error:

Error: MIDL will not generate DLLDATA.C unless you have at least 1 interface in the main project.
AlexATLPS : error PRJ0002 : error result returned from 'c:\documents and settings\administrator\my documents\visual studio projects\alexatl\debugps\bat00000a.bat'.

I'm sure there's something very simple I need to do, but danged if I can find it!

Thanks very much for any help!

Code: [Select]
Logged

mattsnuts

  • Regular Member
  • Junior Woodchuck
  • **
  • Posts: 82
  • that'll do
Re:How to write an interface plugin in C++
« Reply #6 on: November 28, 2004, 11:54:33 pm »

I had the same problem.

Build it first with the #include "_TestATL_i.c" line commented out.

And comment out the line
    StringFromCLSID( CLSID_CTest, &strID );

Now compile, this should build with errors popping up, just hit Abort.

Having compiled (with errors) the _TestATL_i.c file will have been generated. Now you can uncomment the lines and it should build properly, without the error messages popping up.

So that's where I'm up to with the tutorial - now to check it's worked and to figure out how to add a user interface!

Edit: I've found how to do the interface, double click the TestATL.rc file, then open the Dialog folder - double click IDD_TEST and that's your user inteface.

Now, how do I query the MC database? Presumably we have to import an MC reference?

PS. Thanks Simon for the tute. I'm a C# programmer by trade, I did another plugin in VB, let's see how the ATL goes.

-Matt
Listening to: 'Real (feat. Brad Paisley)' from 'Has Been' by 'William Shatner' on Media Center 9.1
Logged
Pages: [1]   Go Up