全般 †
プロパティ追加 †
- クラスビューの_DXxxでプロパティ追加(取得/設定メソッド)
GetPropSample()
SetPropSample()
- クラスビューのCXxxCtrlにプロパティ保持用のメンバ変数をprotectedで追加
m_PropSample
- 自動生成されたSet/Getメソッドを実装
- 必要があれば、プロパティページを実装(コンテナ側の"General")
- デザイン時に表示するプロパティなら、CXxxCtrl::DoPropExchange()を実装(コンテナ側の"全ページ")
PX_Long(pPX, _T("PropSample"), m_PropSample, 0);
- 必要があれば、odl(idl)ファイルのプロパティのIDのところに、説明文を追加する。(VC6.0はウィザードがバグるのでやめた方がいい?)
[id(0), helstring("Sampleプロパティ")]
- デザイン時に表示したくないプロパティは、nonbrowsable属性を付ける。hidden属性だとコードからも参照できないので注意。
[id(0), nonbrowsable]
- 実行時に呼び出されたくないプロパティは、restrictedをつける?
- 列挙体のプロパティは、整数型で定義しておき、idl/odlファイル内でenumして、その列挙型をプロパティの型とする。(手作業でしかできないのか?)
http://support.microsoft.com/kb/191872/ja
メソッド追加 †
- クラスビューの_DXxxでメソッド追加
- 省略可能引数は、C++の仕様と異なる。Variant型の値として引数を定義し、省略されたかどうかを判別する方法なので、C++の言語仕様に基づいた省略は不可。VBであれば、純粋に省略可能となる。
- オーバロードや可変個引数は定義できない。
- 引数付きコンストラクタも実装できない。
- 配列はどう渡す?
- 実行時に呼び出されたくないメソッドは、restrictedをつける?
プロパティページ追加 †
- ダイアログリソースを追加する(IDD_PROPPAGE_XXXをテンプレートにするとよい?)
- ダイアログのクラスを追加する。COlePropPageクラスを継承すること。
- ストリングテーブルで、新しいプロパティページの識別名とキャプション名を定義する。
- それぞれ、以下の場所を書き換える。
UpdateRegistry()の処理
既定クラスCOlePropertyPageのコンストラクタ呼出(メンバ初期化子で処理している)
- ActiveXコントロールのプロパティとの関連付け
クラスウィザードでコントロールに対応する変数を追加する際に、予め作成しておいたプロパティに関連付ける。
チェックボックスならBOOL型プロパティなど、制約はある。
→コントロール変数の場合は?
- コントロールのプロパティにOLE_COLORなどのOLE専用の変数を組み込んでいる場合、ストックプロパティページを使用できる。
CLSID_CColorPropPage | カラー | OLE_COLOR |
CLSID_CFontPropPage | フォント | LPPICTUREDISP? |
CLSID_CPicturePropPage | ピクチャ | LPFONTDISP? |
コントロールのスタイルの動的変更 †
コントロールのウィンドウスタイル(および拡張スタイルなど)の設定は、COleControl::PreCreateWindow()をオーバーライドして記述する。
あとは、スタイルを変更したいタイミングでCOleControl::RecreateControlWindow()をコールすることでPreCreateWindow()を経てコントロールが再生成される。
デザイン時の処理 †
- デバッグ
VS付属のテストコンテナではできないので、自分でテストコンテナのプロジェクトをダイアログなどで作っておき、コンポーネントを貼っておく。
コンポーネント側のプロジェクトで、デバッグ用のexeをVCにし、引数にテストコンテナを渡すことで、デバッグで起動できる。
C:\Program Files\Microsoft Visual Studio\COMMON\MSDev98\Bin\MSDEV.EXE
(起動引数) "C:\Current\TMP\CWork\tester\tester.dsw"
- COleControl::AmbientUserMode()でデザイン時か実行時か知ることができる。
- デザイン時の描画更新をしようとしてInvalidateRect()呼ぶと、まだウィンドウハンドルがないためアサートになる。どうすれば?他にもMFCを使ったリソースのロード等が失敗する。Win32APIを使えばできた。
- コントロールのビットマップは、左下のピクセルを透過色と見なす。VBでは。
- 実行時に非表示のOCXなどサイズを変更されたくない場合は、COleControl::OnSetExtent()で常にFALSEを返せばいい。
その他 †
プロパティやメソッドの順番を入れ替えた場合 †
自動的に生成されたプロパティやメソッドに関するコードは記述される順番が重要な場合が多い。
特にディスパッチID関係は最重要。ここがおかしいと、プロパティページで編集した項目と違う項目の値が変わったりする。
※そもそもIDの順番は並び替えない方がよいが。。
Windowsコントロールをサブクラス化する場合 †
以下の処理が必要となる。
(ほとんどはプロジェクト作成時のウィザードでサブクラス化を指定することで自動生成される。)
参考:MFC ActiveX コントロール : Windows コントロールのサブクラス化
- COleControl::IsSubclassedControl()のオーバーライド。
コントロールがサブクラス化されている場合はTRUEを返す。
- COleControl::PreCreateWindow()のオーバーライド。
コントロールのスタイルの詳細設定。
- OnDraw()内のDoSuperclassPaint()の呼び出し。
コントロール外観の描画を、基底のウィンドウクラスに任せる。
- 返送されたWindowメッセージを処理するメンバ関数の用意と実装。
対応するイベントハンドラを実装する。
上記の内、1と3に関しては必要な定義と実装が全てウィザードによって行われるため、何も変更する必要はない。
2に関しては、必要に応じてスタイルの設定処理を追加することができる。
4に関しては、OCM_COMMANDメッセージのハンドラのみ自動的に作成される。(WM_COMMANDに対応)
しかし、その他に必要なハンドラがある場合は適宜追加する必要がある。例えば、ツリービューコントロールをサブクラス化している場合のOCM_NOTIFYメッセージのハンドラなど。(WM_NOTIFYに対応)
→クラスウィザードによる追加はできない?手書きで追加するしかないのか?
ライセンス †
ActiveXコントロールのプロジェクト作成時の設定で、ランタイムライセンスにチェックをつける。
そうすることで、プロジェクトが以下のようにライセンスファイルを扱う設定となる。
また、以下の点に注意する必要がある。
- ライセンスファイルは、登録したOCX(DLL)と同フォルダに置く必要がある。
- ライセンスチェックに失敗すると、開発環境でコントロールとして貼り付けたりできない。
- ライセンスファイルが無くても、既にそのコントロールを使用しているプロジェクトのリソースからコピー&ペーストして使用することはできてしまう。(毎回警告が出るが)