質問: VisualStudio 2017 Windows10 を使用しております。 C++ CLRアプリケーションで作成したForm上のListBoxに、 別クラスからItemを追加したいと考えております。 Webなど調べているのですが、方法がわからず質問いたしました。 アドバイスや、参考となるwebページ等ございましたら 教えていただけないでしょうか? よろしくお願いいたします。 ![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/d99122c5430a8ff085412f60d004038c.png)
回答: アンマネージドな標準のC++のクラスやメソッドから、マネージドなC++/CLIの参照クラス(ref class)と相互運用することはできないことも無いです。ただし、最終的にやりたいことを踏まえ、実行内容を充分に理解しない限りはお勧めできません。 以下は標準C++の`CTest`クラスのメソッドから、Windows Formsのリストボックスである`System::Windows::Forms::ListBox`に要素を追加するコードの例です。フォームの子コントロールであるリストボックスの生存期間を考えると、その参照をCTestクラスにメンバー関数等で持たせることは適当ではなさそう、との判断からメンバー関数 `CTest::TestFunc`への引数としています。 ``` public class CTest{ private: int num_; // 深い意味は無いが、当然メンバー変数も使えることの例示 public: CTest() : num_(0) {} ~CTest() {} // メンバー関数 void TestFunc(System::Windows::Forms::ListBox^ listBox) { System::String^ s = System::String::Format(L"CTest::TestFunc: num={0}", ++num_); listBox->Items->Add(s); System::Diagnostics::Debug::WriteLine(s); } // staticメンバー関数 static void TestFunc_STATIC(System::Windows::Forms::ListBox^ listBox) { listBox->Items->Add(L"CTest::TestFunc_STATIC"); } }; ``` ボタンクリックの時にリストボックスに要素を追加するのは、具体的なコード例としては以下のようになります。 ``` CTest cTest; // 適切なところで宣言 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { // これは自Formから自分のListBoxへ追加するコード this->listBox1->Items->Add("Item1"); // CTestクラスのメンバー関数を介してListBoxへ追加するコード cTest.TestFunc(listBox1); CTest::TestFunc_STATIC(listBox1); } ``` 状況によりますが、C++/CLIを使う場合(分かり易く言うと、.NET Frameworkのクラスも使う場合)は、一般的にはC++の標準クラスではなく、参照クラス(`ref class`)を使うことが多いです。CTestクラスをもとにするとしたら、宣言の`class CTest`が`ref class CTest`になります。その場合、参照クラスに対して`new`や`delete`は使えなくなったり、標準C++での`int`等のプリミティブな型も`System.Int32`型になったりするので注意が必要です。 ``` // Managedな参照クラス ref class CTest のメンバー関数を介してListBoxへ追加するコード CTest^ ctest = gcnew CTest(); ctest->TestFunc(listBox1); CTest::TestFunc_STATIC(listBox1); ``` 実際、これらのコードを適用してWindows 10で動作させると、下図のようにリストボックスに表示されます。Visual Studio 2010で作成したプロジェクトを最終的にVisual Studio 2017でビルドしたもので、Windows 7でも動作しています。 !リストボックスに追加した様子 > > アドバイスや、参考となるwebページ等ございまかしたら教えていただけないでしょうか? > > > 公式では例えば以下ですが、 Microsoft Docs - C++/CLI による .NET プログラミング その他にも「C++/CLI Windows Forms」などと検索すると、色々ヒットしますので見てみると良いです。 本質問の内容に照らし合わせると、C++/CLIと.NET FrameworkのWindows Forms関係のクラスの使い方の問題になりますので、これらの情報を組み合わせて理解するかたちになるかと思います。 **以下は個人的なものも含むいち意見です:** C++/CLIはECMAで標準化 (Standard ECMA-372 / C++/CLI Language Specification)されてはいるものの、今ではマイクロソフトもC++/CLI関連のアップデートは積極的にはせず、むしろ退行して消えつつあるのが現状です。例えばVisual Studio 2017でC++/CLI関連のプロジェクト作成テンプレートは極端に少ないですし、ネットで検索してヒットする記事も、5~10年以上前の古いものが多いです。 既存プロジェクトの保守や小さい機能追加などであれば仕方無い面はありますが、標準のC++とは区別して向き合った方が良いと思います。.NET Frameworkを使う機会が多いのであれば、プログラミング言語としてはC#を使ったコードとの相互運用を意識した方が将来性は高いと思います teratailでも過去、何度かそのようなトピックで意見が述べられました。