[MFC] Static Textを使ってハイパーリンクっぽいボタンを作る
2020年になりましたが、MFCを触る機会はなかなかなくならないですね。
こういうボタンを作る必要があるときの実装をまとめました。

環境
- Windows10 64bit
- Visual Studio 2015
概要
プロジェクト作成時に「MFCのダイアログベース」を選択したものとして、以降の実装を行っています。
今回は以下のような構成のプロジェクトをベースにします。

スタティックテキストをリソースエディタで編集する
初期状態で配置されている「IDC_STAIC」のスタティックテキストをボタンにしていきます。
CButtonで作ると手間がかかるので使いません。

ダイアログのリソースエディタを開いて、ダイアログの中央にあるスタティックテキストを選択してから、プロパティを開いて編集します。
- IDを「IDC_STATIC」から「IDC_STATIC_HYPER」に変更
- Captionを「ハイパーリンク」に変更

リソースを取得する
コード側で設定する必要があるのでリソースから取得できるようにしていきます。
ダイアログクラスに以下の宣言を追加します。
CStatic hyperLink_; COLORREF fontColor_; CFont font_;
ダイアログクラスのDoDataExchange()にリソースを取得する処理を追加します。
void CSample_HyperLinkDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_STATIC, hyperLink_); }
スタティックテキストの文字色を設定する
ダイアログクラスのOnInitDialog()に、実装を追加します。
BOOL AuthorizerDlg::OnInitDialog() { CDialogEx::OnInitDialog(); (省略) // 文字色を作成する. fontColor_ = RGB(0, 0, 255); // アンダースコアの付いたフォントを作成する. CFont* pFont = hyperLink_.GetFont(); LOGFONT lFont; pFont->GetLogFont(&lFont); lFont.lfUnderline = TRUE; font_.CreateFontIndirect(&lFont); hyperLink_.SetFont(&font_, TRUE); return TRUE; }
ダイアログクラスにOnCtlColor()のオーバーライドを追加します。
class CSample_HyperLinkDlg : public CDialogEx { (省略) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV サポート virtual HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); // 追加 (省略) }
OnCtlColor()に文字色を設定する処理を追加します。
HBRUSH CSample_HyperLinkDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); if (pWnd == &this->hyperLink_) { pDC->SetTextColor(fontColor_); } return hbr; }
メッセージマップにもON_WM_CTLCOLOR()を追加します。
BEGIN_MESSAGE_MAP(CSample_HyperLinkDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_CTLCOLOR() // 追加 END_MESSAGE_MAP()
この時点で起動すると、このようになっています。

スタティックテキストにクリックイベントを追加する
ダイアログのリソースエディタを開いて、スタティックテキストのプロパティを開きます。
「表示」に「Notify」という項目があるので、これを「True」にします。

リソースエディタ上の「ハイパーリンク」をダブルクリックします。

ダイアログクラスに以下のクリックイベントの実装が追加されます。
ヘッダへの宣言と、メッセージマップも合わせて追加されています。
void CSample_HyperLinkDlg::OnStnClickedStaticHyper() { // TODO: ここにコントロール通知ハンドラー コードを追加します。 }
クリック時の処理を追加する
ボタンとして機能しているか確認するために、適当にメッセージボックスを表示してみます。
void CSample_HyperLinkDlg::OnStnClickedStaticHyper() { AfxMessageBox(L"はいぱー", MB_ICONINFORMATION); }
ハイパーになりました。

おしまい。
ディスカッション
コメント一覧
まだ、コメントがありません