求如上图程序透明界面的实现方法
试了半天,SetLayeredWindowAttributes如果设置透明颜色,鼠标就会透过窗口;如果设置透明度,窗口上所有控件的透明度也随之改变。
如果要实现只使窗口透明,窗口上控件的透明度不变,同时窗口仍可以相应鼠标消息有什么解决方案?
21 个解决方案
#1
那就设置成颜色和透明度两个共同作用吧
#2
可以在上面创建一个悬浮对话框的镂空来放控件,然后再判断处理WM_WINDOWPOSCHANGED和WM_WINDOWPOSCHANGING来使两个窗口一起移动
#3
貌似只要设置了颜色,鼠标就直接透过了
#4
镂空是指……
#5
除了控件部分,其于部分可以用SetWindowRgn去掉,但你得计算这个rgn
#6
顶下呃……我还是木有解决
#7
#8
窗口背景透明?
#9
看程序的效果图的话应该是对话框全透明的同时,上面的控件也透明了。
从控件中的字符显示看,应该是设置的透明色,但是界面却又能响应鼠标消息,找不到思路啊
#10
SetLayeredWindowAttributes设置好透明度,然后背景贴一个PNG图片把对话框背景搞成透明的,不知行不行?
#11
mfc在半透明窗口比较逊,只有在win8中才变得非常简单了。
http://download.csdn.net/detail/zhoujielunzhimi/5538917
这是一个半透明的例子,缺点是放在窗口上的控件看不见(我没有设置隐藏),但是可以响应。这个改变要在win8才行,到了win8,控件和窗口都可以半透明了。
目前像360,qq这样的半透明窗口,不透明或半透明控件,都是基于directui思想,就是我上面这个例子,把所有的绘制都画在一个窗口上,那些控件都是画出来的,没有句柄。
http://download.csdn.net/detail/zhoujielunzhimi/5538917
这是一个半透明的例子,缺点是放在窗口上的控件看不见(我没有设置隐藏),但是可以响应。这个改变要在win8才行,到了win8,控件和窗口都可以半透明了。
目前像360,qq这样的半透明窗口,不透明或半透明控件,都是基于directui思想,就是我上面这个例子,把所有的绘制都画在一个窗口上,那些控件都是画出来的,没有句柄。
#12
多谢关注,对话框透明包括控件透明都好解决,如下图
但问题在于,这样解决会使所有鼠标事件都透过窗口和控件
另外如果如fishion提到的,分层解决的话,不管怎样,控件上字符的透明度始终还是和控件的透明度一致呃……
#13
“要实现只使窗口透明,窗口上控件的不透明”
void CTransDlgDlg::OnButton1()
{
// TODO: Add your control notification handler code here
static BOOL sw=FALSE;
if(!sw)
{
sw=TRUE;
CRect rcWin;
GetWindowRect(&rcWin);
CRect rcClt;
GetClientRect(&rcClt);
ClientToScreen(&rcClt);
//
rcClt.OffsetRect(-rcWin.left,-rcWin.top);
int offX=rcClt.left;
int offY=rcClt.top;
rcWin.OffsetRect(-rcWin.left,-rcWin.top);
//
CRgn tmp;
tmp.CreateRectRgnIndirect(&rcClt);
//
RgnSubtractCtrls(tmp,offX,offY);
//
CRgn rgn;
rgn.CreateRectRgnIndirect(&rcWin);
rgn.CombineRgn(&rgn, &tmp, RGN_DIFF);
SetWindowRgn(rgn,TRUE);
tmp.DeleteObject();
rgn.DeleteObject();
m_Trans.SetWindowText("不透明");
}
else
{
sw=FALSE;
SetWindowRgn(0,TRUE);
m_Trans.SetWindowText("透明");
}
}
void CTransDlgDlg::RgnSubtractCtrls(CRgn &rgn,int offX,int offY)
{
CWnd *pWnd=0;
int ID[]={IDOK,IDC_BUTTON1,IDCANCEL};
for(int jj=0;jj<sizeof(ID)/sizeof(int);jj++)
{
pWnd=GetDlgItem(ID[jj]);
CRect rc;
pWnd->GetWindowRect(&rc);
ScreenToClient(&rc);
rc.OffsetRect(offX,offY);
CRgn ctlRgn;
ctlRgn.CreateRectRgnIndirect(&rc);
rgn.CombineRgn(&rgn,&ctlRgn,RGN_XOR);
ctlRgn.DeleteObject();
}
}
void CTransDlgDlg::OnButton1()
{
// TODO: Add your control notification handler code here
static BOOL sw=FALSE;
if(!sw)
{
sw=TRUE;
CRect rcWin;
GetWindowRect(&rcWin);
CRect rcClt;
GetClientRect(&rcClt);
ClientToScreen(&rcClt);
//
rcClt.OffsetRect(-rcWin.left,-rcWin.top);
int offX=rcClt.left;
int offY=rcClt.top;
rcWin.OffsetRect(-rcWin.left,-rcWin.top);
//
CRgn tmp;
tmp.CreateRectRgnIndirect(&rcClt);
//
RgnSubtractCtrls(tmp,offX,offY);
//
CRgn rgn;
rgn.CreateRectRgnIndirect(&rcWin);
rgn.CombineRgn(&rgn, &tmp, RGN_DIFF);
SetWindowRgn(rgn,TRUE);
tmp.DeleteObject();
rgn.DeleteObject();
m_Trans.SetWindowText("不透明");
}
else
{
sw=FALSE;
SetWindowRgn(0,TRUE);
m_Trans.SetWindowText("透明");
}
}
void CTransDlgDlg::RgnSubtractCtrls(CRgn &rgn,int offX,int offY)
{
CWnd *pWnd=0;
int ID[]={IDOK,IDC_BUTTON1,IDCANCEL};
for(int jj=0;jj<sizeof(ID)/sizeof(int);jj++)
{
pWnd=GetDlgItem(ID[jj]);
CRect rc;
pWnd->GetWindowRect(&rc);
ScreenToClient(&rc);
rc.OffsetRect(offX,offY);
CRgn ctlRgn;
ctlRgn.CreateRectRgnIndirect(&rc);
rgn.CombineRgn(&rgn,&ctlRgn,RGN_XOR);
ctlRgn.DeleteObject();
}
}
#14
感谢两位大牛的回复~学习了。窗口透明,空间不透明的方法参照了论坛某贴控件使用SetParent()后即可对窗口和控件分别设置透明度,但是问题依然存在,即控件上的字符的透明度始终和控件本身透明度一致,无法达到帖子开始的控件也透明,但是控件上的字符不透明的效果。
#15
另外,还发现一个问题,win7下,完全相同的代码,在aero开关时,表现完全不一致。
如下图,使用aero主题,窗口设置了透明色,但是窗口依然能响应鼠标消息,控件也透明,但是控件上的字符不受影响。
同样的程序,在aero关闭时,如下图,鼠标直接透过窗口,而且控件也未透明
问题是,能否在非aero主题下使程序达到相同效果呢
如下图,使用aero主题,窗口设置了透明色,但是窗口依然能响应鼠标消息,控件也透明,但是控件上的字符不受影响。
同样的程序,在aero关闭时,如下图,鼠标直接透过窗口,而且控件也未透明
问题是,能否在非aero主题下使程序达到相同效果呢
#16
UpdateLayeredWindow+一个上层窗口
理论上可行
普通的情况 的确是可以的 因为我做过
想真的达到完美 就困难了 难点就是 如果背景是播放的某种格式的视频 可能就透不过去了 如果可以的话 放弃吧 我当时研究了很久 也没最终解决视频透明 在多种操作系统 多种视频格式的情况下 总会有例外 还有闪烁的情况 让人揪心 请果断放弃 不然必然有bug 包括迅雷那个半透的小窗口 在某些情况下都闪烁 或透不过去
理论上可行
普通的情况 的确是可以的 因为我做过
想真的达到完美 就困难了 难点就是 如果背景是播放的某种格式的视频 可能就透不过去了 如果可以的话 放弃吧 我当时研究了很久 也没最终解决视频透明 在多种操作系统 多种视频格式的情况下 总会有例外 还有闪烁的情况 让人揪心 请果断放弃 不然必然有bug 包括迅雷那个半透的小窗口 在某些情况下都闪烁 或透不过去
#17
#18
如果有什么办法让不打开aero时,效果和打开aero一样问题就解决了……
#19
inline BOOL SetWindowTransparent(HWND hwnd, BOOL bOpaque, UINT nAlpha)
{
// Check parameter
if (!::IsWindow(hwnd)) {
return FALSE;
}
// nAlpha needs between 0 and 255
if (nAlpha > 255) {
return FALSE;
}
if (bOpaque) {
// Set WS_EX_LAYERED on this window
SetWindowLong(hwnd,
GWL_EXSTYLE,
GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
// Make this window 70% alpha
::SetLayeredWindowAttributes(hwnd, 0, (255 * nAlpha) / 100, LWA_ALPHA);
} else {
// Remove WS_EX_LAYERED from this window styles
::SetWindowLong(hwnd,
GWL_EXSTYLE,
GetWindowLong(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
}
// Ask the window and its children to repaint
::RedrawWindow(hwnd,
NULL,
NULL,
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
return TRUE;
}
#20
#21
您好
我是本版版主
此帖已多日无人关注
请您及时结帖
如您认为问题没有解决可按无满意结帖处理
另外本版设置了 疑难问题汇总帖
并已在版面置顶
相关规定其帖子中有说明
您可以根据规定提交您帖子的链接
如您目前不想结帖只需回帖说明
我们会删除此结帖通知
见此回复三日内无回应
我们将强制结帖
相关规定详见界面 界面版关于版主结帖工作的具体办法
我是本版版主
此帖已多日无人关注
请您及时结帖
如您认为问题没有解决可按无满意结帖处理
另外本版设置了 疑难问题汇总帖
并已在版面置顶
相关规定其帖子中有说明
您可以根据规定提交您帖子的链接
如您目前不想结帖只需回帖说明
我们会删除此结帖通知
见此回复三日内无回应
我们将强制结帖
相关规定详见界面 界面版关于版主结帖工作的具体办法
#1
那就设置成颜色和透明度两个共同作用吧
#2
可以在上面创建一个悬浮对话框的镂空来放控件,然后再判断处理WM_WINDOWPOSCHANGED和WM_WINDOWPOSCHANGING来使两个窗口一起移动
#3
貌似只要设置了颜色,鼠标就直接透过了
#4
镂空是指……
#5
除了控件部分,其于部分可以用SetWindowRgn去掉,但你得计算这个rgn
#6
顶下呃……我还是木有解决
#7
#8
窗口背景透明?
#9
看程序的效果图的话应该是对话框全透明的同时,上面的控件也透明了。
从控件中的字符显示看,应该是设置的透明色,但是界面却又能响应鼠标消息,找不到思路啊
#10
SetLayeredWindowAttributes设置好透明度,然后背景贴一个PNG图片把对话框背景搞成透明的,不知行不行?
#11
mfc在半透明窗口比较逊,只有在win8中才变得非常简单了。
http://download.csdn.net/detail/zhoujielunzhimi/5538917
这是一个半透明的例子,缺点是放在窗口上的控件看不见(我没有设置隐藏),但是可以响应。这个改变要在win8才行,到了win8,控件和窗口都可以半透明了。
目前像360,qq这样的半透明窗口,不透明或半透明控件,都是基于directui思想,就是我上面这个例子,把所有的绘制都画在一个窗口上,那些控件都是画出来的,没有句柄。
http://download.csdn.net/detail/zhoujielunzhimi/5538917
这是一个半透明的例子,缺点是放在窗口上的控件看不见(我没有设置隐藏),但是可以响应。这个改变要在win8才行,到了win8,控件和窗口都可以半透明了。
目前像360,qq这样的半透明窗口,不透明或半透明控件,都是基于directui思想,就是我上面这个例子,把所有的绘制都画在一个窗口上,那些控件都是画出来的,没有句柄。
#12
多谢关注,对话框透明包括控件透明都好解决,如下图
但问题在于,这样解决会使所有鼠标事件都透过窗口和控件
另外如果如fishion提到的,分层解决的话,不管怎样,控件上字符的透明度始终还是和控件的透明度一致呃……
#13
“要实现只使窗口透明,窗口上控件的不透明”
void CTransDlgDlg::OnButton1()
{
// TODO: Add your control notification handler code here
static BOOL sw=FALSE;
if(!sw)
{
sw=TRUE;
CRect rcWin;
GetWindowRect(&rcWin);
CRect rcClt;
GetClientRect(&rcClt);
ClientToScreen(&rcClt);
//
rcClt.OffsetRect(-rcWin.left,-rcWin.top);
int offX=rcClt.left;
int offY=rcClt.top;
rcWin.OffsetRect(-rcWin.left,-rcWin.top);
//
CRgn tmp;
tmp.CreateRectRgnIndirect(&rcClt);
//
RgnSubtractCtrls(tmp,offX,offY);
//
CRgn rgn;
rgn.CreateRectRgnIndirect(&rcWin);
rgn.CombineRgn(&rgn, &tmp, RGN_DIFF);
SetWindowRgn(rgn,TRUE);
tmp.DeleteObject();
rgn.DeleteObject();
m_Trans.SetWindowText("不透明");
}
else
{
sw=FALSE;
SetWindowRgn(0,TRUE);
m_Trans.SetWindowText("透明");
}
}
void CTransDlgDlg::RgnSubtractCtrls(CRgn &rgn,int offX,int offY)
{
CWnd *pWnd=0;
int ID[]={IDOK,IDC_BUTTON1,IDCANCEL};
for(int jj=0;jj<sizeof(ID)/sizeof(int);jj++)
{
pWnd=GetDlgItem(ID[jj]);
CRect rc;
pWnd->GetWindowRect(&rc);
ScreenToClient(&rc);
rc.OffsetRect(offX,offY);
CRgn ctlRgn;
ctlRgn.CreateRectRgnIndirect(&rc);
rgn.CombineRgn(&rgn,&ctlRgn,RGN_XOR);
ctlRgn.DeleteObject();
}
}
void CTransDlgDlg::OnButton1()
{
// TODO: Add your control notification handler code here
static BOOL sw=FALSE;
if(!sw)
{
sw=TRUE;
CRect rcWin;
GetWindowRect(&rcWin);
CRect rcClt;
GetClientRect(&rcClt);
ClientToScreen(&rcClt);
//
rcClt.OffsetRect(-rcWin.left,-rcWin.top);
int offX=rcClt.left;
int offY=rcClt.top;
rcWin.OffsetRect(-rcWin.left,-rcWin.top);
//
CRgn tmp;
tmp.CreateRectRgnIndirect(&rcClt);
//
RgnSubtractCtrls(tmp,offX,offY);
//
CRgn rgn;
rgn.CreateRectRgnIndirect(&rcWin);
rgn.CombineRgn(&rgn, &tmp, RGN_DIFF);
SetWindowRgn(rgn,TRUE);
tmp.DeleteObject();
rgn.DeleteObject();
m_Trans.SetWindowText("不透明");
}
else
{
sw=FALSE;
SetWindowRgn(0,TRUE);
m_Trans.SetWindowText("透明");
}
}
void CTransDlgDlg::RgnSubtractCtrls(CRgn &rgn,int offX,int offY)
{
CWnd *pWnd=0;
int ID[]={IDOK,IDC_BUTTON1,IDCANCEL};
for(int jj=0;jj<sizeof(ID)/sizeof(int);jj++)
{
pWnd=GetDlgItem(ID[jj]);
CRect rc;
pWnd->GetWindowRect(&rc);
ScreenToClient(&rc);
rc.OffsetRect(offX,offY);
CRgn ctlRgn;
ctlRgn.CreateRectRgnIndirect(&rc);
rgn.CombineRgn(&rgn,&ctlRgn,RGN_XOR);
ctlRgn.DeleteObject();
}
}
#14
感谢两位大牛的回复~学习了。窗口透明,空间不透明的方法参照了论坛某贴控件使用SetParent()后即可对窗口和控件分别设置透明度,但是问题依然存在,即控件上的字符的透明度始终和控件本身透明度一致,无法达到帖子开始的控件也透明,但是控件上的字符不透明的效果。
#15
另外,还发现一个问题,win7下,完全相同的代码,在aero开关时,表现完全不一致。
如下图,使用aero主题,窗口设置了透明色,但是窗口依然能响应鼠标消息,控件也透明,但是控件上的字符不受影响。
同样的程序,在aero关闭时,如下图,鼠标直接透过窗口,而且控件也未透明
问题是,能否在非aero主题下使程序达到相同效果呢
如下图,使用aero主题,窗口设置了透明色,但是窗口依然能响应鼠标消息,控件也透明,但是控件上的字符不受影响。
同样的程序,在aero关闭时,如下图,鼠标直接透过窗口,而且控件也未透明
问题是,能否在非aero主题下使程序达到相同效果呢
#16
UpdateLayeredWindow+一个上层窗口
理论上可行
普通的情况 的确是可以的 因为我做过
想真的达到完美 就困难了 难点就是 如果背景是播放的某种格式的视频 可能就透不过去了 如果可以的话 放弃吧 我当时研究了很久 也没最终解决视频透明 在多种操作系统 多种视频格式的情况下 总会有例外 还有闪烁的情况 让人揪心 请果断放弃 不然必然有bug 包括迅雷那个半透的小窗口 在某些情况下都闪烁 或透不过去
理论上可行
普通的情况 的确是可以的 因为我做过
想真的达到完美 就困难了 难点就是 如果背景是播放的某种格式的视频 可能就透不过去了 如果可以的话 放弃吧 我当时研究了很久 也没最终解决视频透明 在多种操作系统 多种视频格式的情况下 总会有例外 还有闪烁的情况 让人揪心 请果断放弃 不然必然有bug 包括迅雷那个半透的小窗口 在某些情况下都闪烁 或透不过去
#17
#18
如果有什么办法让不打开aero时,效果和打开aero一样问题就解决了……
#19
inline BOOL SetWindowTransparent(HWND hwnd, BOOL bOpaque, UINT nAlpha)
{
// Check parameter
if (!::IsWindow(hwnd)) {
return FALSE;
}
// nAlpha needs between 0 and 255
if (nAlpha > 255) {
return FALSE;
}
if (bOpaque) {
// Set WS_EX_LAYERED on this window
SetWindowLong(hwnd,
GWL_EXSTYLE,
GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
// Make this window 70% alpha
::SetLayeredWindowAttributes(hwnd, 0, (255 * nAlpha) / 100, LWA_ALPHA);
} else {
// Remove WS_EX_LAYERED from this window styles
::SetWindowLong(hwnd,
GWL_EXSTYLE,
GetWindowLong(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
}
// Ask the window and its children to repaint
::RedrawWindow(hwnd,
NULL,
NULL,
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
return TRUE;
}
#20
#21
您好
我是本版版主
此帖已多日无人关注
请您及时结帖
如您认为问题没有解决可按无满意结帖处理
另外本版设置了 疑难问题汇总帖
并已在版面置顶
相关规定其帖子中有说明
您可以根据规定提交您帖子的链接
如您目前不想结帖只需回帖说明
我们会删除此结帖通知
见此回复三日内无回应
我们将强制结帖
相关规定详见界面 界面版关于版主结帖工作的具体办法
我是本版版主
此帖已多日无人关注
请您及时结帖
如您认为问题没有解决可按无满意结帖处理
另外本版设置了 疑难问题汇总帖
并已在版面置顶
相关规定其帖子中有说明
您可以根据规定提交您帖子的链接
如您目前不想结帖只需回帖说明
我们会删除此结帖通知
见此回复三日内无回应
我们将强制结帖
相关规定详见界面 界面版关于版主结帖工作的具体办法