2013年9月2日月曜日

MFCのタブコントロールの背景を灰色に変える。

VisualStudio2012 (VS2012) C++  MFC

今時ではないが、昔作ったMFCを再コンパイルしたら、ダメじゃん。

MFCのタブコントロールはそのままでは背景が白なので、コントロールを並べると奇妙な感じになる。これの背景色を普通の灰色に戻したい。Theme系のAPIを使っていたのだが、XP専用のようで、サポートされなくなってしまって、VS2012で再コンパイルするとサポート外でコンパイルエラーになってしまう。よって、Theme系コーディングを削除した結果がこの通り。格好悪い。

image

CTabCtrl これのMFCの作り込みがおかしいんじゃないのかな。一貫性が無いのはタブコントロールがMFCのコントロールではなくVB用のコントロール?かな。愚痴は一杯あるんだ。それでもMFCのサポートをやめないでいる(現時点では嘘をついていない)ところだけは認めてあげたい。

グーグル先生の指示ではオーナードローで回避するようにということなので、以下の通り。

まず、ダイアログ編集画面でタブコントロール(例:IDC_TAB1)のプロパティOwnerDrawFixed Trueにする。

ダイアログメンバーにブラシを作っておく。クラスメンバー CBrush m_brGr;で構わない。コンストラクタで作っておく。

   ...コンストラクタ....
DWORD     bkColor = GetSysColor(COLOR_3DFACE);
m_brGr.CreateSolidBrush(bkColor);

ダイアログのクラスウィザードを開いて、メッセージWM_DRAWITEMのハンドラ作成を指示するとOnDrawItem()が出来る。

.hヘッダーファイルには、クラスウィザードにより
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);

.cppファイルには、メッセージ振り分け

BEGIN_MESSAGE_MAP(CSampleDlg, CDialog)
  ON_NOTIFY_EX(TTN_NEEDTEXT, 0,OnToolTipNotify)
  ......
  ON_WM_DRAWITEM()
END_MESSAGE_MAP()


が追加されて、エントリも追加されるのでエントリを以下の様に書き替えます。

void CSampleDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpdis)
{
    char        szTabText[100];
    RECT        rect;
    UINT        bkColor;
    CBrush      *cbr;
    TC_ITEM     tci;

    CTabCtrl    *pTabCtrl = (CTabCtrl *)GetDlgItem(IDC_TAB1);
   
    if (pTabCtrl->m_hWnd == lpdis->hwndItem)
    {
        bkColor = GetSysColor(COLOR_3DFACE);
        cbr = &m_brGr;
        memset(szTabText, '\0', sizeof(szTabText));

        tci.mask        = TCIF_TEXT;
        tci.pszText     = szTabText;
        tci.cchTextMax  = sizeof(szTabText)-1;

        pTabCtrl->GetItem(lpdis->itemID, &tci);

        CDC *dc = CDC::FromHandle(lpdis->hDC);

        dc->FillRect(&lpdis->rcItem, cbr);
        dc->SetBkColor(bkColor);
        CSize size2;
        ::GetTextExtentPoint(lpdis->hDC, tci.pszText, strlen(tci.pszText), &size2);
        CRect rect2 = CRect(lpdis->rcItem);
        TextOut(lpdis->hDC,
            lpdis->rcItem.left + rect2.Width()/2 - size2.cx / 2,
            lpdis->rcItem.top + rect2.Height() / 2 - size2.cy / 2,
                tci.pszText,
                lstrlen(tci.pszText));
    }
    else
        CDialog::OnDrawItem(nIDCtl, lpdis);
}

 

ま、こんなところだろう。無駄なコーディングはパクリ元と比較してもらうとわかります。面倒な削除はしていません。描画文字は中央描画にしておいた。ほぼパクリだから、パクリ元を見た方が簡単かもしれましぇん。ごめんなさい。

 

image

 

参考(ほぼ以下のサイトのパクリです)

MSDN タブコントロールの背景色の指定(サンプルコードにバグがあるよね。)
http://support.microsoft.com/kb/179909/en-us

ダイアログの背景色取り出し
http://isobe.exblog.jp/2465331/

0 件のコメント:

コメントを投稿