我自绘了一个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); 
}

解决方案 »

  1.   

    看你放在哪儿的,如果是在OnPaint()中,且使用了InvalideRect那就会重绘
      

  2.   

    按钮和工具栏一点关系都没有
    是不是我该在BTN类里再从载一个OnPaint()函数?
      

  3.   


    RECT r;  
    m_btn3_test.GetWindowRect(&r);  
    ScreenToClient(&r);  
    InvalidateRect(&r);
    改成
    m_btn3_test.Invalidate();
    看看是否还有问题。
      

  4.   

    改成了m_btn3_test.Invalidate(); 问题还是有
    不过这个函数确实方便不少:)
    问题基本可以肯定不是工具栏代码的问题了,可是按钮的重绘怎么可能会影响到工具栏的重绘呢?
    按钮和工具栏是两个完全互不相干的类,而且主程序里,也没有互相之间的联系
      

  5.   

    从上面代码中看不出问题,感觉与你调用的那几个函数有关。你可以试着把OnDrawItem中的代码注释掉一部分,逐步缩小范围看看是那行代码引起的。
      

  6.   

    谢谢,问题找到了,我点按钮后要在一个EDIT控件显示数字,而EDIT控件不知怎么在字超过控件下边界的时间,就会出现字体重叠的现象,(这是另外的问题,如果需要解决我会重新写明原因提问)所以,我在每次在EDIT控件里写字符的时间,我都刷新一下EDIT控件窗口用的代码是
    RECT r;   
    m_edit1.GetWindowRect(&r);   
    ScreenToClient(&r);   
    InvalidateRect(&r); 
    改成m_edit1.Invalidate();后,问题就稀里糊涂的解决了..............如果没人能解释下为什么 那么我想给5楼 cnzdgs 多点分,因为他的代码给我了提示,(也学到了东西),其余的朋友都平分份
    不过我是新手,一次没结过贴,如果结的不对,相信不会有下次,不过心意先在了~~嘿嘿~~
    在CSDN提问的第一个问题,谢谢几位朋友的帮忙!~
      

  7.   

    刷新控件的正确做法就是调用Invalidate函数,Invalidate函数会向控件发送WM_PAINT消息。而你的代码是调用窗口的InvalidateRect函数,这样会向窗口发送WM_PAINT消息,估计是你的窗口在响应WM_PAINT消息时多做了一些事。
      

  8.   

    结帖,没发现全是一个人回的 贴,eee,我真的很笨~~~
    谢谢cnzdgs~