64029


MFCでCCheckListBoxクラスのコントロール処理を作成し、デバッグ実行したらCCheckListBox内に☐がデフォルトで表示される問題で困っています。

参考画像：  
[![参考画像](https://i.stack.imgur.com/CvtCj.png)](https://i.stack.imgur.com/CvtCj.png)

期待していたCCheckListBoxの状態は、CCheckListBox内に☐がデフォルトで表示されない状態です。  
上記の処理作成のために、私が作ったソースは以下です。  
ToDoDlg.h(子ダイアログのクラスヘッダー)

[code]

    #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();
    };
    };
    
    
[/code]

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

[code]

    // 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_CAPTION_EDIT, m_add_edit);
        DDX_Control(pDX, IDC_TO_DO_LIST, m_check_list_box);
    }
    
    
    BEGIN_MESSAGE_MAP(ToDoDlg, CDialogEx)
        ON_EN_KILLFOCUS(IDC_CAPTION_EDIT, &ToDoDlg::OnEnKillfocusCaptionEdit)
    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());
    
        return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
    }
    
    // ToDoDlg メッセージ ハンドラー
    
    
    void ToDoDlg::OnEnKillfocusCaptionEdit()
    {
        // TODO: ここにコントロール通知ハンドラー コードを追加します。
        /*エディットコントロールから入力文字を取得し、
        チェックボックスリストコントロールの表示文字に設定する*/
    
        // エディットコントロールの値変数にエディットコントロールで
        // 入力された文字列を代入する
        UpdateData(TRUE);
        CString edit_CString = m_add_edit;
    
        // 取得した文字列をチェックボックスリストコントロールに設定する
        m_check_list_box.AddString(edit_CString);
    }
    
    
[/code]

この問題を解決するために、CCheckBoxListコントロールのプロパティや関数を調べてみましたが、解決策が見つかりませんでした。

解決策を教えて頂けるとありがたいです。どうかよろしくお願い致します。


CC BY-SA 4.0
2020-03-22T12:34:38.863
64028
2020-03-22T22:55:30.047
21034
question
mfc
デバッグ実行直後にCCheckListBoxの☐のみ表示される


ダイアログウィンドウを最初に表示する時に`ToDoDlg::OnEnKillfocusCaptionEdit()`が呼ばれるため、`m_check_list_box.AddString(edit_CString);`によって空文字列が追加されるからです。

例えば以下のように`edit_CString`が空文字列なら`m_check_list_box.AddString(edit_CString);`を行わない等の処理を行えば発生しません。

[code]

    if (!edit_CString.IsEmpty())
    {
        m_check_list_box.AddString(edit_CString);
    }
    
[/code]

* * *

なお、学習のため？に色んなことを試しているようですが、上記質問＆回答のように色んな機能の呼び出しに`KillFocus`を使い回すことは予期せぬ問題を呼び込むことになるようなので、今後は止めておいたほうが良いと思われます。


CC BY-SA 4.0
2020-03-22T16:10:49.903
64029
2020-03-22T22:55:30.047
2020-03-22T22:55:30.047
26370
26370
64028
answer