请问:如何使得一个客户区域为透明? 已知rc,dc 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 好像有这样的一个函数:SetLayeredWindowAttributes(HWND,COLORREF,ALPHA,FLAG)第三个参数就是设置透明度的AlPHA :0--透明 ; 255--完全不透明没试过,你自己试试看 SetLayeredWindowAttributes是实现窗体的透明,而SetBkMode的参数透明也仅仅是保持背景填充色不变。我想要做的是:前提:该rc是一矩形区域如果在当前的rc、dc环境下不对该区域做任何描画,那么该区域显示出来的就是黑色。目标:希望可以找到一种方法,可以在上述条件下,使得该区域就是完全透明的。也就是说,如果该区域位于一彩色背景上,那么可以透视该区域。 CreateRgnFromBitmap-------自己写这么一个函数(楼主不清楚的话,我可以提供源码, 我有一个现成的类)。然后:SetWindowRgn。可以实现窗口的指定区域透明。 云天,我正在避免使用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()得到的错误码为:参数不正确:(((((不懂是为了什么。 这里有篇文章你也许可以参考参考:位图的淡入淡出显示作者: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; } 前面提到过的位图透明已经可以了,那段代码中产生参数错误的原因是由于源位图的宽度、高度不正确(应为该位图的实际大小)。但是结果证明,这种方法仍旧无法达到我要的效果。我的想法是,能够将该区域变成透明位图的样子,也就是说,在rc上的任何描画动作都仿佛是在后面的背景上所做,而上述方法只是重新产生了一个透明的位图,该区域并没有透明,问题仍旧存在。假设这样的一个函数DrawItem(HDC dc,RECT &rc){ //1:假设该rc传入时是默认画刷的颜色(黑色),我首先需要将它设置为透明 //2:画一不规则的封闭路径,产生新的画刷(位图或者颜色)进行填充 }使用SetWindowRgn的话,可以不用实现1而很容易的达到目的,但前提是尽量避免SetWindowRgn,因为对于不规则的区域,它的速度会相对较慢。不知道各位是否还有别的方法可试验? 把该区域从Update Region中去除即可。 好的,mail地址:[email protected] wqs6,邮件已经收到了,多谢多谢,不过并不能解决这个问题,因为这里的位图透明是将指定的某种颜色值透明而实现的,但是对于想要透明的区域来说,颜色值不可能是单色唯一的,或者首先考虑,如何将该区域变成单色位图?...Mackz,通过设置剪切区域然后更新之后不显示是可以的,但是它与前面提到过的SetWindowRgn一样存在速度问题,即规则区域和不规则区域的处理速度存在一些差别,并不可行。 窗口从被遮住到显示(最顶层),在这中间需要做一些事情,需要对什么消息进行处理 一个网络包不能送达的问题 录音格式转换的问题 线程的问题! 怎样在启动2000前修改系统时间? 没分了,请问我想关闭当前对话框,打开另一个对话框,并且我想把当前对话框的值传到另一个对话框,怎么办呀 只有在listctrl控件中选中一行才使一些按钮有效,该使用哪个消息?如果换做是只有在树型控件中点击叶节点才有效呢? 如何作为第三者监听串口的通讯数据?有没有源码 各路高手快来杀毒!! 关于COM http1.0和1.1协议规定client提交表单时候的内容用怎样的格式编码? 如何处理透明色
SetLayeredWindowAttributes(HWND,COLORREF,ALPHA,FLAG)
第三个参数就是设置透明度的
AlPHA :0--透明 ; 255--完全不透明没试过,你自己试试看
SetLayeredWindowAttributes是实现窗体的透明,而SetBkMode的参数透明也仅仅是保持背景填充色不变。我想要做的是:前提:该rc是一矩形区域
如果在当前的rc、dc环境下不对该区域做任何描画,那么该区域显示出来的就是黑色。目标:
希望可以找到一种方法,可以在上述条件下,使得该区域就是完全透明的。
也就是说,如果该区域位于一彩色背景上,那么可以透视该区域。
然后:SetWindowRgn。可以实现窗口的指定区域透明。
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()得到的错误码为:参数不正确:(((((
不懂是为了什么。
作者: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;
}
DrawItem(HDC dc,RECT &rc)
{
//1:假设该rc传入时是默认画刷的颜色(黑色),我首先需要将它设置为透明 //2:画一不规则的封闭路径,产生新的画刷(位图或者颜色)进行填充
}使用SetWindowRgn的话,可以不用实现1而很容易的达到目的,但前提是尽量避免SetWindowRgn,因为对于不规则的区域,它的速度会相对较慢。不知道各位是否还有别的方法可试验?
Rgn一样存在速度问题,即规则区域和不规则区域的处理速度存在一些差别,并不可行。