CButton 自绘

fangchao918628 2010-12-09 04:42:20
在DrawItem()画一个矩形......
if(m_bInButton)
{
dc->RoundRect(rect.left,rect.top,rect.right,rect.bottom,5,5);

}
else
{
dc->RoundRect(rect.left+20,rect.top+20,rect.right-20,rect.bottom-20,5,5);
}

为什么这两个圆角矩形会同时存在....
m_bInButton是判断鼠标是否在按钮范围内
LRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{

m_bInButton = FALSE;
m_bButtonDown = FALSE;

Invalidate();
return 0;
}

LRESULT CMyButton::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
m_bInButton = TRUE;
Invalidate();

return 0;
}

为什么没有将其中一个矩形刷新掉.....
...全文
472 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
向立天 2010-12-15
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 fangchao918628 的回复:]
填充背景色过后,的确可以擦掉,但是如果要透明的按钮,应该怎么做了...........
[/Quote]要想做透明可就麻烦了
有句柄的东西是不存在透明这一说的
你要通过一种机制获取按钮下的图像作为你的背景画上
leeihcy 2010-12-15
  • 打赏
  • 举报
回复
透明控件:

Draws the part of a parent control that is covered by a partially-transparent or alpha-blended child control


Header uxtheme.h
Import library UxTheme.lib

HRESULT DrawThemeParentBackground( HWND hwnd,
HDC hdc,
const RECT *prc
);
走好每一步 2010-12-15
  • 打赏
  • 举报
回复
透明按钮…那只好从你的背景DC中偷一块粘上去了。假如你背景够复杂的。或者是控件与窗口不要共用DC。
fangchao918628 2010-12-14
  • 打赏
  • 举报
回复
填充背景色过后,的确可以擦掉,但是如果要透明的按钮,应该怎么做了...........
psbeond 2010-12-12
  • 打赏
  • 举报
回复
每次画按钮的时候,要把整个按钮都要画一遍,而不是画一部分。


if(m_bInButton)
{
dc->RoundRect(rect.left,rect.top,rect.right,rect.bottom,5,5);

}
else
{
dc->RoundRect(rect.left+20,rect.top+20,rect.right-20,rect.bottom-20,5,5);
}
以执行上面一段代码前,还要画按钮的背景呢。
向立天 2010-12-11
  • 打赏
  • 举报
回复
你看你的代码
代码中绘制按钮时你没有对背景进行填充
所以造成了之前绘制的影响残留
在DrawNormalButton之前先用一种颜色将客户区填充试一下
向立天 2010-12-10
  • 打赏
  • 举报
回复
你下断点看看if分支都执行到了?
不会吧
是不是第二次画时上一次的没有清除
fangchao918628 2010-12-10
  • 打赏
  • 举报
回复

不保密,

// MyButton.cpp : 实现文件
//

#include "stdafx.h"
#include "MFCProSafe.h"
#include "MyButton.h"


// CMyButton

IMPLEMENT_DYNAMIC(CMyButton, CButton)

CMyButton::CMyButton()
{
m_iBitmap = 0;
m_bInButton = FALSE;
m_bButtonDown = FALSE;
}

CMyButton::~CMyButton()
{
}


BEGIN_MESSAGE_MAP(CMyButton, CButton)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_ERASEBKGND()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
END_MESSAGE_MAP()



// CMyButton 消息处理程序



void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{

// TODO: 添加您的代码以绘制指定项

CRect rect;
GetClientRect(rect);

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

int nSavedDC = dc->SaveDC();

UINT state = lpDrawItemStruct->itemState;

m_Rgn = CreateRoundRectRgn(rect.left,rect.top,rect.right,rect.bottom,5,5);

SetWindowRgn(m_Rgn,TRUE);

DrawNormalButton(dc,state);

dc->RestoreDC(nSavedDC);

}

void CMyButton::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值

CButton::OnLButtonDown(nFlags, point);
}

void CMyButton::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值

CButton::OnLButtonUp(nFlags, point);
}

LRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{

m_bInButton = FALSE;
m_bButtonDown = FALSE;

CRect rect;

GetClientRect(&rect);

ClientToScreen(&rect);


GetParent()->ScreenToClient(&rect);



GetParent()->InvalidateRect(rect,TRUE);



return 0;
}

LRESULT CMyButton::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
m_bInButton = TRUE;
InvalidateRect(NULL);

return 0;
}

void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值

if (!m_bButtonDown)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = 1;
m_bButtonDown = _TrackMouseEvent(&tme);

}

CButton::OnMouseMove(nFlags, point);

}

BOOL CMyButton::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值

return TRUE;

// return CButton::OnEraseBkgnd(pDC);
}
void CMyButton::DrawCirButton(CDC* dc,UINT state)
{

}
void CMyButton::DrawNormalButton(CDC* dc,UINT state)
{

CRect rect;

GetClientRect(&rect);

CPen NewPen;
CPen NewNextPen;
CPen* OldPen;

CBrush NewBrush;
CBrush* OldBrush;


NewBrush.CreateStockObject(NULL_BRUSH);

OldBrush = dc->SelectObject(&NewBrush);

/* if((state&ODS_SELECTED)||(state&ODS_FOCUS))
{

dc->RoundRect(rect.left,rect.top,rect.right,rect.bottom,5,5);
}
*/
if(m_bInButton)
{

dc->RoundRect(rect.left,rect.top,rect.right,rect.bottom,5,5);


}


HICON hLogo = AfxGetApp()->LoadIcon(m_iIcon);


DrawIconEx(dc->m_hDC,rect.left+((rect.Width()-32)/2),rect.top+10,hLogo,32,32,0,0,DI_NORMAL);

dc->SetBkMode(TRANSPARENT);

CString str;

NewPen.CreateStockObject(BLACK_PEN);

OldPen = dc->SelectObject(&NewPen);

GetWindowText(str);

// dc->SetTextColor(m_textcolor);

dc->DrawText(str,CRect(rect.left+8,rect.top+50,rect.right-10,rect.bottom-10),DT_CENTER|DT_VCENTER|DT_SINGLELINE);

dc->SelectObject(OldBrush);

dc->SelectObject(OldPen);



}
void CMyButton::SetButtonBitmap(UINT uiBitmap)
{
m_iBitmap = uiBitmap;
}

void CMyButton::SetButtonIcon(UINT iIcon)
{
m_iIcon = iIcon;
Invalidate();

}

void CMyButton::DrawButtonBorder(CDC* dc)
{
CRect rect;
GetClientRect(&rect);



TRIVERTEX vert[2] ;
GRADIENT_RECT gRect;
vert [0] .x = rect.left;
vert [0] .y = rect.top;
vert [0] .Red = 0xff00;
vert [0] .Green = 0xff00;
vert [0] .Blue = 0x3700;
vert [0] .Alpha = 0x0000;

vert [1] .x = rect.left+rect.Width();
vert [1] .y = rect.top+10;
vert [1] .Red = 0xff00;
vert [1] .Green = 0xff00;
vert [1] .Blue = 0xff00;
vert [1] .Alpha = 0x0000;

gRect.UpperLeft = 0;
gRect.LowerRight = 1;


dc->GradientFill(vert,2,&gRect,1,GRADIENT_FILL_RECT_V);
}

...
向立天 2010-12-10
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 fangchao918628 的回复:]
恩,自绘.....
[/Quote]
我是说代码......
你不是保密吧
fangchao918628 2010-12-10
  • 打赏
  • 举报
回复
恩,自绘.....
向立天 2010-12-10
  • 打赏
  • 举报
回复
按钮你怎么画的
fangchao918628 2010-12-10
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 sparrow429 的回复:]
肯定是没把上次的刷新掉
[/Quote]
我也知道没刷新,但是想知道为什么没刷新......
sparrow429 2010-12-10
  • 打赏
  • 举报
回复
肯定是没把上次的刷新掉
fangchao918628 2010-12-10
  • 打赏
  • 举报
回复
我也找了个别人写的这个按钮类,改了下,好像也有这个问题....
郁闷了很久,不知道原理,憋着难受
fangchao918628 2010-12-10
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 xianglitian 的回复:]
我觉得问题不是出在刷新上
而是出在绘制上
主窗口把之前绘制的东西擦除了
你自己的绘制过程是不是没有这个步骤
[/Quote]
开始的时候我直接是用自绘的按钮InvalidateRect(NULL);没有作用,然后我发现拖动窗口的时候当被挡住的时候给刷掉了,所以我调用主窗口GetParent()->InvalidateRect(rect,TRUE);
向立天 2010-12-10
  • 打赏
  • 举报
回复
我觉得问题不是出在刷新上
而是出在绘制上
主窗口把之前绘制的东西擦除了
你自己的绘制过程是不是没有这个步骤
fangchao918628 2010-12-10
  • 打赏
  • 举报
回复
不知道原理知道的人说下,万分感谢...
fangchao918628 2010-12-10
  • 打赏
  • 举报
回复
不知道为什么要在主窗口的区域才可以刷新掉..........
改成这样

LRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{

m_bInButton = FALSE;
m_bButtonDown = FALSE;

CRect rect;

GetClientRect(&rect);

ClientToScreen(&rect);


GetParent()->ScreenToClient(&rect);



GetParent()->InvalidateRect(rect,TRUE);



return 0;
}

yuanmoren 2010-12-10
  • 打赏
  • 举报
回复
每次画的时候,先把图形清空
lovett777 2010-12-10
  • 打赏
  • 举报
回复
看看你的PreSubclassWindow函数里面是否有设置SetWindowRgn(rgn,TRUE);这样指定的区域就会重绘了。
加载更多回复(8)

15,978

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧