« C4D オブジェクトに適用したマテリアルをXPressoで入れ替えるには… どうするの…? | トップページ | TMSより CINEMA 4D R11.5チュートリアル【PDF版】が発売… »

C4D プラグインとダイアログとリソース

今まで、このブログではプラグインのダイアログは、直接コードとして書き込んでいました。
これを、リソースと言う形式で、外部のファイルとして用意する事ができます。

このリソースの利点は、ダイアログのローカライズが容易に行えます。
日本語、英語、ドイツ語…
対応する言語用のフォルダを用意し、ファイルを格納します。
直接コードに書き込むと、ローカライズはコードを変更しなければなりません。

プラグイン本体の変更なしでダイアログレイアウトを変えることができます。

今回は、SDKやこのブログを参考にしてプラグインを作成できるユーザが対象です。
コードの詳しい説明はいたしません。

まずは、プラグインのファイル構成です。

多分… リソースを使わない単純なプラグインは、プラグイン本体の「cof」ファイルとアイコン用の画像ファイルの2個の構成だと思います。
アイコンの無い場合もあるかもしれません。
この2つのファイルをフォルダにまとめてあると思います。

Dialogresource_15_2

リソースを使った場合は…

Dialogresource_16

resフォルダ:レイアウト構成データ
  c4d_symbols.hには、ガジェットのID用の定数が格納されます。
strings_usフォルダ:英語表示用データ
  myDialog.strには、英語表示用データが格納されます。
strings_jpフォルダ:日本語表示用データ
  myDialog.strには、日本語表示用データが格納されます。

フォルダ名「strings_us」や「strings_jp」等が間違っているとリソース自体が読み込めませんので、注意が必要です。

まずは、今まで通りのダイアログレイアウトを含んだコードです。

/*
TestResource
2009.12.9
*/



var pluginID = 1000005;
//--------------------------------------------------------------------
enum{
  TEST_GROUP = 1000,
  TEST_NAME,
  TEST_EDIT
}
//--------------------------------------------------------------------
class TestResDialog : GeModalDialog
{
  public:
    TestResDialog();
    CreateLayout();
    Init();
    AskClose();
}

TestResDialog::TestResDialog(){super();}

TestResDialog::CreateLayout(){
  SetTitle("TestDialog");
  AddGroupBeginV(TEST_GROUP , BFH_SCALEFIT , 2 , "TestGroup" , 0);
    AddGroupBorder(BORDER_GROUP_IN);
    AddGroupBorderSpace(4 , 4 , 4 , 4);

    AddStaticText(TEST_NAME , BFH_SCALEFIT , 0 , 0 , "TestName" , 0);
    AddEditText(TEST_EDIT , BFH_SCALEFIT , 0 , 0);
  AddGroupEnd();
 
  AddSeparatorH(0);
 
  AddDlgGroup(DR_DLGGROUP_OK + DR_DLGGROUP_CANCEL);
}

TestResDialog::Init(){
 
}

TestResDialog::AskClose(){
 
}

//--------------------------------------------------------------------
class TestRes : MenuPlugin
{
  public:
    TestRes();
    GetID();
    GetName();
    GetHelp();
    GetIcon();
    GetState();
    Execute(doc);
}

TestRes::TestRes(){super();}
TestRes::GetID(){return pluginID;}
TestRes::GetName(){return "TestRes";}
TestRes::GetHelp(){return "TestRes";}

TestRes::GetIcon(){
  var icon = new(BaseBitmap , 32 , 32);
  return icon;
}

TestRes::GetState(){return CMD_ENABLED;}

TestRes::Execute(doc){
  var dlg = new(TestResDialog);
  dlg->Open(-1 , -1);

  println("Test OK?");
}


//--------------------------------------------------------------------

main()
{
  Register(TestRes);
  println("TestRes ID: " , pluginID);
}

「TestRes.ZIP」

Pluginsフォルダにインストールすると、プラグインとして認識します。
但し実行部分には、ダイアログを開く以外、処理が無いので何も起こりません。

これを実行すると現れるダイアログです。

Dialogresource_14

ダイアログのガジェットID用の定数とレイアウト部分のコードです。

enum{
  TEST_GROUP = 1000,
  TEST_NAME,
  TEST_EDIT
}
TestResDialog::CreateLayout(){
  SetTitle("TestDialog");
  AddGroupBeginV(TEST_GROUP , BFH_SCALEFIT , 2 , "TestGroup" , 0);
    AddGroupBorder(BORDER_GROUP_IN);
    AddGroupBorderSpace(4 , 4 , 4 , 4);

    AddStaticText(TEST_NAME , BFH_SCALEFIT , 0 , 0 , "TestName" , 0);
    AddEditText(TEST_EDIT , BFH_SCALEFIT , 0 , 0);
  AddGroupEnd();
 
  AddSeparatorH(0);
 
  AddDlgGroup(DR_DLGGROUP_OK + DR_DLGGROUP_CANCEL);
}

これと同じものをリソースで作ります。
今回のプラグインファイルの構成は次の通りです。

Dialogresource_17

ガジェットID用の定数を格納しているc4d_symbols.hヘッダファイルです。

//c4d_symbols.h
enum
{
  TEST_DIALOG = 10000,
  TEST_GROUP,
  TEST_NAME,
  TEST_EDIT
}

「c4d_symbols.ZIP」

ダイアログのIDを追加しました。
今回のダイアログのリソースのIDは、「TEST_DIALOG」と言う事です。
他は、リソースを使わない場合と同じ定数を使います。

ダイアログのレイアウトを格納している「TEST_DIALOG.res」リソースファイルです。

//TEST_DIALOG.res

DIALOG TEST_DIALOG
{
  NAME IDS_DIALOG;
  CENTER_V;
  CENTER_H;
 
  GROUP TEST_GROUP
  {
    ALIGN_TOP;
    SCALE_H;
    BORDERSTYLE BORDER_GROUP_IN;
    BORDERSIZE 4, 4, 4, 4;
    COLUMNS 2;
   
    STATICTEXT TEST_NAME
    {
      NAME IDS_STATIC1;
      CENTER_V;
      SCALE_H;
    }
   
    EDITTEXT TEST_EDIT
    {
      CENTER_V;
      SCALE_H;
    }
  }
  SEPARATOR
  {
    SCALE_H;
  }
 
  DLGGROUP
  {
    OK;
    CANCEL;
  }
}

「TEST_DIALOG_res.ZIP」

ダイアログをC.O.F.F.E.E.で組めたりコードを読めるユーザは、簡単に共通点がある事がわかると思います。
リソースでのレイアウトの構造は、C.O.F.F.E.E.の時と同じ構造です。
グループの中にStaticTextとEditTextがあり、グループの次にセパレータ、OK/キャンセルボタンが続きます。

StaticText等の文字は、strings_us/dialogsフォルダの「TEST_DIALOG.str」ストリングファイルに格納されています。

//TEST_DIALOG.str

DIALOGSTRINGS TEST_DIALOG
{
  IDS_DIALOG   "TestDialog";
  IDS_STATIC   "TestGroup";
  IDS_STATIC1  "TestName";
}

「TEST_DIALOG_str.ZIP」

これで、一通り必要なのもが揃いました。
ここで、今回のダイアログリソースの「TEST_DIALOG」は、ファイル名にも共通している事に注目してください。

これを、日本語GUIに対応させるには、strings_jp/dialogsフォルダを用意し「TEST_DIALOG.str」をコピーします。
日本語に対応させない場合は、strings_jp/dialogsフォルダを絶対に作成しないでください。
フォルダがカラであれば良いと言う訳ではないようです。
フォルダが存在して、ファイルが無いとリソース自体の読み込みに失敗するようです。

//TEST_DIALOG.str

DIALOGSTRINGS TEST_DIALOG
{
  IDS_DIALOG   "テストダイアログ";
  IDS_STATIC   "テストグループ";
  IDS_STATIC1  "テスト名";
}

グループ名はダイアログに表示させていませんでしたが、もしも表示するなならば、リソースファイルのGROUPブロックに「NAME IDS_STATIC」を追加します。

     :
     :
  GROUP TEST_GROUP
  {
    NAME IDS_STATIC;
    ALIGN_TOP;
    SCALE_H;
    BORDERSTYLE BORDER_GROUP_IN;
    BORDERSIZE 4, 4, 4, 4;
    COLUMNS 2;
        :
        :

この様に変更するとダイアログにはグループ名が表示されます。

Dialogresource_18

さて、C.O.F.F.E.E.でプラグインが組める事を前提に進めてきたので、ほとんど説明をしていません。
それでも、リソースファイル、ヘッダファイル、ストリングファイルの構造が、なんとなく解ったと思います。
リソースを記述するなら、C.O.F.F.E.E.SDKのリソースの書式を参考にしてください。

リソースが用意できたら、リソースを読み込むようにプラグイン本体を変更します。

まずは、ガジェットID用ヘッダファイル「c4d_symbols.h」を取り込みます。
プログラムの冒頭部分で取り込みます。

/*
TestResource
2009.12.9
*/



include "c4d_symbols.h";

//--------------------------------------------------------------------

var
pluginID = 1000005;

//--------------------------------------------------------------------

class TestResDialog : GeModalDialog
{
  public:
    TestResDialog();
    CreateLayout();
    Init();
    AskClose();
}

    :
    :

include ファイル名
このプログラムにプログラムの一部の外部ファイルをincludeの位置に取り込みます。

enum{}
必要がなくなったので削除します。

ダイアログのレイアウトの定義TestResDialogクラスのCreateLayout()メンバ関数を次のように変更します。
ここで、リソースファイルを読み込みます。

TestResDialog::CreateLayout(){
  var fn = GeGetRootFilename();
  fn->RemoveLast();
  var dlgRes = new(GeResource , fn);

  return LoadDialogResource(TEST_DIALOG , dlgRes , 0);
}

CreateLayout()の内容は…

  1. 変数fnにプラグイン本体のFilenameクラスを取得
  2. 変数fnからプラグイン本体のファイル名の削除をし、プラグインが格納されているフォルダのFilenameに変更します。
  3. 変数dlgResにリソースを取り込むために、Filenameクラスを指定してGeResourceクラスを割り当てます。
    このとき、リソースに関するフォルダやファイルの名前や配置に誤りがあると、dlgResにはGeResourceクラスが割り当てられず、nilになります。
  4. 最後に、ID:TEST_DIALGとリソース:dlgResを指定しリソースを取り込みます。取り込んだリソースをreturnで返します。

リソースの取り込みの流れは単純です。
注意が必要なのは、フォルダとファイルの名前と配置に誤りがあると、GeResourceクラスの割り当てに失敗するという事です。
リソースファイル等の記述ミスにも注意が必要です。

プラグイン本体の変更は、これで完了です。

「TestRes_02.ZIP」

実行すると、ダイアログが現れるはずです。

Dialogresource_19

「TestRes_fin.ZIP」

この構造が理解できれば、webで公開されているプラグインで日本語GUIに対応していないものでも、ユーザ自身でローカライズする事が可能です。

strings_us等のフォルダをコピーし、strings_jpに変更。
このフォルダの中にあるdialogsフォルダ内のXXX.strを変更する。

でも他の部分は間違えて変更しないように…

さて、このリソースを作成するにはタイプしなくてはいけないのか…?
リソースの記述を覚えないと利用できないのか…?
覚えるのが面倒だから、今まで通りC.O.F.F.E.E.で記述で良いや…
そう思ったユーザはいるだろうか…?

プラグインを作れる人を前提に書いたので、読んでいる人も多分知っている事だろう…

C4Dプラグインの為のダイアログリソースを作る為のプラグイン「Resedit」がMaxonから公開されています。
操作はGUIなので、グループやボタンを追加しパラメータを入力するだけで、リソースが作成できるプラグインです。

Maxon PluginCafe
http://www.maxon.net/ja/support/for-developers/plugin-cafe.html

Reseditがダウンロードできるページ
http://www.maxon.net/ja/support/for-developers/sdk-downloads.html
「Resource Editor」を探してください。下の方にあります。

「Resedit」をダウンロードし解凍してください。
C4DのPluginsフォルダにインストールします。

C4Dを起動しプラグインメニューを見てください。

Dialogresource_20

インストールに成功していれば、この様にメニューに現れています… 失敗することはないと思いますが…

「Resource editor...」を実行すると4つのダイアログが表示されます。

Dialogresource_21

ガジェットのプロパティを設定する「Properties」
ガジェットを追加する「Tools」
ダイアログのプレビュー「Dialog」
ダイアログのツリー構造「Structure」

使い方は、詳しく説明しません… と言うか、できません… 微妙な部分がわからないのです。
これに関する、日本語解説は残念ながらweb上…いや、世界中に無いと思います。
見つけた人は教えてください。

と、言いながらも…先ほどと同じダイアログを作成しましょう。
簡単な構造ですし…
なんとなく使うぐらいなら…

Dialogresource_14

ダイアログの構造は…

  • グループ
     *StaticText
     *EditText
  • セパレータ
  • OK/キャンセル

こんな構造です。

ではガジェットを追加します。

今回は、追加するガジェットが決まっているので、一気に追加します。
追加後に、それぞれ設定します。

Dialogresource_22

ToolsのアイコンをクリックするとStructureにガジェットが追加されます。
まずは、グループを追加します。

Dialogresource_23

Static textを追加。

Dialogresource_24

Edit boxを追加

Dialogresource_25

セパレータを追加

Dialogresource_26

KO/キャンセルボタンのダイアロググループを追加

Dialogresource_27

さて、Static textとEdit boxはグループの中に配置するので、オブジェクトマネージャの様にグループの子オブジェクトの関係にします。
この2つをドラッグ&ドロップでGroupに重ねます。
複数選択ができないので、1個づつ行います。

Dialogresource_28

構造はこれで完成です。
全ての作業が、先に追加すると言うわけではありません。

では、ガジェットのプロパティを設定しましょう。

Dialogresource_07

Propertiesは3つのパートで構成されています。
「IDs」ヘッダファイル「c4d_symbols.h」やストリングファイル「XXX.str」に格納されます。ガジェットに共通。
「Alignment」ガジェットの配置の設定。全てのガジェットに共通。
「Extended」ガジェット独自の設定

ここで重要なのが「IDs」です。
他の2つのパートの設定は、ガジェット個体の設定ですが、「IDs」は、Init()やAskClose()等でガジェットへの値の設定や取得にも使われます。
ただ、他の2つのパートの設定は、どうでも良いと言うわけではありません。

「IDs」には「Element ID」「Name」「String ID」の3つがあります。

「Element ID」は、ヘッダファイル「c4d_symbols.h」へ格納されます。
このIDで、Init()やAskClose()等でガジェットへの値の設定や取得にも使われます。

「Name」は、ダイアログに表示されるテキスト。Structureダイアログに表示される名前でもあります。

「String ID」は、「Name」を示すIDです。ストリングファイル「XXX.str」に格納されます。これは、ユーザが直接使用する事はありません。

まずは、Dialogの設定です。

Dialogresource_08

「Element ID」を「TEST_DIALOG」へ変更しました。
「Name」も「TestDialog」へ変更、と同時にStructureダイアログの名前も変わります。
必要に応じて、Alignmentも変更してください。

次はGroupの設定です。

Dialogresource_09

「Element ID」を「TEST_GROUP」へ変更しました。
「Name」を「TestGroup」へ変更。
Groupも必要に応じて、Alignment/Extendedも変更してください。

Static textの設定です。

Dialogresource_10

「Element ID」を「TEST_NAME」へ変更しました。
「Name」を「TestName」へ変更。
Groupも必要に応じて、Alignment/Extendedも変更してください。

Edit boxの設定です。

Dialogresource_11

「Element ID」を「TEST_EDIT」へ変更しました。
「Name」は変更できません。
Edit boxも必要に応じて、Alignment/Extendedも変更してください。

Separatorの設定です。

Dialogresource_12

セパレータにInit()/AskClose()で値を設定したり取得したりするのではないガジェットなので、「Element ID」は必要ありません。
Separatorも必要に応じて、Alignment/Extendedも変更してください。

Dialog groupの設定です。

Dialogresource_13

これも、IDは必要無いでしょう…

これで、一通り設定が終わりました。

では、設定したリソースを保存します。
「Structure」ダイアログのFileメニューのSaveで保存します。

Dialogresource_01

まずは、XXX.resを保存する位置を求められます。
プラグインを格納するフォルダ内にres/dialogsフォルダを作成し、dialogsフォルダ内に保存します。

Dialogresource_02

Dialogresource_29

他の「strings_us」フォルダは作る必要がありません。

保存すると、ヘッダファイル「c4d_symbols.h」やストリングファイル「XXX.str」を保存する為にプラグインを格納するフォルダを指定するよう促されます。

Dialogresource_06_2

フォルダを選択すると、残りの「strings_us/dialogs」フォルダを自動的に作成されます。
dialogsフォルダ内にストリングファイル「XXX.str」が保存されます。
「c4d_symbols.bak」
「c4d_symbols.h」
がプラグインを格納する指定したフォルダに作成されます。

Dialogresource_30

「c4d_symbols.h」を所定の位置「res」フォルダに移動させます。
所定の位置にc4d_symbols.hを配置しないと、プラグインの実行時にエラーが出ます。

Dialogresource_31

これで、一通りの作業が完了します。

この記事には間違いがあるかもしれません。ご了承ください。

|

« C4D オブジェクトに適用したマテリアルをXPressoで入れ替えるには… どうするの…? | トップページ | TMSより CINEMA 4D R11.5チュートリアル【PDF版】が発売… »