りさーちゃーのひよこ
技術のこととか
2014年6月13日金曜日
C++/CLI フォームアプリとOpenGLの連携(フォーム新規作成とサンプル)
#はじめに 私自身がど素人なので、頭の回転が遅い自分が理解できるように進めていきます。<br /> フォームアプリ作成時は.Netが自動でコードを生成してくれるようなのだが、手順ごとの差分に注目して、何をしたときにどういうコードが作られるのかを、非常に簡単なコードを作りながら確認しようと思います。<br /> #作りたいもの ボタンを押したときに表示される文字列が変わるようなアプリを作ってみます。とってもつまらないですが、これができればあとは応用なので何とでもなるでしょう。<br /> 最終的にはOpenGLとの連携にもって行きたいです。<br /> #C++/CLR フォームアプリ新規作成 フレームワークはC++/CLIにします。C++なら少しは慣れているし、今まで作ったコードもまんま流用できます。C#も興味は持っています。職場でセミナを申し込んだので、それを糧に何か作りたくなったらまたメモを残します。<br /> <br /> ##1. C++/CLR フォームアプリケーションを新規作成する。 VC2012の解説は次のサイトが秀逸です。ここを参考にフォームの追加まで行います。<br /> <a href="http://y-okamoto-psy1949.la.coocan.jp/booksetc/introvcpp/vs2012FormApp/" target="_blank" title="">岡本安晴の 心理学C++プログラミングなど - 簡単なVisual C++ フォーム アプリケーション プログラミング</a><br /> ありがとうございます。え、手抜き?め、めんどくさいとかありませんよ、たぶん。<br /> ##2. 新規作成時のMyForm.h[デザイン]を確認する。 新規作成時のフォームはまっさらです。MyForm.hを選択するとフォームのデザインが見られます。<br /> ここでボタン等のビジュアルコントロールのデザインができます。<br /> <a class="detailOn" href="http://blog-imgs-86.fc2.com/m/o/r/morimoridiary254/blog_import_568b66914d501.png" id="i12971987794"><img alt="空フォーム" src="http://blog-imgs-86.fc2.com/m/o/r/morimoridiary254/blog_import_568b66914d501.png" id="1402710838424" ratio="1.45" style="border: none; height: 241.3793103448276px; width: 350px;" /></a><br /> この画面をデザイナと呼ぶようです。私は次のような名前をつけました。<br /> <ul> <li>プロジェクト名:InitialForm1</li> <li>フォーム名:MyForm</li> </ul> プロジェクト名はミスりましたが、気にしないことにします。<br /> ##3. 新規作成時のMyForm.h のコードを確認する。 <table bgcolor="#FFFCCC" border="0" cellpadding="0" style="width: 420px;"><tbody> <tr><td><span style="font-size: xx-small;"><span style="color: #00bfbf;">#pragma once</span><br /><span style="color: blue;">namespace</span> InitialForm1 {<br /> <span style="color: blue;">using namespace</span> System;<br /> <span style="color: blue;">using namespace</span> System::ComponentModel;<br /> <span style="color: blue;">using namespace</span> System::Collections;<br /> <span style="color: blue;">using namespace</span> System::Windows::Forms;<br /> <span style="color: blue;">using namespace</span> System::Data;<br /> <span style="color: blue;">using namespace</span> System::Drawing;<br /> <span style="color: #60bf00;">///<br /> /// MyForm の概要<br /> ///</span><br /> <span style="color: blue;">public ref class</span> MyForm : <span style="color: blue;">public </span>System::Windows::Forms::Form<br /> {<br /> <span style="color: blue;">public</span>:<br /> MyForm(<span style="color: blue;">void)</span><br /> {<br /> InitializeComponent();<br /> <span style="color: #60bf00;">//<br /> //TODO: ここにコンストラクター コードを追加します<br /> //</span><br /> }<br /> <span style="color: blue;">protected</span>:<br /> <span style="color: #60bf00;">///<br /> /// 使用中のリソースをすべてクリーンアップします。<br /> ///</span><br /> ~MyForm()<br /> {<br /> <span style="color: blue;">if </span>(components)<br /> {<br /> <span style="color: blue;">delete </span>components<br /> }<br /> }<br /> <span style="color: blue;">private</span>:<br /> <span style="color: #60bf00;">///<br /> /// 必要なデザイナー変数です。<br /> /// </span><br /> System::ComponentModel::Container ^components;<br /><span style="color: #00bfbf;">#pragma</span> region Windows Form Designer generated code<br /> <span style="color: #60bf00;">///<br /> /// デザイナー サポートに必要なメソッドです。このメソッドの内容を<br /> /// コード エディターで変更しないでください。<br /> ///</span><br /> <span style="color: blue;">void </span>InitializeComponent(void)<br /> {<br /> <span style="color: blue;">this</span>->components = <span style="color: blue;">gcnew </span>System::ComponentModel::Container();<br /> <span style="color: blue;">this</span>->Size = System::Drawing::Size(<span style="color: deeppink;">300</span>,<span style="color: deeppink;">300</span>);<br /> <span style="color: blue;">this</span>->Text = L<span style="color: red;">"MyForm"</span>;<br /> <span style="color: blue;">this</span>->Padding = System::Windows::Forms::Padding(<span style="color: deeppink;">0</span>);<br /> <span style="color: blue;">this</span>->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;<br /> }<br /><span style="color: #00bfbf;">#pragma endregion</span><br /> };<br />}</span></td></tr> </tbody></table> フォームのコントロールを形成する処理が自動で追加されるのですね。<br /> ##4. フォームにボタンを追加したときのMyForm.h のコードを確認する。 超絶適当にボタンを追加してみます。<br /> 「表示 → ツールボックス」を選択するとコントロール一覧が出てくるので、Buttonを選択します。フォーム上でボタンを配置したい矩形領域をマウスで選択します。<br /> コードを見たいときはMyForm.hを展開し、{} InitialForm1(プロジェクト名)を展開し、MyFormを選択する必要があります。<br /> <img alt="ボタン追加" src="http://blog-imgs-86.fc2.com/m/o/r/morimoridiary254/blog_import_568b66947e8cf.png" id="1402701999376" ratio="1.445360824742268" style="border: none; height: 242.1540656205421px; margin: 0px 5px; width: 350px;" /><br /> 以下コードの確認です。赤太字部分が差分です。差分に注目するため、差分位置関係がわかる範疇で省略しています。<br /> <table bgcolor="#FFFCCC" border="0" cellpadding="0" style="width: 420px;"><tbody> <tr><td><span style="font-size: xx-small;"><span style="color: #00bfbf;">#pragma once</span><br /><span style="color: blue;">namespace</span> InitialForm1 {<br /> <span style="color: #60bf00;">// 省略</span><br /><span style="color: blue;">public ref class</span> MyForm : <span style="color: blue;">public </span>System::Windows::Forms::Form<br /> {<br /> <span style="color: blue;">public</span>:<br /> MyForm(<span style="color: blue;">void</span>)<br /> <span style="color: #60bf00;">// 省略</span><br /> <span style="color: blue;">protected</span>:<br /> ~MyForm()<br /> <span style="color: #60bf00;">// 省略</span><br /><span style="color: red; font-weight: bold;"> private: System::Windows::Forms::Button^ button1;<br /> protected:</span><br /> <span style="color: #60bf00;">// 省略</span><br /><span style="color: #00bfbf;">#pragma</span> region Windows Form Designer generated code<br /> <span style="color: blue;">void </span>InitializeComponent(void)<br /> {<br /><b><span style="color: red;"> this->button1 = (gcnew System::Windows::Forms::Button());<br /> this->SuspendLayout();<br /> //<br /> // button1<br /> //<br /> this->button1->Location = System::Drawing::Point(209, 197);<br /> this->button1->Name = L"button1";<br /> this->button1->Size = System::Drawing::Size(63, 27);<br /> this->button1->TabIndex = 0;<br /> this->button1->Text = L"button1";<br /> this->button1->UseVisualStyleBackColor = true;<br /> //<br /> // MyForm<br /> this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);<br /> this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;<br /> this->ClientSize = System::Drawing::Size(292, 273);<br /> this->Controls->Add(this->button1);<br /> this->Name = L"MyForm";<br /> this->Text = L"MyForm";<br /> this->ResumeLayout(false);</span></b><br /> }<br /><span style="color: #00bfbf;">#pragma endregion</span><br /> };<br />}</span></td></tr> </tbody></table> <br /> なるほど、部品となるbutton1の宣言とプロパティの設定が追加されていますね。<br /> そしてMyFormのプロパティ設定については、button1コントロールが無い場合とある場合で処理が違います。<br /> 下記に特に気になった点を個人メモしておきますが、読まなくても問題はないでしょう笑。<br /> <ol> <li>componentsの初期化がされない</li> Buttonコントロールが無い場合にはcomponentsの初期化がされていますが、Buttonがある場合にはそれがありません。<br /> componentsはその型からコンテナであることが分かります。コンテナとは、オブジェクトの入れ物を指します。データ構造を意識して便利に変数の入れ替えができるパワーアップ版配列というイメージだと思っています。<br /> ボタンがあるのにコンテナは使わないの?と思ったのですが、どうやらここに入るのはTimerコントロール等の非ビジュアルコンポーネントのようです。非ビジュアルなほうはコンテナにまとめて入れて管理するようです。今はビジュアルコンポーネントであるButtonしか定義されていないので、使う必要が無いみたいです。<br /> 一方、ビジュアルコントロールはコンテナに入れて管理するという考え方ではないようです。<br /> ですので、Buttonを挿入する前gcnew System::ComponentModel::Container()は単なるおまじないで、別に無くても支障は無いのだと思います。<br /> ※試しにTimerコントロールを追加するときっちり初期化がされているようでした。 <li>Formの設定プロパティが変更されている</li> 追加されているものは見るとなんとなく分かるのですが、this->ClientSize が気になりました。ClientSize はフォームから境界線とタイトルバーを取り除いた領域との事です(<a href="http://blog.ameba.jp/ucs/entry/srventrypreview.do#" style="color: #000066; text-decoration: none;" target="_blank" title="">MSDN - Form::ClientSize プロパティ</a>)。 Buttonの有無で初期化のパラメータが異なる理由は良く分かっていませんが、おそらくまっさらなFormでの初期化は最低限他の要素が依存しない最適(無難)なものに限定しているのだと思います。</ol> ##5. ボタンをダブルクリックした時のコードを確認する。 上記のコードではボタンを押したときの動作を定義する場所がありませんでした。<br /> 動作を定義したいコントロールをフォームデザイナ上でダブルクリックするとハンドラが用意されるという噂なので、やってみました。<br /> <table bgcolor="#FFFCCC" border="0" cellpadding="0" style="width: 420px;"><tbody> <tr><td><span style="font-size: xx-small;"><span style="color: #00bfbf;">#pragma once</span><br /><span style="color: blue;">namespace</span> InitialForm1 {<br /> <span style="color: #60bf00;">// 省略</span><br /> <span style="color: blue;">public ref class</span> MyForm : <span style="color: blue;">public </span>System::Windows::Forms::Form<br /> {<br /> <span style="color: blue;">public</span>:<br /> MyForm(<span style="color: blue;">void</span>)<br /> <span style="color: #60bf00;">// 省略</span><br /> <span style="color: blue;">protected</span>:<br /> ~MyForm()<br /> <span style="color: #60bf00;">// 省略</span><br /><span style="color: #00bfbf;">#pragma</span> region Windows Form Designer generated code<br /> <span style="color: blue;">void </span>InitializeComponent(void)<br /> {<br /> <span style="color: #60bf00;">// 省略</span><br /><b><span lang="EN-US" style="color: red;"> //<br /> button1<br /> //<br /> this->button1->Click += gcnew System::EventHandler(this, &MyForm::button1_Click);</span></b> <span style="color: #60bf00;">// 省略</span><br /> }<br /><span style="color: #00bfbf;">#pragma endregion</span><br /><b><span style="color: red;"> private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {<br /> };</span></b><br /> };<br />}</span></td></tr> </tbody></table> <br /> 最後のほうにイベントハンドラが登場しました。InitializeComponent()内でハンドラを登録しているようです。<br /> この中に具体的な処理を入れればよいようです。<br /> ##6. ボタンを押したときにテキストボックスの文字列が変わるサンプル。 ここまで分かればあとは好き勝手できそうです。<br /> こんな適当なアプリケーションを作ります。<br /> ・ボタンが2つとテキストボックスが1つ。ボタンを押すとテキストボックス内の表示が切り替わります。<br /> 起動時はテキストボックスに"Initial"と表示されてあります。<br /> <a class="detailOn" href="http://blog-imgs-86.fc2.com/m/o/r/morimoridiary254/blog_import_568b669235f06.png" id="i12972419662"><img alt="初期" src="http://blog-imgs-86.fc2.com/m/o/r/morimoridiary254/blog_import_568b669235f06.png" id="1402701276923" ratio="2.7777777777777777" style="border: none; height: 108px; width: 300px;" /></a><br /> ボタン1を押すと"Button1"と表示されます。<br /> <a class="detailOn" href="http://blog-imgs-86.fc2.com/m/o/r/morimoridiary254/blog_import_568b6692aff87.png" id="i12972419663"><img alt="ボタン1" src="http://blog-imgs-86.fc2.com/m/o/r/morimoridiary254/blog_import_568b6692aff87.png" id="1402701064755" ratio="2.7777777777777777" style="border: none; height: 108px; width: 300px;" /></a><br /> ボタン1を押すと"Button2"と表示されます。<br /> <a class="detailOn" href="http://blog-imgs-86.fc2.com/m/o/r/morimoridiary254/blog_import_568b669336293.png" id="i12972419661"><img alt="ボタン2" src="http://blog-imgs-86.fc2.com/m/o/r/morimoridiary254/blog_import_568b669336293.png" id="1402701064636" ratio="2.7777777777777777" style="border: none; height: 108px; width: 300px;" /></a><br /> これだけです笑。以下、MyForm.h のうち、イベントハンドラのbコードです。<br /> <br /> <table bgcolor="#FFFCCC" border="0" cellpadding="0" style="width: 420px;"><tbody> <tr><td><span style="font-size: xx-small;"><span style="color: #00bfbf;">#pragma once</span><br /><span style="color: blue;">namespace</span> InitialForm1 {<br /> <span style="color: blue;">using namespace</span> System;<br /> <span style="color: blue;">using namespace</span> System::ComponentModel;<br /> <span style="color: blue;">using namespace</span> System::Collections;<br /> <span style="color: blue;">using namespace</span> System::Windows::Forms;<br /> <span style="color: blue;">using namespace</span> System::Data;<br /> <span style="color: blue;">using namespace</span> System::Drawing;<br /><br /> <span style="color: #60bf00;">/// <summary><br /> /// MyForm の概要<br /> /// </summary></span><br /> <span style="color: blue;">public ref class</span> MyForm : public System::Windows::Forms::Form<br /> {<br /> <span style="color: blue;">public</span>:<br /> MyForm(<span style="color: blue;">void</span>)<br /> {<br /> InitializeComponent();<br /><span style="color: #60bf00;"> //<br /> //TODO: ここにコンストラクター コードを追加します<br /> //</span> }<br /> <span style="color: blue;">protected</span>:<br /> <span style="color: #60bf00;">/// <summary><br /> /// 使用中のリソースをすべてクリーンアップします。<br /> /// </summary></span><br /> ~MyForm()<br /> {<br /> <span style="color: blue;">if</span> (components)<br /> {<br /> <span style="color: blue;">delete</span> components;<br /> }<br /> }<br /> <span style="color: blue;">private</span>: System::Windows::Forms::Button^ button1;<br /> <span style="color: blue;">private</span>: System::Windows::Forms::Button^ button2;<br /> <span style="color: blue;">private</span>: System::Windows::Forms::TextBox^ textBox1;<br /> <span style="color: blue;">private</span>: System::ComponentModel::IContainer^ components;<br /> <span style="color: blue;">protected</span>:<br /> <span style="color: blue;">private</span><br /><span style="color: #60bf00;"> /// <summary><br /> /// 必要なデザイナー変数です。<br /> /// </summary></span><br /><br /><span style="color: #00bfbf;">#pragma region</span> Windows Form Designer generated code<br /><span style="color: #60bf00;"> /// <summary><br /> /// デザイナー サポートに必要なメソッドです。このメソッドの内容を<br /> /// コード エディターで変更しないでください。<br /> /// </summary></span> <span style="color: blue;">void</span> InitializeComponent(<span style="color: blue;">void</span>)<br /> {<br /> <span style="color: blue;">this</span>->button1 = (gcnew System::Windows::Forms::Button());<br /> <span style="color: blue;">this</span>->button2 = (gcnew System::Windows::Forms::Button());<br /> <span style="color: blue;">this</span>->textBox1 = (gcnew System::Windows::Forms::TextBox());<br /> <span style="color: blue;">this</span>->SuspendLayout();<br /><span style="color: #60bf00;"> //<br /> // button1<br /> // </span><br /> <span style="color: blue;">this</span>->button1->Location = System::Drawing::Point(<span style="color: deeppink;">203</span>, <span style="color: deeppink;">12</span>);<br /> <span style="color: blue;">this</span>->button1->Name = L<span style="color: red;">"button1"</span>;<br /> <span style="color: blue;">this</span>->button1->Size = System::Drawing::Size(<span style="color: deeppink;">63</span>, <span style="color: deeppink;">27</span>);<br /> <span style="color: blue;">this</span>->button1->TabIndex = <span style="color: deeppink;">0</span>;<br /> <span style="color: blue;">this</span>->button1->Text = L<span style="color: red;">"button1"</span>;<br /> <span style="color: blue;">this</span>->button1->UseVisualStyleBackColor = <span style="color: blue;">true</span>;<br /> <span style="color: blue;">this</span>->button1->Click += <span style="color: blue;">gcnew</span> System::EventHandler(<span style="color: blue;">this</span>, &MyForm::button1_Click);<br /><span style="color: #60bf00;"> //<br /> // button2<br /> // </span><br /> <span style="color: blue;">this</span>->button2->Location = System::Drawing::Point(<span style="color: deeppink;">203</span>, <span style="color: deeppink;">47</span>);<br /> <span style="color: blue;">this</span>->button2->Name = L<span style="color: red;">"button2"</span>;<br /> <span style="color: blue;">this</span>->button2->Size = System::Drawing::Size(<span style="color: deeppink;">62</span>, <span style="color: deeppink;">23</span>);<br /> <span style="color: blue;">this</span>->button2->TabIndex = <span style="color: deeppink;">1</span>;<br /> <span style="color: blue;">this</span>->button2->Text = L<span style="color: red;">"button2"</span>;<br /> <span style="color: blue;">this</span>->button2->UseVisualStyleBackColor = <span style="color: blue;">true</span>;<br /> <span style="color: blue;">this</span>->button2->Click += <span style="color: blue;">gcnew</span> System::EventHandler(<span style="color: blue;">this</span>, &MyForm::button2_Click);<br /><span style="color: #60bf00;"> //<br /> // textBox1<br /> // </span><br /> <span style="color: blue;">this</span>->textBox1->Location = System::Drawing::Point(<span style="color: deeppink;">26</span>, <span style="color: deeppink;">12</span>);<br /> <span style="color: blue;">this</span>->textBox1->Name = L<span style="color: red;">"textBox1"</span>;<br /> <span style="color: blue;">this</span>->textBox1->Size = System::Drawing::Size(<span style="color: deeppink;">124</span>, <span style="color: deeppink;">19</span>);<br /> <span style="color: blue;">this</span>->textBox1->TabIndex = <span style="color: deeppink;">2</span>;<br /><span style="color: #60bf00;"> //<br /> // MyForm<br /> // </span><br /> <span style="color: blue;">this</span>->AutoScaleDimensions = System::Drawing::SizeF(<span style="color: deeppink;">6</span>, <span style="color: deeppink;">12</span>);<br /> <span style="color: blue;">this</span>->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;<br /> <span style="color: blue;">this</span>->ClientSize = System::Drawing::Size(<span style="color: deeppink;">292</span>, <span style="color: deeppink;">81</span>);<br /> <span style="color: blue;">this</span>->Controls->Add(<span style="color: blue;">this</span>->textBox1);<br /> <span style="color: blue;">this</span>->Controls->Add(<span style="color: blue;">this</span>->button2);<br /> <span style="color: blue;">this</span>->Controls->Add(<span style="color: blue;">this</span>->button1);<br /> <span style="color: blue;">this</span>->Name = L<span style="color: red;">"MyForm"</span>;<br /> <span style="color: blue;">this</span>->Text = L<span style="color: red;">"MyForm"</span>;<br /> <span style="color: blue;">this</span>->Load += <span style="color: blue;">gcnew</span> System::EventHandler(this, &MyForm::MyForm_Load);<br /> <span style="color: blue;">this</span>->ResumeLayout(<span style="color: blue;">false</span>);<br /> <span style="color: blue;">this</span>->PerformLayout();<br /> }<br /><span style="color: #00bfbf;">#pragma endregion</span><br /> <span style="color: blue;">private</span>: System::Void MyForm_Load(System::Object^ sender, System::EventArgs^ e) {<br /> <span style="color: blue;">this</span>->textBox1->Text = <span style="color: red;">"Initial"</span>;<br /> }<br /> <span style="color: blue;">private</span>: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {<br /> <span style="color: blue;">this</span>->textBox1->Text = <span style="color: red;">"Button1"</span>;<br /> }<br /> <span style="color: blue;">private</span>: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {<br /> <span style="color: blue;">this</span>->textBox1->Text = <span style="color: red;">"Button2"</span>;<br /> }<br /> };<br />}</span></td></tr> </tbody></table> <br />
0 件のコメント:
コメントを投稿
次の投稿
前の投稿
ホーム
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿