请问大虾,
    我想在已有的项目上修改UI,使用非规则PNG图片当背景,目前已经可以显示图片,但盖住了之前的控件!
请问有什么办法解决吗?

解决方案 »

  1.   

    主对话框中设置属性ClipChildren,并且控件必须是主对话框的子窗口。
    这样在绘制主对话框背景的时候就不会把控件遮住了。
      

  2.   

    在VC6.0中用GDI+调用png图片实现半透明渐变的特效窗口
      

  3.   


    补充:
    我之前用的是BMP图片,直接贴在背景上的,不会盖住控件!但是图是不规则型的,四周让自动加了背景色,所以现在想改用PNG图片,按网友的帖子做可以显示出图片,可是会盖掉控件!
    大家可以模拟下!先建个对话框项目,背景是直接贴上去的BMP图,上面有很多控件!
    如何把这个BMP的图换成PNG的图片呢?(最好不重建新窗口,上面的控件超级多!)
      

  4.   

    用BMP图片也可以通明背景色啊,只要背景色是同一个颜色就可以,有个函数叫TRANSL什么来的,也可以自己处理图象.PNG的图片没用过,你是用什么方法加载显示的?
    GDI+还是什么方法?
      

  5.   

    是吗?BMP要怎么弄啊?不会阿
    现在是用GDI+加载的PNG
    指点下吧
      

  6.   

    最后只有出杀手锏了,就是获取所有的按钮RECT,然后在DrawImage这个PNG图片之前,对Graphics对象调用ExcludeClip将按钮的区域排除在外,这样是绝对不会出现绘制图片遮盖的问题的。
      

  7.   

    晕了,剪是剪了一块,可是下面啥都没有,透明的!控件还是看不到,点也点不上了,之前还能点,只是看不到而已!
    下面是OnInitDialog()的代码,帮我看看吧,各位大虾
    BOOL CKEYSDlg::OnInitDialog()
    {

    CDialog::OnInitDialog(); ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);
    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
    CString strAboutMenu;
    strAboutMenu.LoadString(IDS_ABOUTBOX);
    if (!strAboutMenu.IsEmpty())
    {
    pSysMenu->AppendMenu(MF_SEPARATOR);
    pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    }
    }
    SetIcon(m_hIcon, TRUE);
    SetIcon(m_hIcon, FALSE);
    m_pRasDlg=new CRasDlg();
    m_pRasDlg->m_pParentDlg = this; m_pSendSmsDlg=new CSendSmsDlg();
    m_pSendSmsDlg->m_pParentDlg = this; m_pReceiveSmsDlg=new CReceiveSmsDlg();
    m_pReceiveSmsDlg->m_pParentDlg = this; m_pPhoneBookDlg=new CPhoneBookDlg();
    m_pPhoneBookDlg->m_pParentDlg = this; m_pSetDlg=new CSetDlg();
    m_pSetDlg->m_pParentDlg = this; m_pHistoryDlg=new CRecordDlg();
    m_pHistoryDlg->m_pParentDlg = this; m_pNetworkDlg=new CNetworkDlg();
    m_pNetworkDlg->m_pParentDlg = this; m_pHelpDlg=new CHelpDlg();
    m_bInit = true; m_pSendSmsDlg->Create(IDD_MESSAGE_DIALOG);
    m_pSendSmsDlg->ShowWindow(SW_HIDE); m_pReceiveSmsDlg->Create(IDD_RECEIVE_SMS_DIALOG);
    m_pReceiveSmsDlg->ShowWindow(SW_HIDE); m_pPhoneBookDlg->Create(IDD_PHONEBOOK_DIALOG);
    m_pPhoneBookDlg->ShowWindow(SW_HIDE); m_pSetDlg->Create(IDD_SET_DIALOG);
    m_pSetDlg->ShowWindow(SW_HIDE); m_pHistoryDlg->Create(IDD_RECORD_DIALOG);
    m_pHistoryDlg->ShowWindow(SW_HIDE);

    m_pRasDlg->Create(IDD_RAS_DIALOG);
    m_pRasDlg->ShowWindow(SW_HIDE); m_pNetworkDlg->Create(IDD_NETWORK_DIALOG);
    m_pNetworkDlg->ShowWindow(SW_HIDE); pStatic1=(CStatic *)(GetDlgItem(IDC_STATIC_SIGNAL));
    pStaticBack1 = (CStatic *)(GetDlgItem(IDC_STATIC));
    Bitmap1=::LoadBitmap(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDB_BITMAP_SIGNAL_1));
    Bitmap2=::LoadBitmap(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDB_BITMAP_SIGNAL_2));
    Bitmap3=::LoadBitmap(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDB_BITMAP_SIGNAL_3));
    Bitmap4=::LoadBitmap(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDB_BITMAP_SIGNAL_4));
    Bitmap5=::LoadBitmap(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDB_BITMAP_SIGNAL_5));
    Bitmap6=::LoadBitmap(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDB_BITMAP_SIGNAL_6));
    m_ctrlBtnRas.LoadBitmaps(IDB_BITMAP_INTERNET2,IDB_BITMAP_INTERNET1);
         m_ctrlBtnSendSms.LoadBitmaps(IDB_BITMAP_SENDSMS1,IDB_BITMAP_SENDSMS2);
    m_ctrlBtnReceiveSms.LoadBitmaps(IDB_BITMAP_RECSMS1,IDB_BITMAP_RECSMS2);
            m_ctrlBtnPhoneBook.LoadBitmaps(IDB_BITMAP_PHONEBOOK1,IDB_BITMAP_PHONEBOOK2);
    m_ctrlBtnHistory.LoadBitmaps(IDB_BITMAP_HISTORY1,IDB_BITMAP_HISTORY2);
            m_ctrlBtnNetwork.LoadBitmaps(IDB_BITMAP_NETWORK1,IDB_BITMAP_NETWORK2);
            m_ctrlBtnSetting.LoadBitmaps(IDB_BITMAP_SETTINGS1,IDB_BITMAP_SETTINGS2);

    m_ctrlBtnClose.LoadBitmaps(IDB_BITMAP_BUTTON_CLOSE_1,IDB_BITMAP_BUTTON_CLOSE_2);
    m_ctrlBtnMinimize.LoadBitmaps(IDB_BITMAP_BUTTON_MINIMIZE_1,IDB_BITMAP_BUTTON_MINIMIZE_2); EnableToolTips(true);
    m_tt.Create(this);
    m_tt.Activate(true); m_tt.AddTool(GetDlgItem(IDC_BUTTON_RAS),_T("Internet"));
    m_tt.AddTool(GetDlgItem(IDC_BUTTON_SENDSMS),_T("Send Sms"));
    m_tt.AddTool(GetDlgItem(IDC_BUTTON_RECEIVESMS),_T("Receive Sms"));
    m_tt.AddTool(GetDlgItem(IDC_BUTTON_PHONEBOOK),_T("PhoneBook"));
    m_tt.AddTool(GetDlgItem(IDC_BUTTON_CLOSE),_T("Close"));
    m_tt.AddTool(GetDlgItem(IDC_BUTTON_MINIMIZE),_T("Minimize"));
    m_tt.AddTool(GetDlgItem(IDC_BUTTON_NETWORK),_T("Network setting"));
    m_tt.AddTool(GetDlgItem(IDC_BUTTON_SETTING),_T("Setting"));
    m_tt.AddTool(GetDlgItem(IDC_BUTTON_HISTORY),_T("History"));    
    m_ctrlBtnRas.EnableWindow(true);
    m_ctrlBtnSendSms.EnableWindow(true);
    //m_ctrlBtnSendSms.EnableWindow(true);
    m_ctrlBtnReceiveSms.EnableWindow(true);
    m_ctrlBtnPhoneBook.EnableWindow(true);
    m_ctrlBtnHistory.EnableWindow(true);
    m_ctrlBtnNetwork.EnableWindow(true);
    m_ctrlBtnSetting.EnableWindow(true);
    m_StaticStatus.SetWindowText("Initializing...");
    m_pRasDlg->m_ctrlConnect.EnableWindow(true);
        //RefreshStaticCtrl(IDC_STATIC_STATUS);
    //this->UpdateWindow();


        HDC hdcTemp=GetDC()->m_hDC;
    m_hdcMemory=CreateCompatibleDC(hdcTemp);
    HBITMAP hBitMap=CreateCompatibleBitmap(hdcTemp,m_BakWidth,m_BakHeight);
    SelectObject(m_hdcMemory,hBitMap);
    //确定透明度
    if(Transparent<0||Transparent>100) Transparent=100; m_Blend.SourceConstantAlpha=int(Transparent*2.55);//1~255
    HDC hdcScreen=::GetDC (m_hWnd);
    RECT rct;
    //得到窗体的区域 GetWindowRect(&rct);
    POINT ptWinPos={rct.left,rct.top};
    Graphics graph(m_hdcMemory);
    RECT rectMain;//刚加上的
    (GetDlgItem(IDC_BUTTON_CLOSE))->GetWindowRect(&rectMain);//刚加上的//确定画的背景区域
    Point points[] = { Point(0, 0), 
                   Point(m_BakWidth, 0), 
       Point(0, m_BakHeight)
    };
    static bool bFly=false;
    graph.ExcludeClip((Gdiplus::Rect&)rectMain);//刚加上的
    graph.DrawImage(m_pImageClock, points, 3);
    pStaticBack1->SetBitmap(hBitMap); SIZE sizeWindow={m_BakWidth,m_BakHeight};
    POINT ptSrc={0,0};
    DWORD dwExStyle=GetWindowLong(m_hWnd,GWL_EXSTYLE);//GWL_EXSTYLE;获得扩展窗口风格。
    if((dwExStyle&0x80000)!=0x80000)//dwExStyle&0x80000显示alpha透明通道,如为0x80000窗体为透明,否则设置为透明
    SetWindowLong(m_hWnd,GWL_EXSTYLE,dwExStyle^0x80000); BOOL bRet=FALSE;
    //The UpdateLayeredWindow function updates the position, size, shape, content, and translucency of a layered window. 
    //刷新窗口函数
    bRet= UpdateLayeredWindow( m_hWnd,hdcScreen,&ptWinPos,
    &sizeWindow,m_hdcMemory,&ptSrc,0,&m_Blend,2); ChangePanel(TYPE_CONNECT);
    AfxGetMainWnd()->SetWindowPos(&CWnd::wndTopMost,200,200,0,0,SWP_NOSIZE);
    //bRet= UpdateLayeredWindow(m_hWnd,hdcScreen,&ptWinPos,
    // &sizeWindow,m_hdcMemory,&ptSrc,0,&m_Blend,2);
    SetTimer(INITIALIZE_EVENT,99,NULL);
    return TRUE;
    }
      

  8.   

    透明BMP图片的实现函数,最后一个参数是透明色void TransparentBltEx( HDC hdcDest,    
      int nXOriginDest,  
      int nYOriginDest,  
      int nWidthDest,    
      int nHeightDest,   
      HDC hdcSrc,        
      int nXOriginSrc,   
      int nYOriginSrc,   
      int nWidthSrc,     
      int nHeightSrc,    
      UINT crTransparent 
      )
    {
    HBITMAP hOldImageBMP, hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest); // 创建兼容位图
    HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL); // 创建单色掩码位图
    HDC hImageDC = CreateCompatibleDC(hdcDest);
    HDC hMaskDC = CreateCompatibleDC(hdcDest);
    hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP);
    hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC, hMaskBMP);

    if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
    BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
    else
    StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, 
    hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);

    SetBkColor(hImageDC, crTransparent);

    BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY);

    SetBkColor(hImageDC, RGB(0,0,0));
    SetTextColor(hImageDC, RGB(255,255,255));
    BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

    SetBkColor(hdcDest,RGB(255,255,255));
    SetTextColor(hdcDest,RGB(0,0,0));
    BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

    // or
    BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);


    SelectObject(hImageDC, hOldImageBMP);
    DeleteDC(hImageDC);
    SelectObject(hMaskDC, hOldMaskBMP);
    DeleteDC(hMaskDC);
    DeleteObject(hImageBMP);
    DeleteObject(hMaskBMP);
    }
      

  9.   

    ExcludeClip只是影响绘图的显示而已,并不会影响到你的按钮包括点击等事件的响应啊。
    肯定是你的代码哪里写错了。
    有可能是你的按钮控件等并不是主窗口的子窗口,而且你的主窗口又设置成TopMost,所以把所有的按钮给遮住了,无法响应事件。
      

  10.   

    用UpdateLayeredWindow后, 窗体就不会再用原来的绘制消息机制, 所以控件虽然已经添加到窗体上, 也可以操作, 但根本没被绘制出来, 你可以跟踪窗体的OnPaint看看就知道了 (OnPaint是C#里的, 在每次窗体重绘时通知, 我不知道C++里是什么)所以你这个问题, 并不是控件被PNG盖住了, 所以不要想在这方面下功夫解决了, 我曾经为这个问题把百度都搜烂了, 没办法直接解决.两种可行的方式:一. 像上面有人说的, 再加一个背景色透明的窗体覆盖至于原窗体上控件太多没法移动的问题 (唉 这个如果用 C# 的 WinForm 实在太简单了, 全部控件选中, Ctrl+C, 再到新窗体中Ctrl+V, 同样把对应的事件和方法COPY一下就OK了 ,哈哈)我只懂用C#来描述 你自己翻译一下public class CustomForm : System.Windows.Forms.Form {
      private void InitializeComponent() { // 这个方法会在构造函数中被调用
        base.ControlAdded += new ControlEventHandler(this.CustomForm_ControlAdded);
      }
      private void CustomForm_ControlAdded(object sender, ControlEventArgs e) {
        this.foreForm.Controls.Add(e.Control);
      }
    }上面只是用于把背景窗体的控件转到上层窗体的代码, 其它省略了
    然后再把你自己的窗体继承自这个 CustomForm 就OK了, 控件会自动转移了
    不过我不知道用MFC之类的能不能这样做, 那再看第二种方法吧二. 用PS在背景png图片上画出所有控件的外观, 这样用户就看得见了, 再在对应位置添加控件, 虽然不会被绘制出来, 但还是可以正常响应的.不过这个方法只适用于控件少且简单的, 像你这个控件超多的, 唉, 我为你难过...
      

  11.   

    这个地方帖不了图啊。
    http://hi.baidu.com/%D5%E2%B5%C0%CC%E2%CE%D2%BB%E1%D7%F6/album/item/856d8fd8d0cc0fd938012fcb.htmlhttp://hi.baidu.com/%D5%E2%B5%C0%CC%E2%CE%D2%BB%E1%D7%F6/album/item/b64e85c7c833c02b9c163dcb.htmlhttp://hi.baidu.com/%D5%E2%B5%C0%CC%E2%CE%D2%BB%E1%D7%F6/album/item/4a20730b9604b20eb0351dcb.html
      

  12.   

    重载Onpaint,在里面贴图会有问题?
    我都是这么弄的
      

  13.   


    用了透明的API后,控件也响应变成透明了
    如果要控件不透明,需要至少2层窗体联动显示。可以考虑参考这个帖子http://topic.csdn.net/u/20090805/11/e69e166f-efa5-4c2f-80c5-7f0caf757ff9.html
      

  14.   

    如果爱WM_PAINT消息中绘制对话框窗体的话会出现你这种情况。 你可以在WM_INITDIALOG时创建一个位图画刷,然后在WM_CTLCOLOR中返回该位图画刷即可。
      

  15.   

    这样行吗还是用两层窗体, 把你目前的这个改回全透明的, 但不用PNG背景, 然后另外实现一个PNG背景窗体在目前的窗体之下, 再实现联动.如果可以, 那对你来说应该是代价最小的了, 目前控件都不用动.
      

  16.   

    对话框用png做背景不会出现你那样的问题啦,肯定是你处理背景时出的问题,无关png透明度等。
    你背景是怎么处理的?
      

  17.   


    我也在关注这个问题, 我是用的 UpdateLayeredWindow 处理的, LZ应该也是,这个问题我曾经搜了好久, 还是没有找到更好的办法, 你有什么别的处理方式吗?前提是, 除了PNG做窗体背景外, 还要实现PNG的半透明.