子窗口的透明
来源:互联网 发布:后三组六计划软件 编辑:程序博客网 时间:2024/06/10 06:27
由于项目中要实现子窗口的透明的功能,在网上找到了这一段提示:
子窗口的透明和主窗口完全不同, 主窗口是通过layeredwindow实现的, 而子窗口则必须自己实现, 尤其是半透明, 必须自己对获取的透明背景图进行操作。 要实现子窗口的透明需要做到下面几步:
1. windows的ExStyle中需要包含WS_EX_TRANSPARENT属性
2. windows的Style中要去掉WS_CLIPSIBLING属性
3. 对继承自windows标准控件的子窗口( 比如edit, scrollbar等等 ), 需要截获WM_CTLCOLORxxx消息并返回一个style为BS_HOLLOW的brush的handle(即一个透明画刷的handle)
4. 需要截获WM_ERASEBKGND消息并不要清除背景(如果做到了3, 则这一步可以省略)
5. 最关键的一点(也是很多人没有想到或不知道的), 必须将parent窗口style中的WS_CLIPCHILDREN标志去掉, 否则PARENT窗口重画时不会重画被子窗口覆盖的部分.
6. 做到以上各步后, 在子窗口收到WM_PAINT消息时就可以获得完整的背景图了, 接下去对这背景进行处理就可以实现半透明效果.
另外一点, 最好同时截获parent窗的WM_PAINT消息, 在parent窗重画前调用InvalidateRect让本子窗口显示实效, 这样子窗口才能同样也收到一个WM_PAINT消息( 这样做是为了保险, 因为我不是很确定主窗口重画系统是否会自动给具有WS_EX_TRANSPARENT属性的子窗口同样发WM_PAINT ).
如果谁更好的实现方法,请告诉我
实现过程中,我没处理第二和第五提示。
我的部分代码如下:
void CWndTool::AlphaCompositeBmp(const HBITMAP& bmpFront,const HBITMAP& bmpBKGround, HBITMAP& bmpDest, int nAlpha)
{
ASSERT(bmpFront);
ASSERT(bmpBKGround);
CBitmap* pBmpFront = CBitmap::FromHandle(bmpFront);
CBitmap* pBmpBkGround = CBitmap::FromHandle(bmpBKGround);
CDC memDcFront;
CDC memDcBkGround;
CDC memDcDest;
BITMAP bmFront;
CDC* pDc = GetDC();
memDcFront.CreateCompatibleDC(pDc);
memDcDest.CreateCompatibleDC(pDc);
memDcBkGround.CreateCompatibleDC(pDc);
CBitmap* pOldBmpFront = memDcFront.SelectObject(pBmpFront);
pBmpFront->GetBitmap(&bmFront);
CBitmap* pOldBmpBkGround = memDcBkGround.SelectObject(pBmpBkGround);
if (m_pTmpDest)
{
delete m_pTmpDest;
m_pTmpDest = NULL;
}
m_pTmpDest = new CBitmap();
m_pTmpDest->CreateCompatibleBitmap(pDc, bmFront.bmWidth, bmFront.bmHeight);
CBitmap* pBmpDest = memDcDest.SelectObject(m_pTmpDest);
for (int i=0; i<bmFront.bmHeight; i++)
for (int j=0; j<bmFront.bmWidth; j++)
{
int rFront,gFront,bFront;
int rBkGround,gBkGround,bBkGround;
int rDest,gDest,bDest;
COLORREF crFront = memDcFront.GetPixel(j, i);
COLORREF bkRgb = memDcBkGround.GetPixel(j, i);
rFront = GetRValue(crFront);
gFront = GetGValue(crFront);
bFront = GetBValue(crFront);
rBkGround = GetRValue(bkRgb);
gBkGround = GetGValue(bkRgb);
bBkGround = GetBValue(bkRgb);
rDest = (rBkGround*nAlpha+rFront*(256-nAlpha))/256;
gDest = (gBkGround*nAlpha+gFront*(256-nAlpha))/256;
bDest = (bBkGround*nAlpha+bFront*(256-nAlpha))/256;
COLORREF crDest = RGB(rDest, gDest, bDest);
COLORREF crRet = memDcDest.SetPixel(j, i, crDest);
}
memDcFront.SelectObject(pOldBmpFront);
memDcBkGround.SelectObject(pOldBmpBkGround);
memDcDest.SelectObject(pBmpDest);
bmpDest = (HBITMAP)(m_pTmpDest->m_hObject);
}
void CWndTool::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CUIWnd::OnPaint() for painting messages
CRect rt;
GetClientRect(&rt);
CDC memDc;
memDc.CreateCompatibleDC(&dc);
CBitmap* pBmp = memDc.SelectObject(CBitmap::FromHandle(m_bmpDest));
dc.BitBlt(0, 0, rt.Width(), rt.Height(), &memDc, 0, 0, SRCCOPY);
memDc.SelectObject(pBmp);
}
void CWndTool::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_isOverWnd == FALSE)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_HOVER|TME_LEAVE;
tme.dwHoverTime = 1;
_TrackMouseEvent(&tme);
m_isOverWnd = TRUE;
}
CUIWnd::OnMouseMove(nFlags, point);
}
void CWndShowHeaderTool::OnTimer(UINT_PTR id)
{
if (id == TIMER_OVER_TOOLWND)
{
if (m_nTransparent < 55)
{
KillTimer(TIMER_OVER_TOOLWND);
return;
}
if (m_bmpDest)
{
DeleteObject(m_bmpDest);
m_bmpDest = NULL;
}
AlphaCompositeBmp(m_bmpFront, m_bmpBKGround, m_bmpDest, m_nTransparent);
Invalidate(FALSE);
UpdateWindow();
m_nTransparent -= 50;
}
if (id == TIMER_LEAVE_TOOLWND)
{
if (m_nTransparent > 255)
{
KillTimer(TIMER_LEAVE_TOOLWND);
return;
}
AlphaCompositeBmp(m_bmpFront, m_bmpBKGround, m_bmpDest, m_nTransparent);
Invalidate(FALSE);
UpdateWindow();
m_nTransparent += 50;
}
}
int CWndTool::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CUIWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
DWORD dwExStyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
dwExStyle |= WS_EX_TRANSPARENT;
SetWindowLong(m_hWnd, GWL_EXSTYLE, dwExStyle);
m_bmpFront = LoadBITMAPOBJ(CUIMgr::GetUIPathWithoutTitle()+_T("IDB_CHATWND_TOOL.bmp"));
m_bmpBKGround = LoadBITMAPOBJ(CUIMgr::GetUIPathWithoutTitle()+_T("IDW_CHAT_RIGHT_SHOW_HEADER.bmp"));
AlphaCompositeBmp(m_bmpFront, m_bmpBKGround, m_bmpDest, m_nTransparent);
return 0;
}
LRESULT CWndTool::OnMouseHover( WPARAM wParam, LPARAM lParam )
{
TRACE(_T("CWndShowHeaderTool::OnMouseHover %d/n"), IsMouseOver()?1:0);
if (m_bHaveOverTimer == TRUE)
{
return 0;
}
m_isOverWnd = true;
m_bHaveOverTimer = TRUE;
m_nTransparent = 255;
KillTimer(TIMER_LEAVE_TOOLWND);
SetTimer(TIMER_OVER_TOOLWND, 50, NULL);
return 0;
}
LRESULT CWndTool::OnMouseLeave( WPARAM wParam, LPARAM lParam )
{
TRACE(_T("CWndShowHeaderTool::OnMouseLeave %d/n"), IsMouseOver()?1:0);
KillTimer(TIMER_OVER_TOOLWND);
SetTimer(TIMER_LEAVE_TOOLWND, 50, NULL);
m_isOverWnd = false;
m_bHaveOverTimer = FALSE;
m_nTransparent = 55;
return 0;
}
- 子窗口的透明
- 子窗口透明
- VC实现顶层窗口的透明与实现子窗口的透明【重点:子窗口透明处理】
- 透明窗口的实现
- MFC为子窗口绘制透明背景
- windowsSDK利用子窗口控件设置窗口透明
- Qt 主窗口透明,子窗口不受影响--暴力方式
- QT 实现子控件的透明,可以实现主窗口设置背景皮肤
- 有关透明窗口的显示
- 透明、无窗口的Flash
- 局部透明窗口的实现
- MFC : 在主窗口不透明的情况下, 建立一个半透明的子窗体带透明的TreeCtrl
- 透明窗口
- 透明窗口
- 透明窗口
- 透明窗口
- 透明窗口
- 子窗口的调用;
- There is not a header with name ServiceContext and namespace http://schemas.microsoft.com/sharepoint/servicecontext in the messa
- 关于链表的blog
- 简单方式查看 Oracle 索引扫描方式
- MFC消息映射(研究中)
- javascript日历实现
- 子窗口的透明
- PSpice分析类型
- 获取页面中某Table的高度
- 让关机按钮显示“休眠”按钮
- asp.net页面中 回车触发提交事件
- 在线测试写BLOG
- Oracle 存储过程中发送邮件,并支持用户验证、中文标题和内容
- mysql数据安全与备份
- 传智播客Hibernate视频教程学习笔记33