开发了一个彩色界面的程序为了方便在窗口上的控件都没有采用自己继承的类来实现而是在OnCtlColor里对标准控件进行了透明华处理,具体代码如下:
HBRUSH CMyDECExamDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); if(pWnd->GetDlgCtrlID() >= IDC_RADIO1 && pWnd->GetDlgCtrlID() <= IDC_CHECK8 || pWnd->GetDlgCtrlID() == IDC_EDIT_QUESTION)
{
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0, 0, 0));
hbr = (HBRUSH)GetStockObject(NULL_BRUSH);
}


// TODO: Return a different brush if the default is not desired
return hbr;
}效果非常理想,控件底色就是我在窗口上所涂的颜色。但是程序需要不断变换控件上的文字,这时如果使用SetWindowText函数将文字写在控件上,控件上的文字就会出现重叠,我考虑可能是重画没有通知控件造成的,所以将这个控件ShowWindow(FALSE)在ShowWindow(TRUE)就OK了,可是这样做总会在不可见和可见瞬间存在闪烁,效果不理想。所以就考虑使用控件的UpdateWindow,RedrawWindow,但是些函数使用以后没有效果。十分苦恼,望知道解决方法老师给个答案!

解决方案 »

  1.   

    从标准控件继承一层 ONREASEBKGND 消息 return TRUE;
      

  2.   

    不要刷新整个屏幕。只对你所变化的控件刷新就好了。
    整个屏幕刷新的时间太长。取得所对应控件的句柄,然后再invalidate, 和 updatewindow 就好了
      

  3.   

    重写控件的OnPaint()函数
    CPaintDC dc(this);
    dc.SetMapMode(MM_TEXT);
    CRect rect;
    GetClientRect(&rect);
    dc.FillSolidRect(rect,RGB(255,255,255));
    取消重叠的话必须每次画底  但不知道这么做对透明的效果有没有影响  作为参考
    invalidate应该没有什么用吧  上次的东西还是在屏幕上呀  必须用东西把上次的东西盖上
      

  4.   

    采用你这种机制是不可避免这种情况的,因为文字改变需要擦除原来的内容,即需要某个操作,本来的操作是WM_ERASEBKGND,但是因为pDC->SetBkMode(TRANSPARENT);而取消!所以现在的代码没有一个擦除的机制存在,也就不能正确运行!
    如果需要背景透明而文字又要变动的话,目前的方法可能不行!
    建议处理WM_ERASEBKGND,通过某种办法实现你的想法!
      

  5.   

    SetWindowText之后怎样重画控件?如果用Invalidate应该会先重画父窗口再重画控件,这样先前画的就会被父窗口背景擦除,不会重叠。如果用RedrawWindow重画控件就会重叠。我以前碰过类似情况
      

  6.   

    同意楼上的,使用RedrawWindow的确会出现窗口重叠的问题,应该先画父窗口背景再重画控件。