0

MFCチェックボックスとラジオボタンの外観(背景色とテキストの前景色)を変更するために、次の実装を使用しました。これは、Windows2000では正常に機能し、Windows XPでは半分は問題ありませんが、Windows7では問題ありません。

BEGIN_MESSAGE_MAP(mycheckbox, CButton)
  ...
  ON_WM_CTLCOLOR_REFLECT()
  ...
END_MESSAGE_MAP()

HBRUSH mycheckbox::CtlColor(CDC* pDC, UINT nCtlColor)
{
  pDC->SetBkColor( RGB( 255, 0, 0 ) );
  pDC->SetTextColor( RGB( 0, 255, 0 ) );
  return m_brush;
}

これは、Windowsクラシックテーマが使用されている限り正常に機能します。ただし、別のテーマを使用する場合:

  • Windows XPの症状:SetBkColor動作しますSetTextColorが無視されます
  • Windows 7の症状:とは両方ともSetBkColor無視SetTextColorされます

OnEraseBkgndを試して、背景をカスタムカラー(pDC->FillSolidRect)で塗りつぶしましたが、これでも効果がありませんでした。

所有者描画の使用を避けたいOnPaintので、チェックマークとラジオ​​マークはWindowsでアクティブなテーマに従い続けます。前に書いたように、このコードはW2000、Windows Xp、Vista、Windows7で使用されています...背景色とテキストの色を変更したいだけです。

4

4 に答える 4

1

CButtonは、ボタンを描画するためにWindowsのデフォルトのウィンドウプロシージャを呼び出す以外のことは何もしません。OnPaintコードをオーバーライドして独自のことを行うことはできますが、それを避けたい理由は理解できます。さまざまな状況で適切な外観を得るのは大変な作業です。

MFCは、オーバーライド可能なメソッドを持つ別のクラスCMFCButtonを提供OnFillBackgroundします。それが機能するかどうかを確認してください。

于 2011-11-14T16:15:46.123 に答える
1

私は、テーマが Windows でアクティブなときに ownerdraw を使用する CButton を作成しました (Windows クラシックが使用されている場合はそうではありません)。これは動的に行われます。このサンプル コードは完全ではありませんが、結果を得るために必要なすべてを示しています。

難しい部分は、強調表示された状態と押された状態を表す必要があることです。 のパラメーターを参照してくださいDrawCheckBox。私のアプリケーションではそれらが完全に見落とされるわけではないので、それらを無視しています。

IMPLEMENT_DYNAMIC(mycheckbox, CButton)

mycheckbox::mycheckbox()
  : mv_bIsChecked( false )
{
  m_brush.CreateSolidBrush( RGB( 0,0,255) );
}

mycheckbox::~mycheckbox()
{
}

BEGIN_MESSAGE_MAP(mycheckbox, CButton)
  ON_WM_CTLCOLOR_REFLECT()
  ON_WM_PAINT()
  ON_CONTROL_REFLECT(BN_CLICKED, &mycheckbox::OnBnClicked)
END_MESSAGE_MAP()

HBRUSH mycheckbox::CtlColor(CDC* pDC, UINT nCtlColor)
{
  pDC->SetBkColor( RGB( 255, 0, 0 ) );   // text background color
  pDC->SetTextColor( RGB( 0, 255, 0 ) ); // text foreground color
  return m_brush;                        // control background
}

void mycheckbox::DrawItem(LPDRAWITEMSTRUCT)
{
}

void mycheckbox::OnPaint()
{
  if( ( GetStyle() & BS_OWNERDRAW ) == BS_OWNERDRAW )
  {
    CPaintDC dc( this );

    RECT rect;
    GetClientRect( & rect );
    rect.right = rect.left + 20;
    CMFCVisualManager::GetInstance()->DrawCheckBox(
                & dc
              , rect
              , false                               // highlighted
              , mv_bIsChecked ? 1 : 0 // state
              , true                                // enabled
              , false                               // pressed
              );

    // draw text next to the checkbox if you like
  }
  else
    __super::OnPaint();
}

  // when BS_OWNERDAW is active,
  // GetCheck() is reporting a wrong value
  // so we have to do a little bookkeeping ourselves
void mycheckbox::OnBnClicked()
{
  mv_bIsChecked = ! mv_bIsChecked;
}

BOOL mycheckbox::PreCreateWindow( CREATESTRUCT & cs )
{
  CString lv_szValue;
  CSettingsStore lv_Registry( FALSE, TRUE );
  lv_Registry.Open( _T("Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager") );
  lv_Registry.Read( _T("ThemeActive"), lv_szValue );
  lv_Registry.Close();
  if( lv_szValue == _T("1") )
    cs.style |= BS_OWNERDRAW;

  return CButton::PreCreateWindow(cs);
}

Windows 7ランタイムテーマの切り替えも試しましたが、テーマから切り替えたときに望ましくない効果が生じWindows Classicます(チェックボックスは通常のボタンのように見えます)。だから私はこれを使用していませんが、共有するのは面白いかもしれません:

void mycheckbox::OnNMThemeChanged( NMHDR * pNMHDR, LRESULT * pResult )
{
  CString lv_szValue;
  CSettingsStore lv_Registry( FALSE, TRUE );
  lv_Registry.Open( _T("Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager") );
  lv_Registry.Read( _T("ThemeActive"), lv_szValue );
  lv_Registry.Close();

  ModifyStyle( BS_OWNERDRAW, 0 ); // turn off
  if( lv_szValue == _T("1") )
    ModifyStyle( 0, BS_OWNERDRAW ); // turn on

  // This feature requires Windows XP or greater.
  // The symbol _WIN32_WINNT must be >= 0x0501.
  // TODO: Add your control notification handler code here
  *pResult = 0;
}
于 2011-11-16T16:24:46.257 に答える
0

このマイクロソフトの記事によると:

Windows 3.0 以降でボタン コントロールの背景色を変更するには、オーナー ドロー ボタンを作成する必要があります。

特定のコントロールの表示を変えたい場合は、サブクラス化したほうがよいと思います。

この記事は、サブクラス化を理解するのに役立ちます。

ここで、ボタンの背景テキストの色CButtonを変更するには、 sayから新しいクラスを派生させ、MyButtonその関数をオーバーライドしDrawItemて、特定のコントロールを描画するためのコードを追加する必要があります。

注: これらのコントロールには、所有者描画プロパティ ( ) を設定する必要がありBS_OWNERDRAWます。

于 2011-11-15T12:08:05.497 に答える
0

ここでの最善の解決策は、テキスト含む CStatic と、チェック ボックスのみを含む CButton を用意することです。Vista の時点では、控えめに言っても、チェックボックスの背景を変更することは問題です。

于 2011-11-16T13:03:41.123 に答える