Sdk Skin
Last changed: -204.177.179.86

.
SummaryThe Rhino Application Platform (RAP) provides the tools for C++ developers to wrap their application around Rhino 4.0 by creating a custom "Skin".

Overview

Rhino 4.0 allows developers to customize most of Rhino's interface so that the application appears to be their own. We call this a custom Skin. With a custom Skin, you can change the application icon, splash screen, the menu bar, the application title bar, the about box, and the toolbars.

Creating a custom Skin for Rhino involves creating two code modules:

Create the Skin DLL

    1. A CWinApp-derived class. This is the entry point of the DLL.
    2. A CRhinoSkinDLL-derived class. This class allows you to specify Rhino's icon, splash screen and menu. For more information on this class, see rhinoSdkSkinDLL.h.
    3. CSplashWnd. This is a basic implementation of a splash screen class. If you require something fancier, feel free to replace it with your own implementation.

Create the Skin Plug-in

  // Skin DLL menu update handler
  void OnInitPlugInMenuPopups(WPARAM wparam, LPARAM lparam);


  // Skin DLL menu command handler
  BOOL OnPlugInMenuCommand(WPARAM wparam );


  // Change to CRhinoPlugIn::load_plugin_at_startup
  plugin_load_time PlugInLoadTime();


  CRhinoPlugIn::plugin_load_time CSkinPlugInSamplePlugIn::PlugInLoadTime()
  {
    // Override to change load time to "at startup"
    return CRhinoPlugIn::load_plugin_at_startup;
  }
  #include "stdafx.h"
  #include "MySkinPlugIn.h"
  #include "../MySkinDLL/Resource.h"


  // Put these to overrides in a separate CPP file so they could
  // include the MySkinDLL/Resource.h file without conflicting
  // with this projects resource.h


  void CSkinPlugInSamplePlugIn::OnInitPlugInMenuPopups(WPARAM wParam, LPARAM lParam)
  {
    HMENU hMenu = (HMENU)wParam;
    if( NULL == hMenu )
      return;


    switch( GetMenuItemID(hMenu, LOWORD(lParam)) )
    {
      case IDM_SAMPLE_DISABLE:
        ::EnableMenuItem( hMenu, IDM_SAMPLE_DISABLE, 
                          MF_BYCOMMAND|MF_DISABLED|MF_GRAYED );
        break;
      case IDM_SAMPLE_SUB_DISABLE:
        ::EnableMenuItem( hMenu, IDM_SAMPLE_SUB_DISABLE, 
                          MF_BYCOMMAND|MF_DISABLED|MF_GRAYED );
        break;
      // TODO...
    }
  }


  BOOL CSkinPlugInSamplePlugIn::OnPlugInMenuCommand(WPARAM wParam)
  {
    ON_wString w;
    switch( (UINT)wParam )
    {
      case IDM_SAMPLE_ONE:
        w = L"Test Item One";
        break;
      case IDM_SAMPLE_TWO:
        w = L"Two";
        break;
      case IDM_SAMPLE_DISABLE:
        w = L"Disabled";
        break;
      case IDM_SAMPLE_SUB_A:
        w = L"Sub Menu A";
        break;
      case IDM_SAMPLE_SUB_B:
        w = L"Sub Menu B";
        break;
      case IDM_SAMPLE_SUB_DISABLE:
        w = L"Sub Menu Disabled";
        break;
      default:
        return true;
    }


    ::RhinoMessageBox( w, L"OnMenu", MB_OK );
    return true;
  }

Finishing Up

Installation

Item Value
Subkey HKEY_LOCAL_MACHINE\SOFTWARE\McNeel\Rhinoceros\4.0\Scheme: MySkin
Entry name SkinDLLPath
Type REG_SZ
Data value C:\Src\MySkin\MySkinDLL\Release\MySkinDLL.rhs
  "C:\Program Files\Rhinoceros 4.0\System\Rhino4.exe" /scheme=MySkin

Question One

If the user chooses not to run my "skinned" version of Rhino, how can I keep my skin-specific plug-in from loading?

Answer

In your plug-in's OnLoadPlugIn member, check to see if the name of the scheme that Rhino is using matches your skin's scheme name. For example:

  BOOL CSkinPlugInSamplePlugIn::OnLoadPlugIn()
  {
    ON_wString scheme = RhinoApp().RegistrySchemeName();
    if( scheme.CompareNoCase(L"Scheme: MySkin") != 0 )
      return -1; // Fail silently...


    return CRhinoUtilityPlugIn::OnLoadPlugIn();
  }