質問: すみません。プログラミング初心者レベルの者です。 MFCでチェックボックスコントロールをダイアログ上に複製する処理を作りたいのですが、 どうすればそれが作れるでしょうか? ![画像の説明をここに入力](https://i.stack.imgur.com/FgviV.png) ボタンコントロールのイベントハンドラを作成後、 チェックボックスコントロールのコントロール変数を作成して、 チェックボックスコントロールを複製する関数があるかMSDNを見たりネットで検索しましたが、 やり方が分かりませんでした。 教えて頂けるとありがたいです。 どうぞよろしくお願い致します。
回答: **純粋に単純なダイアログウィンドウにチェックボックスを追加作成するだけの処理について回答します。** タブコントロール上の子ウィンドウに表示するにはどうするかとか、それぞれのチェックボックスでチェック状態が変化した時の処理ルーチンとか、チェックボックスの表示/非表示や文言を変更したり、プログラム終了時に廃棄するには? と言ったことは別途自分で検索するなり考えてみるなりしてください。 `XxxxDlg.h`に以下を追加します。 ``` // 作成するCheckBoxのIDの開始番号と開始左端位置 #define IDBASE_CHECKBOX 2000 #define LEFTBASE_CHECKBOX 10 // 作成したCheckBoxを記憶しておく配列オブジェクト CObArray m_CheckBoxArray; int m_CumulativeCount; // 作成したCheckBoxの累積数 ``` `XxxxDlg.cpp`の`追加ボタン`のクリック処理に以下を実装します。 10個を1列として下に表示して行き、10個毎に列を変えて表示するようになっています。 ``` CButton *pCheckBox = new CButton(); // CheckBox用CButtonオブジェクト作成 int cbaCount = m_CheckBoxArray.GetCount(); // CheckBox用表示領域の計算 int cbLeft = (10 + ((cbaCount / 10) * 200));// 以下同じ(位置やサイズは適当に調整する) int cbTop = (10 + ((cbaCount % 10) * 24)); int cbRight = cbLeft + 160; int cbBottom = cbTop + 20; CString cbCaption; // 以下と併せてCheckBox用表示文言作成 cbCaption.Format(_T("Check Item No. %d"), (m_CumulativeCount + 1)); // CheckBox作成 pCheckBox->Create(cbCaption, WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, CRect(cbLeft, cbTop, cbRight, cbBottom), this, (IDBASE_CHECKBOX + m_CumulativeCount)); // 作成したCheckBoxを配列に格納 m_CheckBoxArray.Add(pCheckBox); m_CumulativeCount++; // 作成したCheckBoxの累積数を更新 ``` ちなみにチェック状態が変化した時の処理ルーチンをどのように定義して呼び出されるようにするか、についてはこの記事を応用することで出来るでしょう。 動的に作成したStatic Textのクリックイベント `XxxxDlg.h`に以下を追加します。 * チェックボックスに対して割り付けるIDの最大値 * `afx_msg void Yyyy(UINT id)`で処理ルーチンの定義 `XxxxDlg.cpp`に以下を追加します。 * `BEGIN_MESSAGE_MAP`と`END_MESSAGE_MAP`の間に`ON_COMMAND_RANGE(ID最小値, ID最大値, 処理ルーチンアドレス(&クラス名::Yyyy))`を定義 * `void クラス名::Yyyy(UINT id)`関数を定義し、`id`パラメータでどのチェックボックスが変更されたかを特定し、対応する処理を行う 他の人の回答だと **「複製」** という言葉がこだわりの心を呼び覚ましてしまったようですが、質問画面上の「To Do」と「完了」と書いてあるのを考えると、予定や課題の増減/完了をリストにしたいのが目的でしょう。 その場合、単独のチェックボックスを複製する(したように見せかける)のではなく、より相応しいであろうCCheckListBoxクラスに切り替えるのが簡単でリーズナブルだと思われます。変なテクニックを使う必要も無くなりますし。 (太字は引用者) CCheckListBox の使い方 > > 1. 通常の手順で,リストボックスをダイアログに貼り付ける. > 2. コントロールのプロパティを「オーナー描画」-「固定」,「文字列あり」-「チェック」に変更する. > 3. クラスウィザードなどを利用して,コントロールの変数(CListBox)を登録する. > 4. ヘッダファイルを開いて,CListBox を CCheckListBox に変更する. > 5. **項目の追加は,CListBox などと同様に AddString など.** > 6. チェックの指定は,SetCheck で. > > > 上記記事にあったCListBoxでのAddStringの使用例 CListBox::AddString 直接的な関連は無いですがCCheckListBoxを扱った記事 セルフ描画コントロール Checkboxes in MFC listbox are appearing differently in VS2015 CCheckListBox items get overlapped on selection if app build using 'Visual Studio 2017 (v141)' Platform Toolset