vc 实现透明窗口和不规则窗口

来源:互联网 发布:淘宝大学在哪里 编辑:程序博客网 时间:2024/05/16 06:25

做一个vc项目的时候,用到了不规则-透明窗口,中间走了几个弯路,在此总结一下:

相关的函数:

1

int SetWindowRgn(  HWND hWnd,     // handle to window  HRGN hRgn,     // handle to region  BOOL bRedraw   // window redraw option);
这个函数,没有太多的限制,只要hRgn正确,效果就会出现,但是有个缺点,就是使用该函数制作的不规则窗口可能出现锯齿
示例:
HRGN hRgn = CreateEllipticRgn(0,0,100,100);SetWindowRgn(hwnd, hRgn, TRUE);
 
2 
BOOL SetLayeredWindowAttributes(      
    HWND hwnd,    COLORREF crKey,    BYTE bAlpha,    DWORD dwFlags);
这个函数限制较大,它只能用于非child窗口,适合于背景为png图片的不规则窗口,同样可能会有锯齿出现,但是可以放控件。
示例,原始效果:
执行

// Set WS_EX_LAYERED on this window  SetWindowLong(hwnd,   GWL_EXSTYLE,   GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);

 // Make this window 70% alpha SetLayeredWindowAttributes(hwnd, RGB(255,255,255),  (255 * 70) / 100, LWA_ALPHA|LWA_COLORKEY);

效果:

 
3 
BOOL UpdateLayeredWindow(          HWND hwnd,    HDC hdcDst,    POINT *pptDst,    SIZE *psize,    HDC hdcSrc,    POINT *pptSrc,    COLORREF crKey,    BLENDFUNCTION *pblend,    DWORD dwFlags);
这个函数同样可以实现透明-不规则窗口,但是同样只适用于非child窗口,但是它可以抗锯齿。
由于该函数改变了窗口的绘制机制,因此使用了该函数的窗口是不会收到WM_PAINT消息的,因此无法放置控件。
示例:
Image image(L"apple.png"); Bitmap bitmap(100,100); Graphics tg(&bitmap); tg.Clear(Color(0,255, 255, 255)); tg.DrawImage(&image, Rect(0,0,100,100),  0,0,image.GetWidth(), image.GetHeight(), UnitPixel); HBITMAP hBitmap = NULL; bitmap.GetHBITMAP(Color(0,0,0), &hBitmap); HDC hdc = GetDC(hwnd); HDC hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, hBitmap); POINT ptDest = {0,0}; POINT ptSrc = {0,0}; SIZE size = {100,100}; BLENDFUNCTION blend; blend.AlphaFormat = AC_SRC_ALPHA; blend.BlendFlags = 0; blend.BlendOp = AC_SRC_OVER; blend.SourceConstantAlpha = 255 * 70 / 100;SetWindowLong(hwnd,   GWL_EXSTYLE,   GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); UpdateLayeredWindow(hwnd, hdc, &ptDest, &size,   hdcMem, &ptSrc, RGB(0,0,0), &blend, LWA_ALPHA|LWA_COLORKEY); DeleteDC(hdcMem); ReleaseDC(hwnd, hdc);
 效果:
0 0