65365
MFCで子ダイアログ内のCCheckListBoxコントロール内に追加したチェックボックスに✔を入れる方法が分からず問題で困っています。

以下は参考gifです。  
子ダイアログ上のチェックボックスに✔を入れたいのですが、入れられません。  
また、✔を入れられたら、✔を外せるようにしたいです。  
[![画像の説明をここに入力](https://i.stack.imgur.com/i65ZG.gif)](https://i.stack.imgur.com/i65ZG.gif)

上記の処理作成のために、私が作ったソースは以下です。  
ToDoDlg.h(子ダイアログのクラスヘッダー)

```

    #pragma once
    
    
    // ToDoDlg ダイアログ
    
    class ToDoDlg : public CDialogEx
    {
        DECLARE_DYNAMIC(ToDoDlg)
    
    public:
        ToDoDlg(CWnd* pParent = nullptr);   // 標準コンストラクター
        virtual ~ToDoDlg();
    
    // ダイアログ データ
    #ifdef AFX_DESIGN_TIME
        enum { IDD = IDD_TODO_DIALOG };
    #endif
    
    protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV サポート
    
    
    // 実装
    protected:
        HICON m_hIcon;
        // 生成された、メッセージ割り当て関数
        virtual BOOL OnInitDialog();
        DECLARE_MESSAGE_MAP()
    
    private:
        /*privateメンバ変数*/
        // To Do項目チェックボックスコントロールリスト変数
        CCheckListBox m_check_list_box;
        // To Do項目表示文字列入力変数
        CString m_add_edit;
    
        /*privateメンバ関数*/
        afx_msg void OnEnKillfocusCaptionEdit();
    public:
        afx_msg void OnIdok();
    
    };
    
```

ToDoDlg.cpp(子ダイアログのクラス実装部分)

```

    // ToDoDlg.cpp : 実装ファイル
    //
    
    #include "stdafx.h"
    #include "LearningPokect.h"
    #include "ToDoDlg.h"
    #include "afxdialogex.h"
    
    // ToDoDlg ダイアログ
    
    IMPLEMENT_DYNAMIC(ToDoDlg, CDialogEx)
    
    ToDoDlg::ToDoDlg(CWnd* pParent /*=nullptr*/)
        : CDialogEx(IDD_TODO_DIALOG, pParent)
        , m_add_edit(_T(""))
    {
    }
    
    ToDoDlg::~ToDoDlg()
    {
    }
    
    void ToDoDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialogEx::DoDataExchange(pDX);
        DDX_Text(pDX, IDC_ITEM_ADD_EDIT, m_add_edit);
        DDX_Control(pDX, IDC_TO_DO_LIST, m_check_list_box);
    }
    
    
    BEGIN_MESSAGE_MAP(ToDoDlg, CDialogEx)
        ON_EN_KILLFOCUS(IDC_ITEM_ADD_EDIT, &ToDoDlg::OnEnKillfocusCaptionEdit)
        ON_COMMAND(IDOK, &ToDoDlg::OnIdok)
    END_MESSAGE_MAP()
    
    BOOL ToDoDlg::OnInitDialog()
    {
        CDialogEx::OnInitDialog();
    
        // "バージョン情報..." メニューをシステム メニューに追加します。
    
        // IDM_ABOUTBOX は、システム コマンドの範囲内になければなりません。
        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
        ASSERT(IDM_ABOUTBOX < 0xF000);
    
        CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != nullptr)
        {
            BOOL bNameValid;
            CString strAboutMenu;
            bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
            ASSERT(bNameValid);
            if (!strAboutMenu.IsEmpty())
            {
                pSysMenu->AppendMenu(MF_SEPARATOR);
                pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
            }
        }
    
        // このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
        //  Framework は、この設定を自動的に行います。
        SetIcon(m_hIcon, TRUE);         // 大きいアイコンの設定
        SetIcon(m_hIcon, FALSE);        // 小さいアイコンの設定
    
        // TODO: 初期化をここに追加します。
    
        // MFCのチェックリストコントロールが二重に表示されるバグを直すコード
        // 参考：https://stackoverflow.com/questions/57951333/cchecklistbox-items-get-overlapped-on-selection-if-app-build-using-visual-studi
        m_check_list_box.SetFont(GetFont());
    
        // Set the CheckStyle to BS_3STATE, so that check state notifications can be received
        m_check_list_box.SetCheckStyle(BS_3STATE);
    
        return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
    }
    
    // ToDoDlg メッセージ ハンドラー
    
    
    void ToDoDlg::OnEnKillfocusCaptionEdit()
    {
        // TODO: ここにコントロール通知ハンドラー コードを追加します。
        /*エディットコントロールから入力文字を取得し、
        チェックボックスリストコントロールの表示文字に設定する*/
    
        // エディットコントロールの値変数にエディットコントロールで
        // 入力された文字列を代入する
        UpdateData(TRUE);
    
        /*取得した文字列をチェックボックスリストコントロールに設定する
         ダイアログウィンドウを最初に表示する時に
         ToDoDlg::OnEnKillfocusCaptionEdit()が呼ばれた際
         チェックボックスリストコントロールに空文字の項目が作成されないように
         以下の条件文を作成した*/
         // エディットコントロールの値変数が空でない場合
        if (!m_add_edit.IsEmpty())
        {
            // チェックボックスリストコントロールに
            // エディットコントロールの値変数に格納されている
            // 文字列を追加する
            m_check_list_box.AddString(m_add_edit);
    
            // チェックボックスリストコントロールに
            // エディットコントロールの値変数に格納し終えたので、
            // エディットコントロールの値変数に入力されている文字列を削除する
            m_add_edit = _T("");
            UpdateData(FALSE);
    
    
        }
    
        /* 入力した文字列はエディットコントロールから削除する */
    }
    
    /*Enter押下時のイベントハンドラ*/
    void ToDoDlg::OnIdok()
    {
        // TODO: ここにコマンド ハンドラー コードを追加します。
        // OnEnKillfocusCaptionEditイベントハンドラ内の
        // 必要な処理を関数化して、ここにも貼り付ける
        // 理由：Enterを押したときにOnEnKillfocusCaptionEditと
        // 同様の処理をするため。
    }
    
```

試してみたことは以下です。  
・MFCダイアログベースプロジェクトを新規作成して、最初に自動作成されるダイアログにCCheckListBoxコントロールを作成して、✔を入れる処理を作った。  
試した理由：  
子ダイアログでないダイアログなら✔を入れる処理を書かなくても✔を入れたり外したりする処理が作れるか確認するため。  
結果：  
チェックボックスに✔を入れたり外したりできた。

ただ、なぜ本問題が起きている子ダイアログにCCheckListBoxコントロールを作成すると、チェックボックスに✔を入れたり、外したりできないかが分かりませんでした。

なので、ソースを手動で書けばよいと思い、SetCheck関数を使って、✔を入れたり外したりする処理を作ろうと思いましたが、CCheckListBoxのプロパティにあるどのイベントを使えばよいか分かりませんでした。

解決策を教えて頂けるとありがたいです。どうかよろしくお願い致します。
CC BY-SA 4.0
2020-04-05T06:31:47.483
65361
2020-04-05T11:00:43.650
2020-04-05T08:26:11.530
21034
21034
question
mfc
子ダイアログ内のCCheckListBoxコントロール内に追加したチェックボックスに✔を入れる方法が分からない
[CTabCtrlにCDialogを埋め込む(VC++)](https://www.kazetest.com/vcmemo/dlgintab/dlgintab.htm)を以下のように改造して特に問題無く動作しています。  
Visual Studio Community 2019でプロジェクトをアップグレードして改造

`TabDlg.rc`の主な変更部分

```

    IDD_TABDLG_DIALOG DIALOGEX 0, 0, 139, 170
    STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
    EXSTYLE WS_EX_APPWINDOW
    CAPTION "TabDlg"
    FONT 9, "MS UI Gothic", 0, 0, 0x1
    BEGIN
        CONTROL         "",IDC_TAB1,"SysTabControl32",0x0,7,7,125,140
        PUSHBUTTON      "Button1",IDC_BUTTON1,7,148,35,15
    END
    
    IDD_DIALOG1 DIALOGEX 0, 0, 124, 120
    STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
    FONT 8, "MS Shell Dlg", 400, 0, 0x1
    BEGIN
        LTEXT           "データ１",IDC_STATIC,7,7,30,9
        EDITTEXT        IDC_EDIT1,7,23,82,15,ES_AUTOHSCROLL
        PUSHBUTTON      "Add",IDC_BUTTON1,90,23,27,15
        LISTBOX         IDC_LIST1,7,40,110,73,LBS_SORT | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
    END
    
```

`Dlg1.h`

```

    #pragma once
    // CDlg1 dialog
    class CDlg1 : public CDialog
    {
        DECLARE_DYNAMIC(CDlg1)
    public:
        CDlg1(CWnd* pParent = NULL);   // standard constructor
        virtual ~CDlg1();
    // Dialog Data
        enum { IDD = IDD_DIALOG1 };
    protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
        DECLARE_MESSAGE_MAP()
    public:
        CString m_strEdit1;
        afx_msg void OnBnClickedButton1();
        CCheckListBox m_check_list_box;
    };
    
```

`Dlg1.cpp`

```

    // Dlg1.cpp : implementation file
    //
    #include "stdafx.h"
    #include "TabDlg.h"
    #include "Dlg1.h"
    // CDlg1 dialog
    IMPLEMENT_DYNAMIC(CDlg1, CDialog)
    CDlg1::CDlg1(CWnd* pParent /*=NULL*/)
        : CDialog(CDlg1::IDD, pParent)
        , m_strEdit1(_T(""))
    {
    }
    CDlg1::~CDlg1()
    {
    }
    void CDlg1::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
        DDX_Text(pDX, IDC_EDIT1, m_strEdit1);
        DDX_Control(pDX, IDC_LIST1, m_check_list_box);
    }
    BEGIN_MESSAGE_MAP(CDlg1, CDialog)
        ON_BN_CLICKED(IDC_BUTTON1, &CDlg1::OnBnClickedButton1)
    END_MESSAGE_MAP()
    // CDlg1 message handlers
    void CDlg1::OnBnClickedButton1()
    {
        UpdateData(TRUE);
        if (!m_strEdit1.IsEmpty())
        {
            m_check_list_box.AddString(m_strEdit1);
            m_strEdit1 = _T("");
            UpdateData(FALSE);
        }
    }
    
```

表示結果

[![子ダイアログのCheckListBox](https://i.stack.imgur.com/tHmMk.png)](https://i.stack.imgur.com/tHmMk.png)
CC BY-SA 4.0
2020-04-05T11:00:43.650
65365
2020-04-05T11:00:43.650
26370
65361
answer