【.NET】GraphicsBoxコントロール

.NET(VB.NET、C#)に対応した画像や線などの描画向けにPictureBoxコントロールを継承した
GraphicsBoxなるコントロールを作成しました。

 

このGraphicsBoxはPictureBoxを使っていて足りないな~と思う、

 

  • 再描画してくれるGraphicsオブジェクト
  • MouseWheelイベント
  • PensやColorsのようなFontのクラス

 

をそれぞれ、

 

  • Graphicsプロパティ
    コントロールがリサイズされるたびに、Graphicオブジェクトを再確保し、プロパティで取得できます。
  • MouseWheeledイベント
    GraphicsBoxにフォーカスがある時(Focus()をした後)、マウスホイールを上下に回転させたときにMouseWheeledイベントが発生します。
  • Fontsプロパティ
    フォームのデザイナ上のプロパティのFontsでGraphicsBoxへFontを指定します。
    このFontを使用する場合は、 graphicsbox1.Fonts などとすると、Fontsプロパティで取得できます。

 

としてPictureBoxに追加しました。

 

対象のフレームワークを.NET Framework2.0としました。

 

で、このGraphicsBoxコントロールは

 

GraphicsBoxSample_Ver111.zip

 

 

よりダウンロードできます。

 

このコントロールの実態は上記ファイルを解凍したフォルダ内の

 

ImagingSolution.Control.GraphicsBox.dll

 

となります。

 

使い方はVisual Studioを起動し、ツールボックス上で右ボタンアイテムの選択参照ボタンをクリック→ImagingSolution.Control.GraphicsBox.dllを選択

 

すると、ツールボックスにGraphicsBoxのアイコンが表示されるので、あとはPictureBoxと同様に使用できます。

 

GraphicsBoxSample_Ver111.zipをダウンロードするとVisual Studio 2010 Express EditionのVB.NET、C#のサンプルもつけているので、お試し下さい。

 

サンプルプログラムを実行し、ウィンドウ内をクリックした後、マウスホイールを上下させると下図のように線と文字がホイールの回転に合わせて上下しながら表示されます。

 

 

バージョン 更新日 ファイル 更新内容
Ver.1.1.1 2017.12.19 GraphicsBoxSample_Ver111.zip SplitContainerへDockしたときに画像がちらつくのを修正
Ver.1.1.0 2013.9.16 GraphicsBoxSample_Ver110.zip ●名前空間をImagingSolution.GraphicsBoxからImagingSolution.Control.GraphicsBoxへ変更

●GraphicsオブジェクトをBufferedGraphicsへ変更し描画の高速化

Ver.1.0.2 2011.5.7 GraphicsBoxSample_Ver102.zip MouseWheeledイベントを実装していないときのエラーを修正
Ver.1.0.1 2011.4.20 GraphicsBoxSample_Ver101.zip Focus()をコントロール内のイベントへ移動
名前空間名の修正
ユーザーコントロールのアイコンを指定
Ver.1.0.0 2011.4.20 GraphicsBoxSample.zip 初版

【C++/CLI】画像データの拡大縮小

画像表示の拡大縮小については画像の拡大縮小表示(高機能版)として紹介しましたが、今回は画像データのそのものを拡大縮小する方法を紹介します。

 

画像データを拡大縮小するにはSystem.Drawing.Bitmapクラスの以下のコンストラクタを用いる事で可能となります。

 

Bitmap (
    Image^ original,
    int width,
    int height
)

 

概要

指定したサイズを使用して、指定した既存のイメージで Bitmap クラスの新しいインスタンスを初期化します。

 

パラメータ

original 新しい Bitmap の作成元の Image
width 新しい Bitmap の幅 (ピクセル単位)
height 新しい Bitmap の高さ (ピクセル単位)

 

処理例

//元の画像
Bitmap^ src = gcnew Bitmap("test.bmp");
//縮小画像(1/2に縮小)
Bitmap^ dstSmall = gcnew Bitmap(src, src->Width / 2, src->Height / 2);
//画像の保存
dstSmall->Save("SmallImage.bmp", Imaging::ImageFormat::Bmp);
//拡大画像(2倍に拡大)
Bitmap^ dstBig = gcnew Bitmap(src, src->Width * 2, src->Height * 2);
//画像の保存
dstBig->Save("BigImage.bmp", Imaging::ImageFormat::Bmp);

 

処理結果

元の画像(test.bmp)

 

縮小画像(SmallImage.bmp)

 

拡大画像(BigImage.bmp)

 

補間モード(InterpolationMode)を指定して保存したい場合は、いったんGraphicsを通して画像を描画することで、補間モードを設定します。

 

//元の画像
Bitmap^ src = gcnew Bitmap("test.bmp");
//拡大画像データの確保
Bitmap^ dst = gcnew Bitmap(src->Width * 2, src->Height * 2);
//Graphicsオブジェクトの確保
Graphics^ g = Graphics::FromImage(dst);
//補間モードの設定
g->InterpolationMode = Drawing2D::InterpolationMode::HighQualityBicubic;
//拡大してGraphicsへ描画
g->DrawImage(src, 0, 0, src->Width * 2, src->Height * 2);
//画像の保存
dst->Save("BigImage.bmp", Imaging::ImageFormat::Bmp);

ただし、この方法では元の画像データ(src)がモノクロデータ(8Bit)の場合、上記のプログラムのままではR,G,Bの値が等しい24Bitのカラー画像として保存されてしまいます。
モノクロ画像データとして保存したい場合は、カラー画像からモノクロ画像に変換するしかなさそうです。

【C++/CLI】Graphicsオブジェクトの作成

.NETではピクチャボックスに画像や線、文字などを描画するには、Graphicsオブジェクトを作成し、このGraphicsオブジェクトに対して描画を行います。

 

Graphicsオブジェクトを作成する方法は3つ。
1.Imageオブジェクトから作成(オススメ!)
2.CreateGraphicsメソッドを使う方法(使わないことをオススメ!)
3.PaintイベントのPaintEventArgsから取得する方法

 

Graphiscオブジェクトを作成したら、画像の描画は

g->DrawImage(bmp, 0, 0);

線の描画は

g->DrawLine(Pens::Blue,0, 0, 100, 100);

というような具合で。

 

Imageオブジェクトから作成

(コード例)

//PictureBoxと同じ大きさのBitmapクラスを作成する。
Bitmap^ bmpPicBox = gcnew Bitmap(pictureBox1->Width, pictureBox1->Height);
//空のBitmapをPictureBoxのImageに指定する。
pictureBox1->Image = bmpPicBox;
//Graphicsオブジェクトの作成(FromImageを使う)
Graphics^ g = Graphics::FromImage(pictureBox1->Image);

 

上記コードをフォームのResizeイベントなどで処理を行い、作成したGraphicsオブジェクトを使い回せばよいかと思います。
この手法だと再描画は勝手にやってくれる上に、CreateGraphicsを使うよりも
格段に描画が速くなります。
.NET(GDI+)による描画が遅い!と思っている方は、まずはこの方法をお試し下さい。
(でも個人的には、それでも遅く感じます)

 

CreateGraphicsメソッドを使う

(コード例)

//Graphicsオブジェクトの作成(CreateGraphicsを使う)
Graphics^ g = pictureBox1->CreateGraphics();

 

この手法だと簡単ですが描画がかなり遅くなります。
しかも再描画してくれません...
説明が簡単なので、使っちゃう場合もありますが。

 

PaintイベントのPaintEventArgsから取得する

(コード例)

private: System::Void pictureBox1_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) {
//PaintEventArgsから取得
Graphics^ g = e->Graphics;
}

この方法が一番高速ですが、ちょっと扱いにくい。

 

ImageオブジェクトからGraphicsオブジェクトを作成する方法とCreateGraphisメソッドを使った方法の処理時間の比較などを「モノクロ画像の上に線などを描画」のページで紹介しています。
もしよろしければご参照下さい。

【C++/CLI】VB.NET固有の関数を使用する方法

.NET Framework ではVisual Basic.NETであっても、ただのVisualBasicという名前空間であるだけなので、C#やC++/CLIからVB.NET固有の関数を使うことが可能です。

 

以下、VB固有の関数の代表格のInputBox関数の使用方法を紹介します。

 

まず、VisualBasicの名前空間を参照できるように参照設定を行います。

 

プロジェクトの名前の部分で右ボタンをクリックし、参照を選択します。

 

 

次に新しい参照の追加ボタンをクリックします。

 

 

すると、使用可能な.NETの名前空間を表示されるので、この中からMicrosoft.VisualBaicを選択しOKボタンをクリックします。

 

 

すると、現在参照設定している名前空間の一覧にMicrosoft.VisualBasicの名前か追加されます。

 

 

これで準備は完了です。

 

実際にInputBoxを呼び出すのは、こんな感じ↓です。

 

String^ str = Microsoft::VisualBasic::Interaction::InputBox(“入力文字?”, “タイトル”, “初期値”, -1, -1);

 

とすると、このよう↓に表示されます。

 

 

C++からVBの関数が呼べてしまうのは不思議な感じもしますが、他にも使いたいVBの関数があったので、今回わざわざ記事にしてみました。

【C++/CLI】大文字/小文字、全角/半角、ひらがな/カタカナ変換

大文字/小文字の変換をするには System.String クラスToLowerToUpper メソッドを用います。

 

【コード例】

String^ str;

//大文字→小文字変換
str = "ImagingSolution";    // → imagingsolution
str = str->ToLower();
//小文字→大文字変換
str = "Imagingsolution";    // → IMAGINGSOLUTION
str = str->ToUpper();

さらにVBの関数を用いると全角/半角、ひらがな/カタカナの変換も行う事が出来ます。
VBの関数をC++/CLIから使う方法は VB.NET固有の関数を使用する方法 を参照願います。

 

【コード例】

using namespace Microsoft::VisualBasic;

String^ str;

//大文字→小文字変換
str = "ImagingSolution";    //→imagingsolution
str = Strings::StrConv(str, VbStrConv::Lowercase, 0);
//小文字→大文字変換
str = "Imagingsolution";    //→IMAGINGSOLUTION
str = Strings::StrConv(str, VbStrConv::Uppercase, 0);

//全角→半角変換
str = "画像処理ソリューション";    //→画像処理ソリューション
str = Strings::StrConv(str, VbStrConv::Narrow, 0);
//半角→全角変換
str = "画像処理ソリューション";            //→画像処理ソリューション
str = Strings::StrConv(str, VbStrConv::Wide, 0);

//ひらがな→カタカナ
str = "画像処理そりゅーしょん";    //→画像処理ソリューション
str = Strings::StrConv(str, VbStrConv::Katakana, 0);
//カタカナ→ひらがな
str = "画像処理ソリューション";    //→画像処理そりゅーしょん
str = Strings::StrConv(str, VbStrConv::Hiragana, 0);

(参考)
http://msdn.microsoft.com/ja-jp/library/7wtc81z6%28v=VS.80%29.aspx
http://msdn.microsoft.com/ja-jp/library/microsoft.visualbasic.vbstrconv.aspx

【C++/CLI】ファイルパス(フルパス)からファイル名、拡張子、ディレクトリの取得

ファイルを開くダイアログボックスなどから取得したファイル名(フルパス)からファイル名や拡張子、
ディレクトリなどを取得する場合には

System::IOクラスのGet×××メソッド

を用います。

 

以下、サンプルプログラムです。

//ファイル名(フルパス)
String^ FullPath = "c:\\Dir1\\Dir2\\Bitmap.bmp";
String ^FileName, ^Extension, ^Directory;

//ファイル名の取得(拡張子を含む)        → "Bitmap.bmp"
FileName = IO::Path::GetFileName(FullPath);
//ファイル名の取得(拡張子を含まない) → "Bitmap"
FileName = IO::Path::GetFileNameWithoutExtension(FullPath);
//拡張子の取得                         → ".bmp"  ※ピリオド"."を含みます。
Extension = IO::Path::GetExtension(FullPath);
//ディレクトリの取得                    → "c:\Dir1\Dir2"
Directory = IO::Path::GetDirectoryName (FullPath);
//相対パスから絶対パスを取得            → "c:\Dir1\Dir2\Bitmap.bmp"
FullPath = IO::Path::GetFullPath("Bitmap.bmp");

 

相対パスから絶対パスを取得する場合、指定したファイル名がカレントディレクトリに無い場合は
カレントディレクトリにファイル名が追加された文字列が返されます。

【C++/CLI】数値の書式(フォーマット)指定文字列

数値の表示桁数などの設定にはFormatメソッドかToStringメソッドなどで可能ですが、ここではToStringメソッドによる設定方法を紹介します。

 

【コード例】
int Val = 123;
String^ Txt = Val.ToString(“D5”);

 

とすると
Txt = “00123”
となります。

 

以下、主なフォーマットの設定例です。

 

標準書式指定文字列

書式 書式設定文字列 データ型 出力
10進数 D Int32 123 123
10進数(桁数設定) D5 Int32 123 00123
固定小数点 F Double 123.456 123.46
固定小数点(桁数設定) F6 Double 123.456 123.456000
パーセント P Double 0.12345 12.35%
パーセント(桁数設定) P3 Double 0.123456 12.346%
16進数(小文字) x Int32 123456 1e240
16進数(大文字) X Int32 123456 1E240
通貨 C Double 1234567 \1,234,567
数字 N Double 123456 123,456.00
数字(桁数設定) N1 Double 12345678 123,456.8

詳細は下記ページを参照願います。

http://msdn.microsoft.com/ja-jp/library/241ad66z(VS.80).aspx

 

カスタム数値書式指定文字列

書式 書式設定文字列 データ型 出力
ゼロプレースホルダ 00000 Double 123 00123
000.000 Double 12.3456 012.346
000.000 Double 123.45 123.450
桁プレースホルダ ##### Double 123 123
#.# Double 1.2 1.2
#.# Double 1 1
#.# Double 123.456 123.5
#,# Double 123456789 123,456,789
(00)####-#### Double 312345678 (03)1234-5678
正、負、0別表示 +#;-#;±0 Double 123 +123
+#;-#;±0 Double -123 -123
+#;-#;±0 Double 0 ±0
#;(#) Double 123 123
#;(#) Double -123 (123)

詳細は下記ページを参照願います

http://msdn.microsoft.com/ja-jp/library/7x5bacwt(VS.80).aspx

 

【右寄せ】
int Val = 123;
String^ Txt = Val.ToString()->PadLeft(5);
とすると
Txt = ”  123″
となります。

 

【左寄せ】
int Val = 123;
String^ Txt = Val.ToString()->PadRight(5);
とすると
Txt = “123  ”
となります。

 

右寄せ/左寄せは、少し紛らわしいですが、左側を穴埋めして右寄せ(PadLeft)、右側を穴埋めして左寄せ(PadRight)となります。
カッコ内の数値が文字数になります。

 

【C++/CLI】文字列の分割(System.String.Splitメソッド)

文字列を特定の文字で分割し、Stringの配列に格納するには

System.String.Splitメソッド

を用います。
CSVファイルを読み込む時などはカンマ(,)で区切るので、このSplitメソッドを使います。

 

このメソッドの定義は

array^ Split (
    array<String^>^ separator,
    StringSplitOptions options
)

 

パラメータ

separator

分割する文字列をString配列で指定します。

options

StringSplitOptions::Nodeを指定すると分割した文字列が空の場合でもそのまま返します。
StringSplitOptions::RemoveEmptyEntriesを指定すると分割した文字列が空の場合、除去されます

 

【サンプルプログラム】

String^ SrcText = "A,B;C,,E,F";

//分割する文字列の配列
array<String^>^ SepString ={",", ";"};

//文字列の分割
array<String^>^ TextArr1 = SrcText->Split(SepString, StringSplitOptions::RemoveEmptyEntries);
array<String^>^ TextArr2 = SrcText->Split(SepString, StringSplitOptions::None);

このコードを実行し、TestArr1とTestArr2の中身をウォッチで確認すると、以下の通りとなります。

 

 

区切り文字が1つの場合は

array<String^>^ TextArr3 = SrcText->Split(‘,’);

のように区切ることもできます。
ただし、この場合はシングルクォーテーション( )なので注意して下さい。

【C++/CLI】改行文字

メッセージボックスなどの文字列を改行させる時には

System.Environment.NewLineプロパティ

を用います。

以下、サンプルと実行例です。

 

【サンプルプログラム】

private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
         button1->Text = "1行目の文字列" + Environment::NewLine +
                                 "2行目の文字列";
         label1->Text  = "1行目の文字列" + Environment::NewLine +
                                "2行目の文字列";

         MessageBox::Show("ボタンとラベルの文字列が" + Environment::NewLine +
                                       "変更されました。");
     }

 

【実行例】

 

ボタンやラベルに関しては、プロパティウィンドウで文字列を入力すると改行も繁栄されます。

また、System.Environment.NewLineプロパティを使わずとも、\n\rを使って

 

MessageBox::Show(“ボタンとラベルの文字列が\r\n変更されました。”);

 

のように書くことも可能です。

 

【C++/CLI】テキストボックスの文字列を変数へ代入

テキストボックスの文字列はtextbox1->Textのようにすると取得できますが、この文字列を数値へ変換するには各型に用意されているParseメソッドを使います。

 

(例)
int Val= int::Parse(textbox1->Text);

 

文字列変換する型は必要に応じて変えてください。
ただし、この場合、テキストボックスに数値ではない文字列が入力された場合、エラーとなるので、エラー処理を行う場合はTryParseメソッドを用います。

(例)
int Val;
bool result = int::TryParse(textbox1->Text, Val );

 

テキストボックスの文字列がint 型として判断された場合、変数(上の例ではVal)に値が代入され、戻り値(result)にtrueが戻されます。
失敗した場合は戻り値がfalseとなります。

 

このエラー処理を用いると、数値としてByte型の値(0~255)が欲しいときなど便利です。

 

(例)
Byte Val ;
bool result = Byte::TryParse(textbox1->Text, Val );

 

詳細はmsdn2の「Int32.TryParse メソッド 」に記載されています。

【C++/CLI】アンカープロパティによるフォームのリサイズ処理

フォームのリサイズ時にボタンなどの位置をフォームの大きさに合わせて調整する場合、位置を調整するコントロールのAnchorプロパティを設定すると簡単に位置調整が可能となります。

 

 

Anchorプロパティは指定した方向がリサイズ時の位置の基準となり、指定した方向の距離が一定に保たれるようにコントロールの位置が調整されます。

 

何はともあれ、以下の動きを見て頂くと分かりやすいと思います。

 

【button1~button4:Top,Leftの場合】※Top,Leftはデフォルト設定値です。


 

【button4:Bottom,Rightの場合】

 

【button2,button4:Top,Left,Rightの場合】

 

【button3,button4:Bottomの場合】

 

【button4:Top,Bottom,Left,Rightの場合】

 


VB6.0の時はフォームのリサイズイベントで座標を計算しながら位置を調整していましたが、.NETからは、このAnchorプロパティを使う事でやたらと簡単になりました。

【C++/CLI】マウスイベント処理

マウスイベント(マウスをクリック、ダブルクリックなど)の処理を追加するには、イベント処理を行うオブジェクト(ピクチャボックスやボタンなど)を選択した状態でイベントのプロパティウィンドウを表示し、イベント処理の文字の部分をダブルクリックします。

 

 

すると、イベントハンドラが自動的に作成されます。
下記の例はMouseClickを追加した場合

 

this->pictureBox1->MouseClick += gcnew System::Windows::Forms::MouseEventHandler(this, &Form1::pictureBox1_MouseClick);

:
:

private: System::Void pictureBox1_MouseClick(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {

        //この位置にイベント処理を追加する。

}

 

このイベントハンドラ内にイベント処理を追加していきます。

 

ここで注意しないといけないのが、pictureBox1_MouseClickという名前になっていますが、必ずしもpicutureBox1からのイベントとは限りません。
どのオブジェクトかは、最初の引数の System::Object^ sender を参照します。
sender のプロパティはそのまま参照できないので、下記のようにキャストします。

 

PictureBox^ pic = static_cast<PictureBox^>(sender);

 

また、マウスのどのボタンがクリックされ、どの位置でクリックされたか?などは2番目の引数の
System::Windows::Forms::MouseEventArgs^ e を参照します。

 

ボタンの判別例は以下の通りです。

 

if (e->Button == System::Windows::Forms::MouseButtons::Left){
      //左ボタンクリック
      MessageBox::Show("左ボタンがクリックされました。");
}else if (e->Button == System::Windows::Forms::MouseButtons::Right){
      //右ボタンクリック
      MessageBox::Show("右ボタンがクリックされました。");
}else if (e->Button == System::Windows::Forms::MouseButtons::Middle){
      //中ボタンクリック
      MessageBox::Show("中ボタンがクリックされました。");
}

 

クリックされた位置のX座標は e->X、Y座標は e->Y で取得できます。

 

また、マウスをクリックした時にShiftキー、Ctrlキー、Altキー、が押されているかどうかを判別するにはControl::ModifierKeysプロパティを参照すれば良いのですが、厳密にはマウスがクリックされたときのキーを取得するのはなく、Control::ModifierKeysプロパティが呼ばれた時のキーを取得するので、ご注意下さい。

 

//Shift,Ctrl,Altキーが押されているか?
Keys key = Control::ModifierKeys;

if ((key & Keys::Control) == Keys::Control){
      //Controlボタンクリック
      MessageBox::Show("Controlボタンがクリックされました。");
}else if ((key & Keys::Shift) == Keys::Shift){
      //Shiftボタンクリック
      MessageBox::Show("Shiftボタンがクリックされました。");
}else if ((key & Keys::Alt) == Keys::Alt){
      //Altボタンクリック
      MessageBox::Show("Altボタンがクリックされました。");
}

マウスイベントには以下のようなものがあります。

 

イベント 意味
Click クリックされたとき
DoubleClick ダブルクリックされたとき
MouseCaptureChanged マウスのキャプチャがなくなるとき(意味不明???)
MouseClick マウスでクリックされたとき
MouseDoubleClick マウスでダブルクリックされたとき
MouseDown マウスボタンが押されたとき
MouseEnter マウスポインタがコントロールの外側から内側に入ったとき
MouseHover マウスポインタがコントロール上に留まっているとき
MouseLeave マウスポインタがコントロールの内側から外側に出たとき
MouseMove マウスポインタがコントロール上を移動したとき
MouseUp マウスボタンが離されたとき
MouseWheel コントロールにフォーカスがあり、マウスホイールが動いたとき

 

ClickイベントとMouseClickイベント、DoubleClickイベントとMouseDoubleClickイベントとは、ほぼ同じですが、2番目の引数が EventArgs^  e か MouseEventArgs^  e の違いがあります。
マウスの情報をより詳しく取得したい場合は Mouse××イベントをお使い下さい。

また、イベントの発生順番は

 

  1. MouseDown
  2. Click
  3. MouseClick
  4. MouseUp
  5. MouseDown
  6. DoubleClick
  7. MouseDoubleClick
  8. MouseUp

 

となります。

 

 

インデックス付きのピクセル形式をもつイメージとは?

System::Drawing::GraphicsクラスFromImageメソッドSystem::Drawing::BitmapクラスSetPixel、GetPixelメソッドで、モノクロの画像データを指定すると

 

追加情報: インデックス付きのピクセル形式をもつイメージからグラフィックス オブジェクトを作成することはできません。

 

というエラーが出る場合があります。

 

このインデックス付きのピクセル形式というのは、ビットマップフォーマットをご存じの方には、話が早いのですが、例えばモノクロ8Bitの画像データの場合は0~255の輝度値で画像データを指定しますが、モニタ上にモノクロの画像を表示するには、輝度値に対応したR、G、Bの値をカラーテーブルを使って指定する必要があります。

 

このカラーテーブルをもつファイル形式(例えば、1ビットの二値化画像、8ビットのモノクロ画像など)の画像データをインデックス付きのピクセル形式をもつイメージと言います。

 

画像処理ではモノクロ8Bitの画像データを使う機会が多いのですが、.NETのプログラムでは少し工夫しないといけない場合がありますが、この辺はおいおい紹介したいと思います。

 

C++/CLIって何?

よく、お使いの言語は何ですか?と尋ねると

 

『Visual C++』

 

です。
という答えが返ってくるのですが、このC++/CLIの登場によって、Visual C++が差すものが何なのか?ますます分からなくなってきました。

 

現在、Visual StudioでC++言語が扱えるのは

  • MFC(Microsoft Foundation Class)
  • SDK(Software Development Kit)
  • C++/CLI

の3つでしょうか?

 

C++/CLIはこれらの良いとこ取りをしたような言語で、GUI部分はVB6.0のようなフォームエディタで作成し、ボタンをダブルクリックする事でイベント処理を追加していきます。
また、従来のWin32 APIも使えるし、MFCのクラスも使えるし、最近主流になってきているVB.NETやC#などが使っている.NET Frameworkも使う事が可能です。

 

また、C#などでは基本的に使えないポインタもそのまま使う事が可能です。

 

もし、これまで、GUIはVB6.0で作って、処理部分はWin32APIや自作のライブラリを作って来たような人にとっては、比較的とっつき易いと思います。

 

ただ、あまりにゴチャゴチャに開発ができるようにしてしまったせいか、最新のVisual Studio 2010ではIntellisenseが使えないなど、ここ最近は、いまいちMicrosoftのやる気が感じられません。

 

という事で、これから先が不透明感のある感じなのですが、これまで作成してきたC++の資産を生かしつつ簡単なGUI周りを作成したい方にはオススメです。
ただし、多少凝ったソフトになると、フォーム間の参照や64bitの対応など、他のVB.NETやC#と比べてかなり面倒なので、評価用のサンプルを作る程度に留めておいた方が無難です。

 

もし、新規にプログラムを始めたい方にはC#の方が良いと思います。
C#もC++/CLIも.NET Frameworkを使うプログラムなので、基本的には同じような物と言いつつも、少しずつC#の方が優遇されているような気がします。

 

なので、C++/CLIで従来のC++のライブラリを使ったクラスライブラリを作成し、画面周りなどのアプリケーションよりな部分はC#で作る!というのが私なりの現在の結論なのですが、C++/CLIの情報は非常に少ないので、記事にまとめていこうと思います。

 

【追記】

結局、C++/CLIを使うのは辞めました。

フォーム間参照が面倒だし、/MT(d)が指定できないし、Any CPUがないし・・・

AnyCPUが無いと、OSが64bitであっても32bitで動いているVisual Studioでは、フォームエディタにカスタムコントロールを配置しようとすると、64bitにコントロールを対応させようとすると、AnyCPUでないと都合が悪いんですよね。

 

という事で、フォーム周りはC#で作る方がおすすめです。