文字列を変数名にするには?

解決


モロッコ  2007-03-05 16:12:20  No: 64594  IP: 192.*.*.*

checkBox1,checkBox2,checkBox3,・・・のような構造体に対して同じような処理を行いたいんですが、一つずつ指定して同じ処理を書くのは冗長になってしまいます。そこで、ループさせて統一させようと思うのですが、うまくいきません。

String s;
for(i = 1; i <= 100; i++){
s = "checkBox" + i;
if(s->Checked){};
}

のような処理をしたいのですが、ifの条件のsをその内容の変数名とする方法はないものでしょうか?宜しくお願いします。

編集 削除
Blue  2007-03-05 16:17:20  No: 64595  IP: 192.*.*.*

とりあえず、環境が不明です。
MC++かC++/CLIっぽいけど


>String s;
^や*がついていないので違う。

C#っぽいけど
>->
がでてくるとC++だし。


環境がはっきりしないと回答できるのもできません。

環境明記の例

Windows XP Pro SP2/Visual Studio 2005 Pro SP1/Windows フォームアプリケーション

>checkBox1,checkBox2,checkBox3,・・・のような構造体
構造体ですか?Formに載せたコントロールとかであれば別の方法がありますが、、
C++ではリフレクションのようなことはできないので文字列から変数名にするのは
できないでしょう。

編集 削除
モロッコ  2007-03-05 16:20:54  No: 64596  IP: 192.*.*.*

環境はVisual C++ 2005 Express Editionです。

処理内容はいろいろ略記してしまいました。すみません。
checkBoxはコントロールです。これもすみませんです。

編集 削除
Blue  2007-03-05 16:31:07  No: 64597  IP: 192.*.*.*

方法1.

あらかじめ配列に入れておく。
Formのメンバ変数として 

array<CheckBox^>^ myCheckBoxs;

を用意して、Form_Loadイベントで

this->myCheckBoxs = gcnew array<CheckBox^>(10); // 10個の場合
this->myCheckBoxs[0] = this->CheckBox1;
this->myCheckBoxs[1] = this->CheckBox2;
     ・
     ・
てなかんじで、配列に入れておく。

ただ100個もあるとこれも大変でしょう。。。


方法2.

もとからコントロールを配列で作る。
※この場合デザインモードでCheckBoxを表示できなくなります。


Formのメンバ変数として 

array<CheckBox^>^ myCheckBoxs;

を用意して、Form_Loadイベントで

this->myCheckBoxs = gcnew array<CheckBox^>(10); // 10個の場合
for (int i = 0; i < this->myCheckBoxs->Length; ++i)
{
     this->myCheckBoxs[i] = gcnew CheckBox();
     this->myCheckBoxs[i]->Size = ・・・
     this->myCheckBoxs[i]->Location = ・・・・
     this->myCheckBoxs[i]->Name = "CheckBox" + (i + 1).ToString();
     ・
     ・
}


方法3.

Form::Controlsを使う。

CheckBox^ chk = static_cast<CheckBox^>(this->Controls("CheckBox1"));

というのができるらしい。
ただし、この場合、コントロール名をキーに探すという処理が走るため
上の2つに比べて速度は落ちると思います。

編集 削除
Blue  2007-03-05 16:33:51  No: 64598  IP: 192.*.*.*

>Form::Controlsを使う。
これはできないっぽ。
(現在調査中)

編集 削除
Blue  2007-03-05 16:38:28  No: 64599  IP: 192.*.*.*

Form::Controls::Findで探せるらしい。
http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.control.controlcollection.find(VS.80).aspx

array<Control^>^ ctls = this->Controls->Find("CheckBox1");
if (ctls != nullptr && ctls.Length == 1)
{
    CheckBox^ chk = static_cast<CheckBox^>(ctls[0]);
    if (chk->Checked){}
}

編集 削除
Blue  2007-03-05 16:48:19  No: 64600  IP: 192.*.*.*

ちなみに、100もCheckBoxがあるような画面はあまりふさわしいものではありません。

せめて、CheckedListBoxを使うようにしてみてはどうでしょうか?

編集 削除
Blue  2007-03-05 16:50:16  No: 64601  IP: 192.*.*.*

すみません、Findのコードに誤りがありました。

>array<Control^>^ ctls = this->Controls->Find("CheckBox1");
array<Control^>^ ctls = this->Controls->Find("CheckBox1", true);

です。

編集 削除
モロッコ  2007-03-05 16:53:42  No: 64602  IP: 192.*.*.*

Blueさん、親切でわかりやすいアドバイスと解説ありがとうございました。

自分の感覚的にわかりやすいので元から配列で設定する方法で構築していきたいと思います。本当にありがとうございました。

編集 削除
Blue  2007-03-05 16:56:39  No: 64603  IP: 192.*.*.*

何度もすみません。

>>Form::Controlsを使う。
>これはできないっぽ。
これはインデクサを使えばできるっぽいです。
http://msdn2.microsoft.com/ja-jp/library/s1865435(VS.80).aspx

>CheckBox^ chk = static_cast<CheckBox^>(this->Controls("CheckBox1"));
CheckBox^ chk = static_cast<CheckBox^>(this->Controls["CheckBox1"]);

編集 削除