lafe @ ウィキ
ComboBoxProxy
最終更新:
lafe
-
view
フラットコンボボックスを余所でも使うかもしれないので
// CComboBoxProxy.h
///////////////////////////////////////////////////////////////////////////////////////////
// CComboBoxProxy
class CComboBoxProxy
: public CWindowImpl<CComboBoxProxy, CComboBox>
, public CTrackMouseLeave<CComboBoxProxy>
{
private:
enum { s_kcxyBorder = 2 };
enum _ComboState { _comboNormal, _comboHot, _comboPressed };
// Data members
_ComboState m_state;
int m_nDrawStyle;
BOOL m_bExistManifest;
public:
// コンストラクタ
CComboBoxProxy();
bool FlatComboBox_Install(HWND hWndCombo);
void FlatComboBox_UnInstall();
void SetDrawStyle(int nStyle);
public:
// メッセージマップ
BEGIN_MSG_MAP(CComboBoxProxy)
MSG_WM_PAINT( OnPaint )
CHAIN_MSG_MAP(CTrackMouseLeave<CComboBoxProxy>)
END_MSG_MAP()
private:
void OnPaint(CDCHandle dc);
private:
void _DoComboPaint(CDCHandle dc);
void _DrawFlatThumb(CDCHandle &dc);
void _DrawFlatCombo(CDCHandle &dc, _ComboState state);
CRect _GetOriginalThumbRect();
CRect _GetFlatThumbInvalidateRect();
CRect _GetFlatComboInvalidateRect();
void _SetUseXPTheme(HWND hWnd, BOOL bUse);
};
// ComboBoxProxy.cpp
#include "ComboBoxProxy.h"
////////////////////////////////////////////////////////////////////////////////////////
// CComboBoxProxy
// コンストラクタ
CComboBoxProxy::CComboBoxProxy()
: m_state(_comboNormal)
, m_nDrawStyle(SKN_COMBO_STYLE_DEFAULT)
, m_bExistManifest(TRUE)
{
}
bool CComboBoxProxy::FlatComboBox_Install(HWND hWndCombo)
{
ATLVERIFY( SubclassWindow(hWndCombo) );
return true;
}
void CComboBoxProxy::FlatComboBox_UnInstall()
{
if ( IsWindow() ) {
UnsubclassWindow();
}
}
void CComboBoxProxy::SetDrawStyle(int nStyle)
{
m_nDrawStyle = nStyle;
if (nStyle == SKN_COMBO_STYLE_THEME && m_bExistManifest) {
_SetUseXPTheme(m_hWnd, TRUE);
} else {
_SetUseXPTheme(m_hWnd, FALSE);
}
}
/////////////////////////////////////////////////////////////////////////////////////
// メッセージマップ
void CComboBoxProxy::OnPaint(CDCHandle dc)
{
if ( m_nDrawStyle == SKN_COMBO_STYLE_DEFAULT
|| (m_nDrawStyle == SKN_COMBO_STYLE_THEME && !m_bExistManifest) ) {
// スタイルがデフォルトかテーマなのにmanifestファイルが存在しないとき
CRect rc;
GetUpdateRect(&rc, FALSE);
ValidateRect(NULL); // validate the whole
// invalidate only the internal rect
CRect rcCombo = _GetFlatComboInvalidateRect();
CRect rcThumb = _GetFlatThumbInvalidateRect();
CRect rcUpdate = rc & rcCombo;
InvalidateRect(&rcUpdate, FALSE);
rcUpdate = rc & rcThumb;
InvalidateRect(&rcUpdate, FALSE);
// Update
LRESULT lRet = DefWindowProc();
CClientDC dc(m_hWnd);
_DoComboPaint(dc.m_hDC);
} else {
SetMsgHandled(FALSE);
}
}
//
//////////////////////////////////////////////////////////////////////////////////////
// private:
void CComboBoxProxy::_DoComboPaint(CDCHandle dc)
{
_DrawFlatCombo(dc, m_state);
_DrawFlatThumb(dc);
}
void CComboBoxProxy::_DrawFlatThumb(CDCHandle &dc)
{
CRect rc = _GetOriginalThumbRect();
dc.DrawEdge(rc, BDR_RAISEDINNER, BF_RECT);
rc.DeflateRect(1, 1);
COLORREF clrBtnFace = ::GetSysColor(COLOR_BTNFACE);
dc.Draw3dRect(rc, clrBtnFace, clrBtnFace);
}
void CComboBoxProxy::_DrawFlatCombo(CDCHandle &dc, _ComboState state)
{
COLORREF clrBtnFace = ::GetSysColor(COLOR_BTNFACE);
CRect rc;
GetClientRect(&rc);
dc.Draw3dRect(rc, clrBtnFace, clrBtnFace);
rc.DeflateRect(1, 1);
switch (state)
{
case _comboNormal:
dc.DrawEdge(rc, BDR_SUNKENOUTER, BF_RECT);
break;
case _comboHot:
dc.DrawEdge(rc, BDR_RAISEDINNER, BF_RECT);
break;
case _comboPressed:
break;
}
}
CRect CComboBoxProxy::_GetOriginalThumbRect()
{
CRect rc;
GetClientRect(&rc);
rc.right -= s_kcxyBorder;
rc.left = rc.right - ::GetSystemMetrics(SM_CXHTHUMB);
rc.top += s_kcxyBorder;
rc.bottom -= s_kcxyBorder;
return rc;
}
CRect CComboBoxProxy::_GetFlatThumbInvalidateRect()
{
CRect rc = _GetOriginalThumbRect();
rc.DeflateRect(2, 2);
return rc;
}
CRect CComboBoxProxy::_GetFlatComboInvalidateRect()
{
CRect rc;
GetClientRect(&rc);
rc.DeflateRect(2, 2);
rc.right -= ::GetSystemMetrics(SM_CXHTHUMB);
return rc;
}
void CComboBoxProxy::_SetUseXPTheme(HWND hWnd, BOOL bUse)
{
if (bUse) {
::SetWindowTheme( hWnd, L" ", L"COMBOBOX" );
} else {
::SetWindowTheme( hWnd, L" ", L" " );
}
}