子窗口的透明

由于项目中要实现子窗口的透明的功能,在网上找到了这一段提示:

子窗口的透明和主窗口完全不同,   主窗口是通过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;
}

 

from:http://blog.csdn.net/zhuzhubin/article/details/4418653
 

时间: 2024-11-05 06:26:50

子窗口的透明的相关文章

MDI 窗口在打开一个子窗口同时关闭已经打开的子窗口时,子窗口上 datagridview 中的列标题刷新的问题

问题描述 在MDI窗口中打开一个带有datagridview控件的子窗口,同时关闭另一个已经打开的带有datagridview控件的子窗口时出现datagridview中的列标题中含有已关闭子窗口中datagridview的列标题,如下图.使用的VS版本为VS2010旗舰中文版,datagridview在窗口load事件中绑定数据源.打开一个子窗口,同时关闭已打开子窗口的代码如下privateconsumerf_consumer;privatevoidConsumerToolStripMenuI

ie 8-js子窗口关闭刷新父窗口

问题描述 js子窗口关闭刷新父窗口 使用window.showModalDialog("uploadFile.jsp",null,"dialogWidth=400px;dialogHeight=250px"); 方式弹出的一个子窗口, 我需要用子窗口控制刷新父窗口然后关闭子窗口, window.parent.dialogArguments.document.execCommand('Refresh'); window.close(); ie8下执行不成功 解决方案

asp.net-wpf 怎么让嵌套子窗口 最大化

问题描述 wpf 怎么让嵌套子窗口 最大化 主面板有四个子窗口,点击某一个里面的按钮实现最大化 解决方案 windowsstate=maxmized 解决方案二: 子页面是Page页面,木有windowsstate

iframe如何获取子窗口单选框的value

问题描述 iframe如何获取子窗口单选框的value iframe如何获取子窗口单选框的value iframe如何获取子窗口单选框的value iframe如何获取子窗口单选框的value iframe如何获取子窗口单选框的value iframe如何获取子窗口单选框的value iframe如何获取子窗口单选框的value 解决方案 http://blog.csdn.net/xing_sky/article/details/8519520 解决方案二: iframe和父页,window.o

jQuery父窗口与子窗口通信

$("#父窗口元素ID",window.parent.document);  对应javascript版本为window.parent.document.getElementByIdx_x("父窗口元素ID"): 取父窗口的元素方法:$(selector, window.parent.document); 那么你取父窗口的父窗口的元素就可以用:$(selector, window.parent.parent.document); 类似的,取其它窗口的方法大同小异 $

一种打开子窗口的方法[父页内创建子窗口]

创建|子窗口 <html> <head> <title>Test</title><script>function openSubWin()   {   subWindow=window.open("", "newwin", "height=250, width=250,toolbar=no ,scrollbars="+scroll+",menubar=no");   

JavaScript实际应用:子窗口和父窗口交互

javascript|父窗口|交互|子窗口 最近项目开发中需要子窗口和父窗口交互的内容,基本上无非就是把子窗口的信息传递给父窗口,并且关闭自己等等,或者是父窗口把自己的信息传递给子窗口等等. 1.父窗口传递信息给子窗口 看代码实例:<script language=javascript> function outPut(){ //获取父窗口的文本信息赋值给text var text = document.abc.text.value; //打开子窗口,并且把操作句柄赋值给win变量,以下所有操

分析一下网页子窗口和网页父窗口的交互

父窗口|交互|网页|子窗口 1.父窗口传递信息给子窗口 看代码实例: <script language=javascript>function outPut()...{ //获取父窗口的文本信息赋值给text var text = document.abc.text.value; //打开子窗口,并且把操作句柄赋值给win变量,以下所有操作都是针对win对象的 var win = window.open("","mywin", "menubar

C#中父窗口和子窗口之间实现控件互操作

父窗口|控件|子窗口 很多人都苦恼于如何在子窗体中操作主窗体上的控件,或者在主窗体中操作子窗体上的控件.相比较而言,后面稍微简单一些,只要在主窗体中创建子窗体的时候,保留所创建子窗体对象即可. 下面重点介绍前一种,目前常见的有两种方法,基本上大同小异: 第一种,在主窗体类中定义一个静态成员,来保存当前主窗体对象,例如: public static yourMainWindow pCurrentWin = null; 然后在主窗体构造函数中,给静态成员初始化,如下: pCurrentWin = t