今回はMFCアプリで頻繁に使うコントロールの一つ、
CStaticクラスの操作方法について。
主に、自分がよく使う操作の備忘録です。
準備
プロジェクト作成
プロジェクトの作成方法、コントロールの配置方法は
こちらをご覧ください。
今回のプロジェクト名は「CStaticTest」にします。
コントロールID
Static Textを配置後、IDを変更します。
デフォルト(IDC_STATIC)でも問題ないですが、
わかりやすくするため変更を。
プロパティタブへ飛び、ID欄から変更します。

今回は、ID名をIDC_STATIC_TESTに変更します。
また、お好みで幅を広げたり、デフォルトのテキストを消します。
コントロールを選択後、Deleteボタンで消すことができます。

ビルド
最後にソリューションのビルドを実施し、
出来上がるexeファイルを一度確認します。
完成したのがこちら。

処理記述場所
プロジェクトを一つ作成すると、
プロジェクト名Dlg.cpp
というファイルが出来上がります。
今回ですとCStaticTestDlg.cppです。
そこの
OnInitDialog
関数内に処理を記述します。
Visual Studioのバージョンによって異なるかもしれませんが、
デフォルト処理は下記のよう。
BOOL CCStaticTestDlg::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: 初期化をここに追加します。
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}ご丁寧に30行目に処理追加コメントがありますので、
それよりも下に処理を入れていきます。
テキスト変更 (おまけで方式説明)
プロパティから変更
表示⇒キャプションから変更です。

これはわかりやすい。
しかし、これだと動的な変更ができません。
プログラムからテキスト変更することもできます。
というか、こちらの方を(自分は)よく使います。
プログラムから変更
動的コントロール取得 (GetDlgItem方式)
GetDlgItemを使用して、コントロールのポインタを動的に取得し、操作します。
先のOnInitDialogに記述。
BOOL CCStaticTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 略
// TODO: 初期化をここに追加します。
CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_TEST);
pStatic->SetWindowText(_T("OnInitDialogからGetDlgItemを使用して変更しました"));
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}書き方は
CStatic* 変数名 = (CStatic*)GetDlgItem(コントロールID);
変数名->SetWindowText(変更したい文字列);
です。
一度これでビルドします。
出来上がったexeを開くと

反映されました。
メンバ変数バインド (DDX_Control方式)
DDX_Controlマクロを使用してコントロールを事前にメンバ変数にバインドし、
そのメンバ変数を使って操作します。
事前準備。
プロジェクト名Dlg.hというファイルがあるので開きます。
今回ですと、CStaticTestDlg.hです。
メンバ変数m_ctrlStaticを定義します。
class CCStaticTestDlg : public CDialogEx
{
// 略
private:
CStatic m_ctrlStatic;
};次いでCStaticTestDlg.cppに戻り、バインド準備。
昔だと自分は紐づけって言ってましたが、
バインドの方が一般らしいです。
元から用意されてあるDoDataExchange関数に1行追加します。
void CCStaticTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_STATIC_TEST, m_ctrlStatic);
}4行目のDDX_Controlを追加です。
この準備の下、OnInitDialogでテキストを変更する処理を加えます。
BOOL CCStaticTestDlg::OnInitDialog()
{
// 略
// TODO: 初期化をここに追加します。
//CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_TEST);
//pStatic->SetWindowText(_T("OnInitDialogからGetDlgItemを使用して変更しました"));
m_ctrlStatic.SetWindowText(_T("OnInitDialogからDDX_Controlを使用して変更しました"));
UpdateData(FALSE);
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}必要なのは9行目と10行目。
メンバ変数.SetWindowText(変更したい文字列);
です。
その後、UpdateData(FALSE)で、実際のコントロールに反映させます。
ビルドします。

反映されました。
どっちがいいの?
どちらもCStaticクラスの関数を呼ぶことができます。
一長一短なので、使い分ければいいかと。
動的コントロール取得の場合、
- 必要な時にコントロールを取得する⇒簡単な操作では便利
- 反面、スコープ外に出るとまたポインタ変数を再定義する必要あり
- 再利用や保守性がやや低め
メンバ変数バインドの場合、
- 事前にバインドするので上記の例だと1行で済む
- 保守性は高い(らしい 自分はそこは詳しくないです)
- たった1回だけ操作する場合、ヘッダー、DoDataExchangeと、
コード記載量と実際の処理とで労力が見合わない
シンプルな操作の場合はGetDlgItemを、
何度も操作したり複雑な操作が必要な場合はDDX_Controlを使用するケースが
望ましいかもしれません。
以降、GetDlgItem方式で紹介します。
テキスト表示・非表示
スタティックテキストの表示・非表示を切り替えることができます。
BOOL CCStaticTestDlg::OnInitDialog()
{
// 略
// TODO: 初期化をここに追加します。
CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_TEST);
pStatic->ShowWindow(SW_HIDE); //非表示
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}
引数をSW_SHOWにすると表示させることができます。
デフォルトは、表示させる設定です。
活性・非活性
そのコントロールが活性か、非活性かを切り替えることができます。
スタティックテキストの場合、わかりにくいかもしれません。
ボタンやエディットボックスの場合、非活性だと触れない(編集できない)ようになります。
一応スタティックテキストも、非活性の場合は文字が薄くなります。
BOOL CCStaticTestDlg::OnInitDialog()
{
// 略
// TODO: 初期化をここに追加します。
CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_TEST);
pStatic->EnableWindow(FALSE); //非活性
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}
見えにくいですが、薄くなってますね。
引数をTRUEにすると、活性化します。
デフォルトは活性です。
おまけ
ポインタを指定しないままSetWindowTextを使用した場合、
ダイアログのキャプションを変更できます。
BOOL CCStaticTestDlg::OnInitDialog()
{
// 略
SetWindowText(_T("これはダイアログ上部に現れるキャプションです"));
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}
終わりに
今回は、自分がよく使うCStatic関連の処理をまとめてみました。
他にも、枠線で囲うことも稀にありますが、
プロパティから設定できるので、ぜひ試してみてください。

コメント