お世話になっております。
最近、Visual Studio 2005 ProからVisual Studio 2010 Proにアップグレード
しました。MFCを使用してソフト開発をしています。
VC++2005のプロジェクトをVC++2010でビルドとして実行すると、
ツールバーの各ボタンの背景の色とツールバー自体の背景の色が
ずれてしまう現象が起きています。
具体的には各ツールボタンの背景は薄いグレーですが、
ツールバーの背景(上記の画像の右側の広い部分)や境界線は
薄い青色になっています。
↓こんな感じです。
http://uploadr.net/file/96c5c45c72
MFCのソースコードをトレースしてみると、
void CControlBar::DoPaint(CDC* pDC)
{
// paint inside client area
CRect rect;
GetClientRect(rect);
DrawBorders(pDC, rect);
DrawGripper(pDC, rect);
}
DrawBorders()やDrawGripper()の内部では「afxData.clrBtnHilite,
afxData.clrBtnShadow」などの内部変数を参照して背景色を決定しているようです。
自分としては薄い青色になってしまっている部分を元のように
薄いグレーにしたいのですが、どのようにすればよいのでしょうか?
ご存じの方がいましたら、アドバイスをお願い致します。
>↓こんな感じです。
> http://uploadr.net/file/96c5c45c72
ん? これってWindows 7の画面では?
もし、そうだとしたら、
Visual Studio 2010は、Windows 7対応なんで、ただ「薄い青色」が標準になっている
のではないでしょうか?
コメントありがとうございました。
> Visual Studio 2010は、Windows 7対応なんで、ただ「薄い青色」が標準に
> なっているのではないでしょうか?
これでも良いのですが、その場合にはツールバーの各ボタンの背景も
同じように薄い青色になって欲しいなぁ・・・と思いました。
もともとリソースのビットマップ上では背景はRGB(192, 192, 192)色にして
ありますが、この部分がおそらく透過色として扱われて、OSや
デスクトップテーマによって実際に描画される色が異なります。
結局ボタンの背景色を描画している部分が分からなかったので、
原因は分からなかったのですが、現在はCToolBarからCMFCToolBarクラスへの
移行を行っています。
新しいクラスを使うとプロパティウィンドウや出力ウィンドウなどの
ペインが簡単に追加できるだけでなく、ビジュアルスタイルの適用も
簡単にできてとても便利です。
CControlBarクラスからCPaneクラスへの移行はけっこう大変ですが・・・
ヘルプには以下のように記載されていますが、実際にはこれ以外にも
かなり修正する箇所があります。
-------------------------
CPaneクラスは、CControlBarクラスの拡張版です。
既存のMFCプロジェクトをアップグレードしている場合は、
CControlBarの出現箇所をすべてCPaneに置き換える必要があります。
-------------------------
話が横道にそれてしまってすいません。
そのようなわけですので、とりあえずこのスレッドは終了させて頂きます。
既に解決済みとなっていますが、とても気になったので私も調べてみました。
Windows 7 + VC++2010 + MFC でのテストです。
付属のサンプルプロジェクトである「Scribble」での結果ですが、
まったく同様の現象が起きますね。
http://uploadr.net/file/7aa063bf3a
この現象が起きる条件は、、、
・WinXPのビジュアルスタイルを適用するためのマニフェストを追加してあること。
・CToolBarクラスのツールバーを使用しており、作成時に以下のように
境界線を指定していること。
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT,
WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP, CRect(4, 4, 4, 4)) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0(Failed to create toolbar\n);
return -1; // fail to create
}
まず、ツールバーの背景を薄い青色にしてしまうには、
拡張スタイルに「TBSTYLE_TRANSPARENT」を追加します。
これで、境界線との色が揃います。これが一番簡単な解決方法のようです。
逆に、境界線の色をツールバーの背景(薄いグレー)に合わせる方法が分かりませんで
した。
MFCのソースを読んでみた感じでは、
VC++2010のCControlBarクラスには、新しく「m_hReBarTheme」というデータメンバが
追加されており、OSがデスクトップテーマに対応していると、制御用のハンドルが
保持されるようです。この仕組みはVC++2005のMFCにはありませんでした。
そして、m_hReBarThemeにハンドルがセットされていると、
CToolBar::DrawBorders()とCToolBar::DrawGripper()の動作が変わります。
具体的には「CThemeHelper::DrawThemeBackground」という関数で
青色の境界線が描画されるようです。
一方、各ツールボタンの背景はデスクトップテーマとは一切関係なく、
GetSysColor()で得た情報を元に描画されるようです。
これが色の不一致の原因だと思います。
AfxLoadSysColorBitmap()という関数がポイントとなっているようで、
{ AFX_RGB_TO_RGBQUAD(0x00, 0x00, 0x00), COLOR_BTNTEXT },
{ AFX_RGB_TO_RGBQUAD(0x80, 0x80, 0x80), COLOR_BTNSHADOW },
{ AFX_RGB_TO_RGBQUAD(0xC0, 0xC0, 0xC0), COLOR_BTNFACE },
{ AFX_RGB_TO_RGBQUAD(0xFF, 0xFF, 0xFF), COLOR_BTNHIGHLIGHT }
のようなマッピングにより、例えば、ツールボタンのビットマップの中で
使用されているRGB(0xC0, 0xC0, 0xC0)色が、GetSysColor(COLOR_BTNFACE)で
得られる色に置き換えられます。これはビットマップのパレットを
直接操作していました。つまり、透過処理ではなくて色の置き換え処理ですね。
ちなみに、m_wndToolBar.m_hReBarThemeを無理矢理NULLにしてみると、
境界線の部分が真っ白になってしまいます。ボタンの背景色と同じにはなりません。
結局、境界線やグリッパーなどの領域をGetSysColor(COLOR_BTNFACE)の色で
描画する方法は分かりませんでした。
個人的には、メニューバーは薄い青でもいいですが、
ツールバーは薄いグレーの方が見やすいのですが・・・