原创文章,转载注明出处:
方法一://会闪烁,会刷新窗口;
网上有很多窗口透明的方法,大多都差不多,不过还是有很多人没有完全会用,这里我整理一下,写了一个函数:
窗口透明有两种情况,一种是鼠标可以透过窗口,一种是鼠标不可以透过窗口;
void TransparentWnd( CWnd * PW = NULL /*透明窗口指针*/, int nisLeakDlg = 1 /*透明方式*/ , int iTransparencyDlg = 100 /*透明度,bisLeakDlg 为指定颜色全透明时无效;*/ )
{
CClientDC toumingdc( PW );
COLORREF maskColor = RGB(0,0,0); //当然可以指定透明颜色;
maskColor = toumingdc.GetPixel(0,0); //将透明颜色设置为窗口颜色;
#define LWA_COLORKEY 0x00000001
#define WS_EX_LAYERED 0x00080000
typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
lpfnSetLayeredWindowAttributes SetLayeredWindowAttributes;
HMODULE hUser32 = GetModuleHandleW(L"user32.dll");
SetLayeredWindowAttributes = (lpfnSetLayeredWindowAttributes)GetProcAddress(hUser32,"SetLayeredWindowAttributes");
SetWindowLong( PW->GetSafeHwnd(), GWL_EXSTYLE,
GetWindowLong( PW->GetSafeHwnd(), GWL_EXSTYLE) | WS_EX_LAYERED);
if (nisLeakDlg==1)
{
SetLayeredWindowAttributes( PW->GetSafeHwnd(), maskColor, iTransparencyDlg, LWA_COLORKEY ); //指定颜色透明;
}
if (nisLeakDlg==2)
{
SetLayeredWindowAttributes( PW->GetSafeHwnd(), maskColor, iTransparencyDlg, LWA_ALPHA );//设置透明度;
}
if (nisLeakDlg==3)
{
SetLayeredWindowAttributes( PW->GetSafeHwnd(), maskColor, iTransparencyDlg, LWA_ALPHA|LWA_COLORKEY );// 3 = 1+2;
}
FreeLibrary(hUser32);
}
void C窗口透明Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
// Initialize GDI+.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Graphics graphics(this->m_hWnd);
Image img(L"G:\\t.bmp");
graphics.DrawImage(&img,10,10, 50,50);
graphics.DrawLine(&Pen(Color::Black),Point(10,10), Point(1000,1000) );
//1:
TransparentWnd(this,1,100);
//2:
//TransparentWnd(this,2,100);
//3:
//TransparentWnd(this,3,100);
}
//方法二:
#include <GdiPlus.h>
using namespace Gdiplus;
HBITMAP CreateDIBCompatibleBitmap( HDC hdc, int nWidth, int nHeight )
{
BYTE * pBits ;
BITMAPINFOHEADER bmih;
ZeroMemory( &bmih, sizeof( BITMAPINFOHEADER ) );
bmih.biSize = sizeof( BITMAPINFOHEADER );
bmih.biWidth = nWidth;
bmih.biHeight = nHeight;
bmih.biPlanes = 1 ;
bmih.biBitCount = 32;//这里一定要是32
bmih.biCompression = BI_RGB ;
bmih.biSizeImage = 0 ;
bmih.biXPelsPerMeter = 0 ;
bmih.biYPelsPerMeter = 0 ;
bmih.biClrUsed = 0 ;
bmih.biClrImportant = 0 ;
HBITMAP hBitMap = CreateDIBSection( hdc, ( BITMAPINFO * )&bmih, 0, ( VOID** )&pBits, NULL, 0 );
return hBitMap;
}
BOOL TransparentWindow( CWnd * pWnd, bool bDrawErasePath, int nSourceConstantAlpha = 255, COLORREF TransparentRGB = RGB(0,0,0), int nstyle = 1 )
{
/*
pWnd : 指定透明窗口指针;
bDrawErasePath : 是否绘图;
nSourceConstantAlpha : 半透明度; //nstyle = 2 该参数无效;
TransparentRGB : 指定全透明颜色;// nstyle = 1 该参数无效;
nstyle : 指定透明方式;
*/
CRect rectWnd;
::GetClientRect(pWnd->m_hWnd, &rectWnd);
int nWndWidthForMemdc = rectWnd.Width();
int nWndHeightForMemdc = rectWnd.Height();
BOOL bRet = TRUE;
HDC hdcScreen = ::GetDC(pWnd->m_hWnd);
HDC hdcMemory = CreateCompatibleDC( hdcScreen );
// HBITMAP hBitMap = CreateCompatibleBitmap( hdcScreen, m_nWndWidth, m_nWndHeight );
HBITMAP hBitMap = CreateDIBCompatibleBitmap( hdcScreen, nWndWidthForMemdc, nWndHeightForMemdc );
SelectObject( hdcMemory, hBitMap );
BLENDFUNCTION oBlend;
oBlend.BlendOp = 0; //theonlyBlendOpdefinedinWindows2000
oBlend.BlendFlags = 0; //nothingelseisspecial...
oBlend.AlphaFormat = 1; //...
oBlend.SourceConstantAlpha = nSourceConstantAlpha;//0~255//AC_SRC_ALPHA//可见图像透明度(其余地方透明);
Graphics graphics( hdcMemory );
if ( bDrawErasePath ) //绘图;
{
//graphics.Clear( Color::Black );
Pen pen( Color::Black );
graphics.ResetTransform();
graphics.DrawLine(&pen,Point(0,0), Point(1000,1000) );
Image img(L"G:\\t.bmp");
graphics.DrawImage(&img,0,0,50,50);
}
//
POINT ptSrc = { 0, 0 };
RECT rct={0};
pWnd->GetWindowRect( &rct );
POINT ptWinPos = { rct.left, rct.top };
SIZE sizeWindow = { nWndWidthForMemdc, nWndHeightForMemdc };
DWORD dwExStyle=GetWindowLong(pWnd->m_hWnd,GWL_EXSTYLE);
if((dwExStyle&0x80000)!=0x80000)
SetWindowLong(pWnd->m_hWnd,GWL_EXSTYLE,dwExStyle^0x80000);
if (nstyle == 1)
{
bRet = ::UpdateLayeredWindow( pWnd->m_hWnd, hdcScreen, &ptWinPos, &sizeWindow, hdcMemory, &ptSrc, TransparentRGB, &oBlend, ULW_ALPHA );
}
if (nstyle == 2)
{
bRet = ::UpdateLayeredWindow( pWnd->m_hWnd, hdcScreen, &ptWinPos, &sizeWindow, hdcMemory, &ptSrc, TransparentRGB, &oBlend, LWA_COLORKEY );
}
if (nstyle==3)
{
bRet = ::UpdateLayeredWindow( pWnd->m_hWnd, hdcScreen, &ptWinPos, &sizeWindow, hdcMemory, &ptSrc, TransparentRGB, &oBlend, ULW_ALPHA|LWA_COLORKEY );
}
graphics.ReleaseHDC( hdcMemory );
DeleteDC( hdcMemory );
DeleteObject( hBitMap );
::ReleaseDC( pWnd->m_hWnd, hdcScreen );
return bRet;
}
void C窗口透明Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
//
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
// Initialize GDI+.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
//这种方式透明,绘出的dc不闪烁;
static int i = 1;
i = i+50;
TransparentWindow( this, true, i, RGB(0,0,0), 1 );
// TransparentWindow( this, true, 100, RGB(0,0,0), 2 );
// TransparentWindow( this, true, i, RGB(0,0,0),3 );
}
//注意:UpdateLayeredWindow和SetLayeredWindowAttributes;