窗体透明,控件透明问题

乡客2023 2012-02-15 03:59:40
父窗口上贴了PNG图,需要crate几个窗口在父窗口上,请问如何实现窗体透明,控件透明,效果是:create出的对话框看上去像是在父窗口中,能看到背景上的东东!
...全文
198 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
乡客2023 2012-02-21
  • 打赏
  • 举报
回复
谢谢各位帮忙!!
不说害怕 2012-02-19
  • 打赏
  • 举报
回复
这个好复杂啊.
SKINSE界面库 2012-02-19
  • 打赏
  • 举报
回复
1:在绘制父窗口的时候,把父窗口的背景用个位图存起来;
2:在绘制子窗口的时候,父窗口保存的背景位图的子窗口在父窗口的区域位置会知道子窗口中。
这样子实现了看起来,透明。
SKINSE界面库内部都是这样子处理的,有兴趣的朋友可以去下载来看看:http://www.skinse.com
这里我给出绘制的相关代码,代码:
BOOL CSkinWndManager::OnDrawBack(HWND hwnd, HDC hSrcDC, CSkinRect rect, int nAlpha/* =255 */)
{
CSkinBase* pParentBase = (CSkinBase*)::GetProp(::GetParent(hwnd),PROP_WNDPROC);
if ( !pParentBase )
{
CSkinBase* pItemBase = (CSkinBase*)::GetProp(hwnd, PROP_WNDPROC);
if ( pItemBase && pItemBase->m_bIsWindow )
{
::SetBkColor(hSrcDC, ((CSkinWndSB*)pItemBase)->m_clrBackground);
::ExtTextOut(hSrcDC, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);
return TRUE;
}
else
{
pItemBase = (CSkinBase*)::GetProp(::GetParent(::GetParent(hwnd)), PROP_WNDPROC);
if ( pItemBase && pItemBase->m_bIsWindow )
{
::SetBkColor(hSrcDC, ((CSkinWndSB*)pItemBase)->m_clrBackground);
::ExtTextOut(hSrcDC, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);
return TRUE;
}
}

::SetBkColor(hSrcDC, ::GetSysColor(COLOR_3DFACE));
::ExtTextOut(hSrcDC, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);
return FALSE;
}

if ( !pParentBase->m_bIsWindow )
{
CSkinBase* pParentParentBase = (CSkinBase*)::GetProp(::GetParent(::GetParent(hwnd)), PROP_WNDPROC);
if ( pParentParentBase && pParentParentBase->m_bIsWindow )
{
CSkinWndSB* pParentSB = (CSkinWndSB*)pParentParentBase;

CSkinPoint point(rect.TopLeft());
::ClientToScreen(hwnd,&point);
::ScreenToClient(pParentSB->m_hWnd,&point);

//绘制背景色
::SetBkColor(hSrcDC, pParentSB->m_clrBackground);
::ExtTextOut(hSrcDC, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);

//绘制背景图片
if ( !pParentSB->m_bitmapCompatible )
{
return TRUE;
}

HDC dctmp;
dctmp = ::CreateCompatibleDC(hSrcDC);
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(dctmp,pParentSB->m_bitmapCompatible);
if ( nAlpha == 255 )
{
::BitBlt(hSrcDC,rect.left,rect.top,rect.Width(),rect.Height(),dctmp,point.x,point.y,SRCCOPY);
}
else
{
BLENDFUNCTION blendFunction;
blendFunction.BlendOp = AC_SRC_OVER;
blendFunction.BlendFlags = NULL;
blendFunction.AlphaFormat = AC_SRC_ALPHA;
blendFunction.SourceConstantAlpha = nAlpha;
::AlphaBlend(hSrcDC, rect.left, rect.top, rect.Width(), rect.Height(), dctmp, point.x, point.y, rect.Width(), rect.Height(), blendFunction);
}
::SelectObject(dctmp,hOldBitmap);
::DeleteDC(dctmp);
::DeleteObject(hOldBitmap);

}
else
{
::SetBkColor(hSrcDC, m_clrComBackground);
::ExtTextOut(hSrcDC, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);
}

return TRUE;
}

CSkinWndSB* pParentSB = (CSkinWndSB*)pParentBase;

CSkinPoint point(rect.TopLeft());
::ClientToScreen(hwnd,&point);
::ScreenToClient(pParentSB->m_hWnd,&point);

//绘制背景色
::SetBkColor(hSrcDC, pParentSB->m_clrBackground);
::ExtTextOut(hSrcDC, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);

//绘制背景图片
if ( !pParentSB->m_bitmapCompatible )
{
// ::SelectObject(hSrcDC, pParentSB->m_hBackgroundBrush);
// ::PatBlt(hSrcDC, 0, 0, rect.Width(), rect.Height(), PATCOPY);
return FALSE;
}

HDC dctmp;
dctmp = ::CreateCompatibleDC(hSrcDC);
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(dctmp,pParentSB->m_bitmapCompatible);
if ( nAlpha == 255 )
{
::BitBlt(hSrcDC,rect.left,rect.top,rect.Width(),rect.Height(),dctmp,point.x,point.y,SRCCOPY);
}
else if ( nAlpha >= 0 )
{
BLENDFUNCTION blendFunction;
blendFunction.BlendOp = AC_SRC_OVER;
blendFunction.BlendFlags = NULL;
blendFunction.AlphaFormat = AC_SRC_OVER;
blendFunction.SourceConstantAlpha = nAlpha;
::AlphaBlend(hSrcDC, rect.left, rect.top, rect.Width(), rect.Height(), dctmp, point.x, point.y, rect.Width(), rect.Height(), blendFunction);
}

::SelectObject(dctmp,hOldBitmap);
::DeleteDC(dctmp);
::DeleteObject(hOldBitmap);

return TRUE;
}
楚男人dh哦 2012-02-17
  • 打赏
  • 举报
回复
[Quote=引用楼主 wny198816 的回复:]
父窗口上贴了PNG图,需要crate几个窗口在父窗口上,请问如何实现窗体透明,控件透明,效果是:create出的对话框看上去像是在父窗口中,能看到背景上的东东!
[/Quote]

你创建的窗口不能是你想看到背景的感觉是父窗口的那个窗口

因为子窗口不支持半透明

处理你感觉到是父窗口的那个窗口的wm_size wm_move消息 让创建的窗口在以上消息发生的时候 跟着movewindow 是相对屏幕 不是你想看到背景的那个窗口
乡客2023 2012-02-16
  • 打赏
  • 举报
回复
Popup 为什么在父窗口上鼠标移动会闪呀???
zgszft 2012-02-16
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wny198816 的回复:]

Popup 为什么在父窗口上鼠标移动会闪呀???
[/Quote]
这应该涉及到与楼主标题无关的问题了。。。。。
楼主的背景是如何绘制的?
zgszft 2012-02-15
  • 打赏
  • 举报
回复
刚才那个是popup,如果在子级的话,可以在刷完背景后再更新控件
zgszft 2012-02-15
  • 打赏
  • 举报
回复
ModifyStyleEx(0, WS_EX_LAYERED);
HINSTANCE hInst = LoadLibrary("User32.DLL");
if(hInst)
{
typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD);
MYFUNC fun = NULL;
//取得SetLayeredWindowAttributes()函数指针
fun=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");
if(fun)fun(this->GetSafeHwnd(),0,220,2);
FreeLibrary(hInst);
}
乡客2023 2012-02-15
  • 打赏
  • 举报
回复
popup可以通过分层实现透明?能不能具体些?
乡客2023 2012-02-15
  • 打赏
  • 举报
回复
楼上朋友可以说明白点吗?child时
BOOL CPerson::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
return TRUE;
//return CDialog::OnEraseBkgnd(pDC);
}
有些控件透明了,但是刷新出问题

popup时刷新没问题可以怎么才能实现这个窗口为透明呢?困拢好几天了
zgszft 2012-02-15
  • 打赏
  • 举报
回复
popup可以通过分层实现透明,甚至可以使用Aero。当然,如果非要child的话可以把子对话所占父对话区域的图像弄下来贴到子对话背景里
dahaiI0 2012-02-15
  • 打赏
  • 举报
回复
popup窗口可以实现

15,978

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧