2011/7/8 - 2011/8/27
Pen Jr.D言語なんてやってみそCOMRibbon
Framework
Windows Ribbon Framework

Scenic Ribbon の基礎

Ribbon Markup(XAML)
Creating a Ribbon Application
<application.commands>
  <!--
  コンパイラ(UICC)で出力される .h ファイルに関連するもの
  読み込むリソース(文字列や画像)の指定
  
  ここで定義したコマンド名もしくはid(値)を使うことになる
  -->
</application.commands>
<application.views>
  <!--
  UIの表示を記述
  -->
</application.views>
<?xml version='1.0' encoding='utf-8'?>
<Application xmlns="http://schemas.microsoft.com/windows/2009/Ribbon">
  <Application.Commands>
    <Command Name="cmdHome" LabelTitle="ホーム" />
  </Application.Commands>
  <Application.Views>
    <Ribbon>
      <Ribbon.ApplicationMenu>
        <ApplicationMenu>
        </ApplicationMenu>
      </Ribbon.ApplicationMenu>
      <Ribbon.QuickAccessToolbar>
        <QuickAccessToolbar>
        </QuickAccessToolbar>
      </Ribbon.QuickAccessToolbar>
      <Ribbon.Tabs>
        <Tab CommandName="cmdHome">
        </Tab>
      </Ribbon.Tabs>
    </Ribbon>
  </Application.Views>
</Application>
UICC
D:\Pen-Jr\My Programs\Ribbons>uicc ribbon.xml ribbon.bml /res:ribbon.rc /header:
ribbon.h
ribbon.xml(9): warning SC2001 : Undefined Command on element.
Header file generation successful: 'ribbon.h'.
Ribbon markup file validation successful: 'ribbon.xml'.
Ribbon resource file generation successful: 'ribbon.rc'.
インターフェイス
Ribbon で使うインターフェイスはいくつもありますが、とりあえず表示に必要なものから
Scenic インターフェイス
プラットフォームで実装されてるインターフェイス
CoCreateInstance
IUIFramework
アプリケーション インターフェイス
ホスト側で実装する必要があるインターフェイス
IUIApplication
Header File
自前ヘッダー
サンプル
import core.runtime;
import win32.windows, win32.uiribbon;

pragma( lib, "win32.lib" );
pragma( lib, "ole32.lib" );

class CsRibbonApp : IUIApplication{
  private{
    LONG  nCount = 0;
  }
  public:
  this(){
    AddRef();
  }
  extern( System ){
    HRESULT QueryInterface( REFIID riid, void** ppvObject ){
      if( *riid == IID_IUnknown ){
        *ppvObject = cast( void* )cast( IUnknown )this;
      }
      else if( *riid == IID_IUIApplication ){
        *ppvObject = cast( void* )cast( IUIApplication )this;
      }
      else{
        ppvObject = null;
        return E_FAIL;
      }
      AddRef();
      return S_OK;
    }
    ULONG AddRef(){
      return InterlockedIncrement( &nCount );
    }
    ULONG Release(){
      scope( exit ){
        if( lRef == 0 ) delete this;
      }
      auto lRef = InterlockedDecrement( &nCount );
      return cast( ULONG )lRef;
    }
    
    HRESULT OnViewChanged(
        UINT32 viewId, UI_VIEWTYPE typeId,
        IUnknown pView, UI_VIEWVERB verb,
        INT32 uReasonCode
      ){
      return E_NOTIMPL;
    }
    HRESULT OnDestroyUICommand(
      UINT32 nCmdId, UI_COMMANDTYPE typeId,
      IUICommandHandler commandHandler
      ){
      return E_NOTIMPL;
    }
    HRESULT OnCreateUICommand(
      UINT32 nCmdId, UI_COMMANDTYPE typeId,
      IUICommandHandler* ppCommandHandler
      ){
      return E_NOTIMPL;
    }
  }
}

CsRibbonApp csRibbonApp;
IUIFramework iuiFramework;

extern( Windows ){
  int MyWndProc( HWND hw, UINT msg, WPARAM wp, LPARAM lp ){
    switch( msg ){
      case WM_CREATE:
        auto hr =
        .CoCreateInstance(
            &CLSID_UIRibbonFramework,
            null,
            CLSCTX_INPROC_SERVER,
            &IID_IUIFramework,
            cast( void** )&iuiFramework
          );
        if( hr >= 0 ){
          // 普通に new で問題ない様子
          csRibbonApp = new CsRibbonApp();
          
          hr = iuiFramework.Initialize( hw, csRibbonApp );
          if( hr >= 0 ){
            iuiFramework.LoadUI(
                .GetModuleHandle( null ), "APPLICATION_RIBBON"
              );
          }
        }
        break;
      case WM_DESTROY:
        .PostQuitMessage( 0 );
        break;
      default:
    }
    return .DefWindowProc( hw, msg, wp, lp );
  }
  
  int WinMain(
    HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPTSTR lpCmdLine, int nCmdShow
    ){
    int ret;
    void exc( Throwable e ){
      throw e;
    }
    try{
      Runtime.initialize( &exc );
      
      // COM を使うなら
      .CoInitialize( null );
      
      ret = myMain( hInstance );
      
      .CoUninitialize();
      Runtime.terminate( &exc );
    }
    catch( Throwable o ){
      .MessageBox( null, cast( LPWSTR )o.toString, "Hellow", MB_OK );
    }
    return ret;
  }
}

int myMain( HINSTANCE hinst ){
  WNDCLASSEX wc;
  with( wc ){
    cbSize        = WNDCLASSEX.sizeof;
    hInstance     = hinst;
    style         = CS_HREDRAW | CS_VREDRAW;
    lpszClassName = "MyHellow";
    lpfnWndProc   = &MyWndProc;
    hCursor       = .LoadCursor( null, IDC_ARROW );
    hbrBackground = cast( HBRUSH )( COLOR_WINDOW + 1 );
  }
  
  .CreateWindowEx(
    0,
    cast( LPWSTR ).RegisterClassEx( &wc ), "Hellow",
    WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    CW_USEDEFAULT, CW_USEDEFAULT,
    600, 500,     // あまり小さいと Ribbon が表示されない
    null, null, hinst, null
    );
  
  for( MSG msg; .GetMessage( &msg, null, 0, 0 ) > 0; ){
    .TranslateMessage( &msg );
    .DispatchMessage( &msg );
  }
  
  if( iuiFramework !is null ){
    iuiFramework.Release();
  }
  
  return 0;
}
Window
Ribbons.zip のダウンロード

2011年7月8日

E-Mail : open@pen-jr.org

ご意見やご指摘は大歓迎ですが、質問など返信は期待しないでください

pen jr.
D言語研究
わかったつもりになるD言語
D言語友の会
News&Days
はじめてのブログ選び