重写了OnPaint函数,虽然调用但不改变背景色,为啥?
代码如下:
LRESULT CButtonRainny::OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
HWND hWnd = m_hWnd;
HDC hDC= GetDC();
HBRUSH hBrush = CreateSolidBrush(RGB(0,128,255));
SelectObject(hDC,hBrush);
Rectangle(hDC,0,0,100,100);
return 0;
}
hDC和m_hWnd都非空。
21 个解决方案
#1
重写OnEraseBkGnd
#2
细节请参考window消息:WM_ERASEBKGND
#3
处理 WM_CTLCOLOR
//成员变量 HBRUSH m_brushRed;
CXXXDlg::OnInitDialog()
{
m_brushRed = ::CreateSolidBrush(RGB(255,0,0));
}
CXXXDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the DC here
if ( GetDlgItem(IDC_BUTTION1) == pWnd )
{
return m_brushRed;
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
CXXXDlg:OnDestroy
{
if (NULL != m_brushRed)
DeleteObject(m_brushRed);
}
#4
直接在OnCtlColor函数中处理,或者可以重新绘制按钮.
#6
拜托各位,我的Button是基于Button的ATL控件,没有WM_CTLCOLOR事件。
WM_ERASEBKGND我试过了,依然没有用。
还有人知道么?
WM_ERASEBKGND我试过了,依然没有用。
还有人知道么?
#7
学习了
#8
其实我一向觉得button的话加图片不就好了
比单纯的button控件美观很多
也不用考虑背景色问题
比单纯的button控件美观很多
也不用考虑背景色问题
#9
把你的代码放在OnDraw函数里边肯定是可以的。
重载:
HRESULT CButtonRainny::OnDraw(ATL_DRAWINFO& di)
HDC hdc = di.hdcDraw;
RECT& rc = *(RECT*)di.prcBounds;
重载:
HRESULT CButtonRainny::OnDraw(ATL_DRAWINFO& di)
HDC hdc = di.hdcDraw;
RECT& rc = *(RECT*)di.prcBounds;
#10
HWND hWnd = m_hWnd;
HDC hDC= GetDC(); //在这里GetDC返回的是CDC*,不是HDC句柄,返回句柄应该用::GetDC(m_hWnd)
HBRUSH hBrush = CreateSolidBrush(RGB(0,128,255));
SelectObject(hDC,hBrush); //调用全局函数还是加双引号,好区分 ::SelectObject(hDC,hBrush);
Rectangle(hDC,0,0,100,100); //::Rectangle(hDC,0,0,100,100);
OnDraw函数是需要在OnPaint中调用才执行的
你要看到效果就应该刷新控件,这样OnPaint才会被执行
void CXXButton::SetBkColor(COLORREF clrBkgndColor)
{
....
Invalidate();
}
HDC hDC= GetDC(); //在这里GetDC返回的是CDC*,不是HDC句柄,返回句柄应该用::GetDC(m_hWnd)
HBRUSH hBrush = CreateSolidBrush(RGB(0,128,255));
SelectObject(hDC,hBrush); //调用全局函数还是加双引号,好区分 ::SelectObject(hDC,hBrush);
Rectangle(hDC,0,0,100,100); //::Rectangle(hDC,0,0,100,100);
OnDraw函数是需要在OnPaint中调用才执行的
你要看到效果就应该刷新控件,这样OnPaint才会被执行
void CXXButton::SetBkColor(COLORREF clrBkgndColor)
{
....
Invalidate();
}
#11
我一开始就写了
#12
改变背景色有这么麻烦??我以为只要.setBackgroundcolor之类的就可以了。
#13
正解
#14
看看我的这段代码吧,祝好运。
// 自定义的按钮函数
void CCGStoreBmpDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CString strText;
// 窗体坐标
RECT WRect;
this->GetWindowRect(&WRect);
// 按钮坐标
RECT BRect;
switch( lpDrawItemStruct->CtlID )
{
case IDC_Start: m_bStart.GetWindowTextA(strText); m_bStart.GetWindowRect(&BRect); break;
case IDC_Stop: m_bStop.GetWindowTextA(strText); m_bStop.GetWindowRect(&BRect); break;
default: m_bLoad_For_motion.GetWindowTextA(strText); m_bLoad_For_motion.GetWindowRect(&BRect); break;
}
// 定义变量
CDC * pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rect = lpDrawItemStruct->rcItem;
UINT state = lpDrawItemStruct->itemState;
// 画控制效果
if (state & ODS_SELECTED)
pDC->DrawFrameControl( rect, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_PUSHED );
else
pDC->DrawFrameControl( rect, DFC_BUTTON, DFCS_BUTTONPUSH );
// 将绘图展开为按钮大小
rect.DeflateRect( CSize( GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE) ) );
// 填充颜色到按钮
int butter_color = BRect.top - WRect.top ;
pDC->FillSolidRect(rect, RGB( 0x08+butter_color/20,
0x4C+butter_color/8,
0xAF+butter_color/20 ));
// 绘制文本
if (!strText.IsEmpty())
{
CSize Extent = pDC->GetTextExtent(strText);
CPoint pt( rect.CenterPoint().x - Extent.cx/2,
rect.CenterPoint().y - Extent.cy/2 );
if (state & ODS_SELECTED)
pt.Offset(2,2);
int nMode = pDC->SetTextColor( RGB(0xFF,0xFF,0xFF) );
if (state & ODS_DISABLED)
pDC->DrawState( pt, Extent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL );
else
pDC->TextOut( pt.x, pt.y, strText );
pDC->SetBkMode( nMode );
}
}
#15
可以在父窗口中重载WM_CTLCOLORBTN消息
你在WTL中对于BUTTON的绘制大致可以采用以下几种方法。
1、就是所谓的超类化了,重载WM_ERASEBKGND和WM_PAINT,不过这种方法比较极端,很少采用
class CMyButton : public CWindowImpl<CMyButton, CButton>
{
public:
BEGIN_MSG_MAP(CMainDlg)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_ERASEBKGND,OnEraseBkGround)
END_MSG_MAP()
public:
LRESULT OnEraseBkGround(UINT,WPARAM,LPARAM,BOOL&)
{
return TRUE;
}
LRESULT OnPaint(UING,WPARAM,LPARAM,BOOL&)
{
WTL::CPaintDC dc(m_hWnd);
RECT rt ={0}
GetClientRect(&rt);
dc.FillSolidRect(&rt,RGB(255,0,0)); // 绘制红底背景
//..... 绘制文本,图片等,还需要考虑鼠标的各种状态
}
};
然后将该类添加到你的对话框中,用SubClassWindow()方法钩入。
2、 就是在对话框中的实现WM_CTLCOLORBTN, 或者将消息反射到你的按钮类中处理。
class CXXXDlg : public CDialogImpl<CXXXDlg>
{
public:
WTL::CBrush m_brButton;
public:
BEGIN_MSG_MAP(CMainDlg)
MESSAGE_HANDLER(WM_CTLCOLORBTN, OnCtlColorBtn)
END_MSG_MAP()
public:
LRESULT OnCtlColorBtn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (m_brButton.IsNull())
m_brButton.CreateSolidBrush(RGB(255,0,0)); // 创建画刷,画刷不能是函数局部变量,不然会造成GDI资源泄漏
return (LRESULT)m_brButton.m_hBrush;
}
};
你也可以将WM_CTLCOLORBTN消息反射到你自己定义的类中, 那你需要在MESSAGE_MAP加入REFLECT_NOTIFICATIONS()反射
那么你类中的消息号就不能用WM_CTLCOLORBTN要改成OCM_CTLCOLORBTN
3、可以在父窗口中采用OWNERDRAW, 重载WM_DRAWITEM消息绘制
4、可以在父窗口中采用CustomDraw绘制, 重载NM_CUSTOMDRAW消息,自己按阶段绘制,MSDN中有例子。
#16
谁有这个问题的ATL代码。我看看
#17
还有就是基于Button的ATL控件怎么设置它的风格,使其成为PushButton?
#18
我确定OnPaint被执行了,但没有改变颜色
#19
OnDraw里那个有个 rcRect,用它做范围去画
#20
弱弱的问一下:
按钮的客户去已经占去整个Window Rect了, 你整背景色有啥用呢?
按钮的客户去已经占去整个Window Rect了, 你整背景色有啥用呢?
#21
OnDraw不被执行,我还要说多少次!
我是用ATL做的Button控件当作可点击的颜色方块,使其还有PushButton的效果。可没法改变颜色
我是用ATL做的Button控件当作可点击的颜色方块,使其还有PushButton的效果。可没法改变颜色
#1
重写OnEraseBkGnd
#2
细节请参考window消息:WM_ERASEBKGND
#3
处理 WM_CTLCOLOR
//成员变量 HBRUSH m_brushRed;
CXXXDlg::OnInitDialog()
{
m_brushRed = ::CreateSolidBrush(RGB(255,0,0));
}
CXXXDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the DC here
if ( GetDlgItem(IDC_BUTTION1) == pWnd )
{
return m_brushRed;
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
CXXXDlg:OnDestroy
{
if (NULL != m_brushRed)
DeleteObject(m_brushRed);
}
#4
直接在OnCtlColor函数中处理,或者可以重新绘制按钮.
#5
#6
拜托各位,我的Button是基于Button的ATL控件,没有WM_CTLCOLOR事件。
WM_ERASEBKGND我试过了,依然没有用。
还有人知道么?
WM_ERASEBKGND我试过了,依然没有用。
还有人知道么?
#7
学习了
#8
其实我一向觉得button的话加图片不就好了
比单纯的button控件美观很多
也不用考虑背景色问题
比单纯的button控件美观很多
也不用考虑背景色问题
#9
把你的代码放在OnDraw函数里边肯定是可以的。
重载:
HRESULT CButtonRainny::OnDraw(ATL_DRAWINFO& di)
HDC hdc = di.hdcDraw;
RECT& rc = *(RECT*)di.prcBounds;
重载:
HRESULT CButtonRainny::OnDraw(ATL_DRAWINFO& di)
HDC hdc = di.hdcDraw;
RECT& rc = *(RECT*)di.prcBounds;
#10
HWND hWnd = m_hWnd;
HDC hDC= GetDC(); //在这里GetDC返回的是CDC*,不是HDC句柄,返回句柄应该用::GetDC(m_hWnd)
HBRUSH hBrush = CreateSolidBrush(RGB(0,128,255));
SelectObject(hDC,hBrush); //调用全局函数还是加双引号,好区分 ::SelectObject(hDC,hBrush);
Rectangle(hDC,0,0,100,100); //::Rectangle(hDC,0,0,100,100);
OnDraw函数是需要在OnPaint中调用才执行的
你要看到效果就应该刷新控件,这样OnPaint才会被执行
void CXXButton::SetBkColor(COLORREF clrBkgndColor)
{
....
Invalidate();
}
HDC hDC= GetDC(); //在这里GetDC返回的是CDC*,不是HDC句柄,返回句柄应该用::GetDC(m_hWnd)
HBRUSH hBrush = CreateSolidBrush(RGB(0,128,255));
SelectObject(hDC,hBrush); //调用全局函数还是加双引号,好区分 ::SelectObject(hDC,hBrush);
Rectangle(hDC,0,0,100,100); //::Rectangle(hDC,0,0,100,100);
OnDraw函数是需要在OnPaint中调用才执行的
你要看到效果就应该刷新控件,这样OnPaint才会被执行
void CXXButton::SetBkColor(COLORREF clrBkgndColor)
{
....
Invalidate();
}
#11
我一开始就写了
#12
改变背景色有这么麻烦??我以为只要.setBackgroundcolor之类的就可以了。
#13
正解
#14
看看我的这段代码吧,祝好运。
// 自定义的按钮函数
void CCGStoreBmpDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CString strText;
// 窗体坐标
RECT WRect;
this->GetWindowRect(&WRect);
// 按钮坐标
RECT BRect;
switch( lpDrawItemStruct->CtlID )
{
case IDC_Start: m_bStart.GetWindowTextA(strText); m_bStart.GetWindowRect(&BRect); break;
case IDC_Stop: m_bStop.GetWindowTextA(strText); m_bStop.GetWindowRect(&BRect); break;
default: m_bLoad_For_motion.GetWindowTextA(strText); m_bLoad_For_motion.GetWindowRect(&BRect); break;
}
// 定义变量
CDC * pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rect = lpDrawItemStruct->rcItem;
UINT state = lpDrawItemStruct->itemState;
// 画控制效果
if (state & ODS_SELECTED)
pDC->DrawFrameControl( rect, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_PUSHED );
else
pDC->DrawFrameControl( rect, DFC_BUTTON, DFCS_BUTTONPUSH );
// 将绘图展开为按钮大小
rect.DeflateRect( CSize( GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE) ) );
// 填充颜色到按钮
int butter_color = BRect.top - WRect.top ;
pDC->FillSolidRect(rect, RGB( 0x08+butter_color/20,
0x4C+butter_color/8,
0xAF+butter_color/20 ));
// 绘制文本
if (!strText.IsEmpty())
{
CSize Extent = pDC->GetTextExtent(strText);
CPoint pt( rect.CenterPoint().x - Extent.cx/2,
rect.CenterPoint().y - Extent.cy/2 );
if (state & ODS_SELECTED)
pt.Offset(2,2);
int nMode = pDC->SetTextColor( RGB(0xFF,0xFF,0xFF) );
if (state & ODS_DISABLED)
pDC->DrawState( pt, Extent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL );
else
pDC->TextOut( pt.x, pt.y, strText );
pDC->SetBkMode( nMode );
}
}
#15
可以在父窗口中重载WM_CTLCOLORBTN消息
你在WTL中对于BUTTON的绘制大致可以采用以下几种方法。
1、就是所谓的超类化了,重载WM_ERASEBKGND和WM_PAINT,不过这种方法比较极端,很少采用
class CMyButton : public CWindowImpl<CMyButton, CButton>
{
public:
BEGIN_MSG_MAP(CMainDlg)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_ERASEBKGND,OnEraseBkGround)
END_MSG_MAP()
public:
LRESULT OnEraseBkGround(UINT,WPARAM,LPARAM,BOOL&)
{
return TRUE;
}
LRESULT OnPaint(UING,WPARAM,LPARAM,BOOL&)
{
WTL::CPaintDC dc(m_hWnd);
RECT rt ={0}
GetClientRect(&rt);
dc.FillSolidRect(&rt,RGB(255,0,0)); // 绘制红底背景
//..... 绘制文本,图片等,还需要考虑鼠标的各种状态
}
};
然后将该类添加到你的对话框中,用SubClassWindow()方法钩入。
2、 就是在对话框中的实现WM_CTLCOLORBTN, 或者将消息反射到你的按钮类中处理。
class CXXXDlg : public CDialogImpl<CXXXDlg>
{
public:
WTL::CBrush m_brButton;
public:
BEGIN_MSG_MAP(CMainDlg)
MESSAGE_HANDLER(WM_CTLCOLORBTN, OnCtlColorBtn)
END_MSG_MAP()
public:
LRESULT OnCtlColorBtn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (m_brButton.IsNull())
m_brButton.CreateSolidBrush(RGB(255,0,0)); // 创建画刷,画刷不能是函数局部变量,不然会造成GDI资源泄漏
return (LRESULT)m_brButton.m_hBrush;
}
};
你也可以将WM_CTLCOLORBTN消息反射到你自己定义的类中, 那你需要在MESSAGE_MAP加入REFLECT_NOTIFICATIONS()反射
那么你类中的消息号就不能用WM_CTLCOLORBTN要改成OCM_CTLCOLORBTN
3、可以在父窗口中采用OWNERDRAW, 重载WM_DRAWITEM消息绘制
4、可以在父窗口中采用CustomDraw绘制, 重载NM_CUSTOMDRAW消息,自己按阶段绘制,MSDN中有例子。
#16
谁有这个问题的ATL代码。我看看
#17
还有就是基于Button的ATL控件怎么设置它的风格,使其成为PushButton?
#18
我确定OnPaint被执行了,但没有改变颜色
#19
OnDraw里那个有个 rcRect,用它做范围去画
#20
弱弱的问一下:
按钮的客户去已经占去整个Window Rect了, 你整背景色有啥用呢?
按钮的客户去已经占去整个Window Rect了, 你整背景色有啥用呢?
#21
OnDraw不被执行,我还要说多少次!
我是用ATL做的Button控件当作可点击的颜色方块,使其还有PushButton的效果。可没法改变颜色
我是用ATL做的Button控件当作可点击的颜色方块,使其还有PushButton的效果。可没法改变颜色