已知rc,dc

解决方案 »

  1.   

    好像有这样的一个函数:
    SetLayeredWindowAttributes(HWND,COLORREF,ALPHA,FLAG)
    第三个参数就是设置透明度的
    AlPHA :0--透明 ; 255--完全不透明没试过,你自己试试看
      

  2.   


    SetLayeredWindowAttributes是实现窗体的透明,而SetBkMode的参数透明也仅仅是保持背景填充色不变。我想要做的是:前提:该rc是一矩形区域
    如果在当前的rc、dc环境下不对该区域做任何描画,那么该区域显示出来的就是黑色。目标:
    希望可以找到一种方法,可以在上述条件下,使得该区域就是完全透明的。
    也就是说,如果该区域位于一彩色背景上,那么可以透视该区域。
      

  3.   

    CreateRgnFromBitmap-------自己写这么一个函数(楼主不清楚的话,我可以提供源码, 我有一个现成的类)。
    然后:SetWindowRgn。可以实现窗口的指定区域透明。
      

  4.   

    云天,我正在避免使用SetWindowRgn函数因为要在该区域描画的是不规则形状,最简单的方法就是定义一个Point数组,然后使用 
    HRGN hPolyRgn = CreatePolygonRgn(...)
    以及SetWindowRgn(m_hWnd,hPolyRgn)便可以达到该效果。但是,如果是规则的矩形区域,SetWindowRgn速度很快,而对于不规则区域(包括RoundRect,Ellipse等),速度明显会慢很多。
    为了保证速度同时实现该显示效果,我想做的就是在透明区域上给hPolyRgn填充自己的背景色。曾经尝试过的一种位图透明的方法:
     BLENDFUNCTION m_bf; 
     m_bf.BlendOp = AC_SRC_OVER;
     m_bf.BlendFlags = 0;
     m_bf.SourceConstantAlpha = 0;
     m_bf.AlphaFormat = 0; HDC dcMem = CreateCompatibleDC(dc);
     HBITMAP hBmp = (HBITMAP)CreateCompatibleBitmap(dc,rc.right-rc.left,rc.bottom -rc.top);
     HBITMAP hb = (HBITMAP)SelectObject(dcMem,hBmp);
     
     AlphaBlend(dc, 0,0, rc.right -rc.left ,rc.bottom - rc.top , dcMem, 0,0,rc.right -rc.left ,rc.bottom - rc.top ,m_bf);
    但是并没有达到想要的结果,通过GetLastError()得到的错误码为:参数不正确:(((((
    不懂是为了什么。
      

  5.   

    这里有篇文章你也许可以参考参考:位图的淡入淡出显示
    作者:Ma我们经常在AboutBox中显示一幅关于公司或自己讯息的位图,有没有想过让这幅位图有更酷的效果?比如加上淡入淡出效果?只要有了这个CAlphaCtrl控件就可以轻松实现。
    CAlphaCtrl是从CStatic继承而来。使用时只要把CalphaCtrl加入窗体,然后调用LoadAlphaBitmap(UINT uID, int iTimer)函数就可以实现位图的淡入淡出。其中uID是位图的资源ID,iTimer是位图显示时间间隔,值愈小显示愈快。
    下面就来说一说CalphaCtrl是如何实现的。关键的一个实现函数是一个win32 API: AlphaBlend,此函数可以实现图像的透明显示,相关的参数和资料请自行参阅MSDN,值得注意的是使用此函数时要链接到msimg32.lib库。  第一步,我们先在CalphaCtrl类中增加几个Data Member:CBitmap Bmp; 
    BOOL bCanPaint; UINT nBmpID; int nTimer;
     第二步,在CalphaCtrl类中增加一个Member Function: 
    void AlphaDisplay(CDC &pDC, CClientDC &dc, BLENDFUNCTION& rBlendProps, int width, int heigh, byte nLevel)
    {
            //nLevel是透明度,0表示不显示,255则完全显示
            rBlendProps.SourceConstantAlpha = nLevel;
           AlphaBlend( dc.m_hDC, 0, 0, width, heigh, pDC.m_hDC, 0, 0, 
            width, heigh, rBlendProps );
    }
     第三步,增加一个名为tdDisplay的全局函数,此函数为一个线程函数,用于位图的显示。 UINT tdDisplay(LPVOID lpParam)
    {
            CAlphaCtrl* AlphaCtrl = (CAlphaCtrl*)lpParam;        CClientDC dc(AlphaCtrl);
            CDC pDC;
            pDC.CreateCompatibleDC(&dc); 
            pDC.SelectObject(&AlphaCtrl->Bmp);        BLENDFUNCTION rBlendProps;
            rBlendProps.BlendOp = AC_SRC_OVER;
            rBlendProps.BlendFlags = 0;
            rBlendProps.AlphaFormat = 0;     BITMAP bmInfo;
            ::GetObject( AlphaCtrl->Bmp.m_hObject, sizeof(BITMAP), &bmInfo );
            INT nWidth, nHeigh;
            nWidth = bmInfo.bmWidth;
            nHeigh = bmInfo.bmHeight;AlphaCtrl->SetWindowPos(NULL, 0, 0, nWidth, nHeigh, SWP_NOMOVE);
          int i = 0;
            while(i <= 255)
            {
            AlphaCtrl->AlphaDisplay(pDC, dc, rBlendProps, nWidth, nHeigh, i);
            i += 5;
            Sleep(AlphaCtrl->nTimer);
            }
          AlphaCtrl->bCanPaint = 1; //Make OnPaint Word
           AfxEndThread(0);
            return 0;
    }
     第四步,现在万事俱备,加上初始化函数:
    BOOL LoadAlphaBitmap(UINT uID, int iTimer)
            {
            int i = Bmp.LoadBitmap(uID);
            
            if(i)
            {
            AfxBeginThread(tdDisplay, this);
            nBmpID = uID;
            nTimer = iTimer;
            return 1;
            }
            else
            {
            TRACE("Load Bitmap Failed\n");
            return 0;
            }
            
            return 1;
            }
     
      

  6.   

    前面提到过的位图透明已经可以了,那段代码中产生参数错误的原因是由于源位图的宽度、高度不正确(应为该位图的实际大小)。但是结果证明,这种方法仍旧无法达到我要的效果。我的想法是,能够将该区域变成透明位图的样子,也就是说,在rc上的任何描画动作都仿佛是在后面的背景上所做,而上述方法只是重新产生了一个透明的位图,该区域并没有透明,问题仍旧存在。假设这样的一个函数
    DrawItem(HDC dc,RECT &rc)
    {
        //1:假设该rc传入时是默认画刷的颜色(黑色),我首先需要将它设置为透明    //2:画一不规则的封闭路径,产生新的画刷(位图或者颜色)进行填充
        
    }使用SetWindowRgn的话,可以不用实现1而很容易的达到目的,但前提是尽量避免SetWindowRgn,因为对于不规则的区域,它的速度会相对较慢。不知道各位是否还有别的方法可试验?
      

  7.   

    把该区域从Update Region中去除即可。
      

  8.   

    好的,mail地址:[email protected]
      

  9.   

    wqs6,邮件已经收到了,多谢多谢,不过并不能解决这个问题,因为这里的位图透明是将指定的某种颜色值透明而实现的,但是对于想要透明的区域来说,颜色值不可能是单色唯一的,或者首先考虑,如何将该区域变成单色位图?...Mackz,通过设置剪切区域然后更新之后不显示是可以的,但是它与前面提到过的SetWindow
    Rgn一样存在速度问题,即规则区域和不规则区域的处理速度存在一些差别,并不可行。