如何使MFC 子窗体半透明

时间:2021-04-12 11:45:55
使用SetLayeredWindowAttributes  不行,网上查了较多资料,发现都是使用该函数去设置的,但是这个对于子窗体根本无效,看到有位大哥重绘窗口 ,链接如下http://blog.csdn.net/dsg333/article/details/9990419 但是效果不行,完全达不到效果,请问哪位大神解决了该问题?

7 个解决方案

#2


UpdateLayeredWindow

至少win8,子窗口才有效

#3


void CAlphaBlend::SetTransparent(BOOL bTransparent)
{
if (bTransparent)
{
// make sure they have set it up properly
ASSERT(m_nOpacity >= 0 && m_nOpacity <= 255);
ASSERT(m_hWnd && ::IsWindow(m_hWnd));

// make it transparent
long l = GetWindowLong(m_hWnd, GWL_EXSTYLE);
l |= WS_EX_LAYERED;
SetWindowLong(m_hWnd, GWL_EXSTYLE, l);
SetLayeredWindowAttributes(m_hWnd, 0, m_nOpacity, LWA_ALPHA);

m_bTransparent = true;
}
else
{
long l = GetWindowLong(m_hWnd, GWL_EXSTYLE);
l ^= WS_EX_LAYERED;
SetWindowLong(m_hWnd, GWL_EXSTYLE, l);
CRect r;
::GetWindowRect(m_hWnd, r);
::InvalidateRect(m_hWnd, r, true);

m_bTransparent = false;
}
}

#4


顶,不能这样沉了啊,这是个技术难题

#5


#define WS_EX_LAYERED 0x00080000
#define LWA_ALPHA     0x00000002

typedef BOOL (WINAPI *LPFNSETLAYEREDWINDOWATTRIBUTES)
(HWND hwnd,COLORREF crKey,BYTE bAlpha,DWORD dwFlags) ;

//设置窗口的透明度 hwnd是被设置的窗口 byAlpha是指示了透明度(0完全透明 255完全不透明)
BOOL TransparentWnd(HWND hwnd, BYTE byAlpha)
{
     long lStyle;
     HMODULE hModule;
     BOOL bRet;
     LPFNSETLAYEREDWINDOWATTRIBUTES lpSetLayeredWindowAttributes;
     if(FALSE == IsWindow(hwnd))
     {
          MessageBox(NULL, TEXT("窗口句柄无效!"), NULL, 0) ;
          return FALSE ;
     }
     hModule = (HMODULE)LoadLibrary(TEXT("user32.dll")) ;
     if(hModule)
     {
          lpSetLayeredWindowAttributes = (LPFNSETLAYEREDWINDOWATTRIBUTES)
          GetProcAddress(hModule, TEXT("SetLayeredWindowAttributes")) ;
          if(!lpSetLayeredWindowAttributes)
          {
               MessageBox(hwnd, TEXT("未找到API SetLayeredWindowAttributes的地址!"),
               NULL, MB_OK) ;
               return FALSE ;
          }
     }
     lStyle = GetWindowLong(hwnd, GWL_EXSTYLE) ; 
     if(!lStyle)
     {
          MessageBox(hwnd, TEXT("获取窗口扩展样式失败!"), NULL, MB_OK) ;
          return FALSE ;
     }
     lStyle = lStyle | WS_EX_LAYERED ;
     bRet = SetWindowLong(hwnd, GWL_EXSTYLE, lStyle) ;
     if(!bRet)
     {
          MessageBox(hwnd, TEXT("设置窗口扩展样式失败!"), NULL, MB_OK) ;
          return FALSE ;
     }
     bRet = lpSetLayeredWindowAttributes(hwnd, 0, byAlpha, LWA_ALPHA) ;
     if(!bRet)
     {
          MessageBox(hwnd, TEXT("设置窗口透明度失败!"), NULL, MB_OK) ;
          return FALSE ;
     }
     RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN) ;
     FreeLibrary(hModule) ;
     return TRUE ;
}

#6


你连子控件都要半透明,确实麻烦,如果上面控件不多,控件也子类化一下,然后重置OnEraseBkgnd就可以了。

#7


这个解决不了,结贴!

#1


#2


UpdateLayeredWindow

至少win8,子窗口才有效

#3


void CAlphaBlend::SetTransparent(BOOL bTransparent)
{
if (bTransparent)
{
// make sure they have set it up properly
ASSERT(m_nOpacity >= 0 && m_nOpacity <= 255);
ASSERT(m_hWnd && ::IsWindow(m_hWnd));

// make it transparent
long l = GetWindowLong(m_hWnd, GWL_EXSTYLE);
l |= WS_EX_LAYERED;
SetWindowLong(m_hWnd, GWL_EXSTYLE, l);
SetLayeredWindowAttributes(m_hWnd, 0, m_nOpacity, LWA_ALPHA);

m_bTransparent = true;
}
else
{
long l = GetWindowLong(m_hWnd, GWL_EXSTYLE);
l ^= WS_EX_LAYERED;
SetWindowLong(m_hWnd, GWL_EXSTYLE, l);
CRect r;
::GetWindowRect(m_hWnd, r);
::InvalidateRect(m_hWnd, r, true);

m_bTransparent = false;
}
}

#4


顶,不能这样沉了啊,这是个技术难题

#5


#define WS_EX_LAYERED 0x00080000
#define LWA_ALPHA     0x00000002

typedef BOOL (WINAPI *LPFNSETLAYEREDWINDOWATTRIBUTES)
(HWND hwnd,COLORREF crKey,BYTE bAlpha,DWORD dwFlags) ;

//设置窗口的透明度 hwnd是被设置的窗口 byAlpha是指示了透明度(0完全透明 255完全不透明)
BOOL TransparentWnd(HWND hwnd, BYTE byAlpha)
{
     long lStyle;
     HMODULE hModule;
     BOOL bRet;
     LPFNSETLAYEREDWINDOWATTRIBUTES lpSetLayeredWindowAttributes;
     if(FALSE == IsWindow(hwnd))
     {
          MessageBox(NULL, TEXT("窗口句柄无效!"), NULL, 0) ;
          return FALSE ;
     }
     hModule = (HMODULE)LoadLibrary(TEXT("user32.dll")) ;
     if(hModule)
     {
          lpSetLayeredWindowAttributes = (LPFNSETLAYEREDWINDOWATTRIBUTES)
          GetProcAddress(hModule, TEXT("SetLayeredWindowAttributes")) ;
          if(!lpSetLayeredWindowAttributes)
          {
               MessageBox(hwnd, TEXT("未找到API SetLayeredWindowAttributes的地址!"),
               NULL, MB_OK) ;
               return FALSE ;
          }
     }
     lStyle = GetWindowLong(hwnd, GWL_EXSTYLE) ; 
     if(!lStyle)
     {
          MessageBox(hwnd, TEXT("获取窗口扩展样式失败!"), NULL, MB_OK) ;
          return FALSE ;
     }
     lStyle = lStyle | WS_EX_LAYERED ;
     bRet = SetWindowLong(hwnd, GWL_EXSTYLE, lStyle) ;
     if(!bRet)
     {
          MessageBox(hwnd, TEXT("设置窗口扩展样式失败!"), NULL, MB_OK) ;
          return FALSE ;
     }
     bRet = lpSetLayeredWindowAttributes(hwnd, 0, byAlpha, LWA_ALPHA) ;
     if(!bRet)
     {
          MessageBox(hwnd, TEXT("设置窗口透明度失败!"), NULL, MB_OK) ;
          return FALSE ;
     }
     RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN) ;
     FreeLibrary(hModule) ;
     return TRUE ;
}

#6


你连子控件都要半透明,确实麻烦,如果上面控件不多,控件也子类化一下,然后重置OnEraseBkgnd就可以了。

#7


这个解决不了,结贴!