この記事は2018年08月18日に投稿しました。
目次
プロフェッショナル VISUAL C++ 2010 (MSDNプログラミングシリーズ)
- 作者: エディフィストラーニング株式会社,矢嶋聡
- 出版社/メーカー: 日経BP
- 発売日: 2012/07/05
- メディア: 単行本
- この商品を含むブログ (1件) を見る
1. はじめに
こんにちは、iOSのエディタアプリPWEditorの開発者の二俣です。
今回は業務で使用しているC++/CLIの話です。
前回
paveway.hatenablog.com
を説明しました。
別スレッドで処理した結果を、例えばラベルに表示したりする状況はよくあると思います。
しかしラベルなどのUIコントロールはUIスレッドで処理する必要があります。
そのため別スレッドからUIを操作する方法が必要になります。
2. 別スレッドからUIを操作する
別スレッドからUIを操作する方法は以下の通りです。
- 別スレッドからUIを操作するメソッドのデリゲートを定義します。
- 1で定義したデリゲートと同じ戻り値、引数のUIを操作するメソッドを用意します。
- 別スレッドで行うメソッドでは、InvokeRequiredプロパティによりこのメソッドを呼び出したスレッドが別スレッドかチェックします。
- 3のメソッドが別スレッドから呼び出された場合、Invokeメソッドにより、デリゲート経由でこのメソッドを実行します。
ref class SampleForm { private: // 1. 別スレッドからUIを操作するメソッドのデリゲートを定義します。 // 戻り値、引数有りのメソッド例です。 delegate bool SetTextDelegate(String^ text); // 戻り値、引数無しのメソッド例です。 delegate void SetDisableDelegate(); /// 別スレッドを開始します。 void StartExecThread() { ThreadStart^ start = gcnew ThreadStart(this, &SampleForm::SetTextThread); Thread^ thread = gcnew Thread(start); thread->Start(); } /// 別スレッドで行うメソッドです。 void SetTextThread() { String^ result = <何らかの処理>; // 戻り値有り、引数有りのUIを操作するメソッドを呼び出します。 bool result = SetText(result); // 戻り値無し、引数無しのUIを操作するメソッドを呼び出します。 SetDisable(); } /// 2. UIを操作するメソッドです。 /// 戻り値有り、引数有りのメソッド例です。 /// 引数の文字列をラベルに設定します。 bool SetText(String^ result) { bool result = false; // 3. このメソッドを呼び出したスレッドが別スレッドかチェックします。 // 別スレッドからこのメソッドを呼び出した場合 if (this->InvokeRequired) { // 4. Invokeメソッドにより、デリゲート経由でこのメソッドを実行します。 SetTextDelegate^ method = gcnew SetTextDelegate(this, &SampleForm::SetText); // 引数パラメータを設定します。 // 引数が複数ある場合、複数設定します。 array<Object^>^ args = { result }; // Invokeメソッドを戻り値有り、引数パラメータ有りで実行します。 // 戻り値はObject型のため、適切な型にキャストします。 result = (bool)this->Invoke(method, args); } // UIスレッドからこのメソッドを呼び出した場合 else { result = this->ResultLabel->Text(result); } return result; } // 2. UIを操作するメソッドです。 // 戻り値、引数無しのメソッド例です。 // ボタンを無効にします。 void SetDisable() { // 3. このメソッドを呼び出したスレッドが別スレッドかチェックします。 // 別スレッドからこのメソッドを呼び出した場合 if (this->InvokeRequired) { // 4. Invokeメソッドにより、デリゲート経由でこのメソッドを実行します。 SetDisable^ method = gcnew SetDisableDelegate(this, &SampleForm::SetDisable); // Invokeメソッドを戻り値無し、引数パラメータ無しで実行します、 this->Invoke(method); } else { this->ExecButton->Enable = false; } } };
API Reference
InvokeRequiredプロパティ
Invokeメソッド
3. おわりに
AndroidやiOSでも、UI操作はUIスレッドで行う必要があります。
そのためAndroid、iOSでも同じような仕組みはありますが、ほかに比べてC++/CLIの場合、
- デリゲートの定義
- 別スレッドかのチェック
- Invokeメソッドによる実行
と少し煩雑です。
C++/CLI & OpenCV画像処理GUIプログラミング―リッチなユーザーインターフェースを持つ画像処理プロ
- 作者: 北山洋幸
- 出版社/メーカー: カットシステム
- 発売日: 2013/03/01
- メディア: 単行本
- この商品を含むブログ (3件) を見る
紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。
私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッドOS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOSモバイルアプリやウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。
また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。
EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688