我自绘了一个BUTTON类,为什么点击BUTTON时会出现工具条重绘的现象,工具条也是从网上下的,用默认的工具条也会偶尔出现工具条重绘的现象,问题不大但影响视觉效果,源程序太大无法全贴出来,我只想问问各位有没有什么经验,或判断问题可能出在哪里,情况如下
我自绘的BTN类,实现两种按钮,一种是正常下压按钮,(比默认的添了色彩,和下压的边框效果),另一种是压下后不再弹起来了的按钮(再点击就会弹起来),如果我用正常下压按钮,对话框上的工具条不会重绘,而按第二种按钮时,经常出现工具条刷新重绘的现象,(第二种按钮主要是在DLG类里加一个BOOL变量,点击按钮,如果BOOL变量为真,就为假,为假就为真,然后加一个InvalidateRect刷新按钮区域,BTN重绘类里有一个判断BOOL变量的代码来实现下压和弹起按钮图案的实现),BTN类里没有Invalidate函数,DLG类里将按钮的InvalidateRect(&r)取消后就不会出现上述情况,代码如下
if(m_btn3_test.m_pClick)
m_btn3_test.m_pClick=false;
else
m_btn3_test.m_pClick=true;
RECT r;
m_btn3_test.GetWindowRect(&r);
ScreenToClient(&r);
InvalidateRect(&r); //这里取消后,就没事了,但点击后,按钮不会出现总是下压的效果,而是直接弹了起来,
BTN类里重载了DrawItem()和PreTranslateMessage()函数,其余有一个是自己加的函数来实现按钮的绘图.
void CMyBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
// TODO: Add your code to draw the specified item
//从lpDrawItemStruct获取控件的相关信息
CRect rect = lpDrawItemStruct->rcItem;
CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
int nSaveDC=pDC->SaveDC();
UINT state = lpDrawItemStruct->itemState; TCHAR strText[MAX_PATH + 1];
::GetWindowText(m_hWnd, strText, MAX_PATH); //获取按钮的状态
if (state & ODS_DISABLED )
m_disEnable=true;
else
m_disEnable=false;
//根据按钮的状态填充按钮的底色 if (state & ODS_SELECTED )
{
m_bOver=true;
DoGradientFill(pDC, &rect);
}
else
{
m_bOver=false;
DoGradientFill(pDC,&rect);
} if (m_bOver)
DrawInsideBorder(pDC, &rect);
//显示按钮的文本
if (strText!=NULL)
{
CFont* hFont = GetFont();
CFont* hOldFont = pDC->SelectObject(hFont);
CSize szExtent = pDC->GetTextExtent(strText, lstrlen(strText));
CPoint pt( rect.CenterPoint().x - szExtent.cx / 2, rect.CenterPoint().y - szExtent.cy / 2);
if (state & ODS_SELECTED)
pt.Offset(1, 1); int nMode = pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,0,0));
if (state & ODS_DISABLED)
pDC->DrawState(pt, szExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
else
pDC->DrawState(pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL); pDC->SelectObject(hOldFont);
pDC->SetBkMode(nMode);
}
pDC->RestoreDC(nSaveDC);
}
我自绘的BTN类,实现两种按钮,一种是正常下压按钮,(比默认的添了色彩,和下压的边框效果),另一种是压下后不再弹起来了的按钮(再点击就会弹起来),如果我用正常下压按钮,对话框上的工具条不会重绘,而按第二种按钮时,经常出现工具条刷新重绘的现象,(第二种按钮主要是在DLG类里加一个BOOL变量,点击按钮,如果BOOL变量为真,就为假,为假就为真,然后加一个InvalidateRect刷新按钮区域,BTN重绘类里有一个判断BOOL变量的代码来实现下压和弹起按钮图案的实现),BTN类里没有Invalidate函数,DLG类里将按钮的InvalidateRect(&r)取消后就不会出现上述情况,代码如下
if(m_btn3_test.m_pClick)
m_btn3_test.m_pClick=false;
else
m_btn3_test.m_pClick=true;
RECT r;
m_btn3_test.GetWindowRect(&r);
ScreenToClient(&r);
InvalidateRect(&r); //这里取消后,就没事了,但点击后,按钮不会出现总是下压的效果,而是直接弹了起来,
BTN类里重载了DrawItem()和PreTranslateMessage()函数,其余有一个是自己加的函数来实现按钮的绘图.
void CMyBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
// TODO: Add your code to draw the specified item
//从lpDrawItemStruct获取控件的相关信息
CRect rect = lpDrawItemStruct->rcItem;
CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
int nSaveDC=pDC->SaveDC();
UINT state = lpDrawItemStruct->itemState; TCHAR strText[MAX_PATH + 1];
::GetWindowText(m_hWnd, strText, MAX_PATH); //获取按钮的状态
if (state & ODS_DISABLED )
m_disEnable=true;
else
m_disEnable=false;
//根据按钮的状态填充按钮的底色 if (state & ODS_SELECTED )
{
m_bOver=true;
DoGradientFill(pDC, &rect);
}
else
{
m_bOver=false;
DoGradientFill(pDC,&rect);
} if (m_bOver)
DrawInsideBorder(pDC, &rect);
//显示按钮的文本
if (strText!=NULL)
{
CFont* hFont = GetFont();
CFont* hOldFont = pDC->SelectObject(hFont);
CSize szExtent = pDC->GetTextExtent(strText, lstrlen(strText));
CPoint pt( rect.CenterPoint().x - szExtent.cx / 2, rect.CenterPoint().y - szExtent.cy / 2);
if (state & ODS_SELECTED)
pt.Offset(1, 1); int nMode = pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,0,0));
if (state & ODS_DISABLED)
pDC->DrawState(pt, szExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
else
pDC->DrawState(pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL); pDC->SelectObject(hOldFont);
pDC->SetBkMode(nMode);
}
pDC->RestoreDC(nSaveDC);
}
是不是我该在BTN类里再从载一个OnPaint()函数?
RECT r;
m_btn3_test.GetWindowRect(&r);
ScreenToClient(&r);
InvalidateRect(&r);
改成
m_btn3_test.Invalidate();
看看是否还有问题。
不过这个函数确实方便不少:)
问题基本可以肯定不是工具栏代码的问题了,可是按钮的重绘怎么可能会影响到工具栏的重绘呢?
按钮和工具栏是两个完全互不相干的类,而且主程序里,也没有互相之间的联系
RECT r;
m_edit1.GetWindowRect(&r);
ScreenToClient(&r);
InvalidateRect(&r);
改成m_edit1.Invalidate();后,问题就稀里糊涂的解决了..............如果没人能解释下为什么 那么我想给5楼 cnzdgs 多点分,因为他的代码给我了提示,(也学到了东西),其余的朋友都平分份
不过我是新手,一次没结过贴,如果结的不对,相信不会有下次,不过心意先在了~~嘿嘿~~
在CSDN提问的第一个问题,谢谢几位朋友的帮忙!~
谢谢cnzdgs~