【Demo 0046】可穿透的窗体
本例我们学习另一个操作层窗体的函数, UpdateLayeredWindow 这个函数前几节中讲述的SetLayeredWindow功能更强大一些,它不仅可以显示实现SetLayeredWindow的Colorkey以及Alpha功能外还支持带有不同通道的图从而实现一些部分透明或阴影的功能, 这部分内容我们将会在后继章节中学习。
一. API 学习
BOOL UpdateLayeredWindow(
HWND hwnd, // 带有WS_EX_LAYERED扩展属性的窗体(CreateWindowEx时设置或后期用SetWindowLongPtr设置GWL_EXSTYLE设置) HDC hdcDst, // 本窗体DC POINT *pptDst, // 窗体的位置 SIZE *psize, // 窗体的大小 HDC hdcSrc, // 原DC句柄(一般我们将BITMAP 选入到此DC中, 本函数将从此DC中读取bitmap信息) POINT *pptSrc, // 拷贝数据(可间接理解为BITMAP) 的起始位置 COLORREF crKey, // 当dwFlags 为ULW_COLORKEY时需过滤掉的颜色值 BLENDFUNCTION *pblend, // 主要用于两个混合操作 DWORD dwFlags // 窗体与此DC(可间接理解为BITMAP)混合操作(ULW_COLORKEY, ULW_ALPHA, ULW_OPAQUE) );
二. 代码演示
1. 设置窗体WS_EX_LAYERED属性;
2. 创建一个窗体DC以及源DC并将图片(无通道)选入源DC中;
3. 调用UpdateLayeredWindow函数进入混合.
SetWindowLongPtr(hWnd, GWL_EXSTYLE, GetWindowLongPtr(hWnd, GWL_EXSTYLE)|WS_EX_LAYERED);
RECT rtClient;
GetClientRect(hWnd, &rtClient);
HDC hDC = GetDC(hWnd);
HDC hMemDC = CreateCompatibleDC(hDC);
HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, hBitmap);
POINT ptSrc = {0, 0};
POINT ptPos = {rtClient.left, rtClient.top};
SIZE szSize = {rtClient.right - rtClient.left, rtClient.bottom - rtClient.top};
BLENDFUNCTION blend = { AC_SRC_OVER, 0, 250, AC_SRC_ALPHA };
UpdateLayeredWindow(hWnd, hDC, &ptPos, &szSize, hMemDC, &ptSrc, RGB(255,0,0), &blend, ULW_ALPHA|ULW_COLORKEY);
SelectObject(hMemDC, hOldBmp);
DeleteObject(hMemDC);
ReleaseDC(hWnd, hDC);
RECT rtClient;
GetClientRect(hWnd, &rtClient);
HDC hDC = GetDC(hWnd);
HDC hMemDC = CreateCompatibleDC(hDC);
HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, hBitmap);
POINT ptSrc = {0, 0};
POINT ptPos = {rtClient.left, rtClient.top};
SIZE szSize = {rtClient.right - rtClient.left, rtClient.bottom - rtClient.top};
BLENDFUNCTION blend = { AC_SRC_OVER, 0, 250, AC_SRC_ALPHA };
UpdateLayeredWindow(hWnd, hDC, &ptPos, &szSize, hMemDC, &ptSrc, RGB(255,0,0), &blend, ULW_ALPHA|ULW_COLORKEY);
SelectObject(hMemDC, hOldBmp);
DeleteObject(hMemDC);
ReleaseDC(hWnd, hDC);
三. 效果
窗体显示成不规则透明状态, 我们的鼠标可以穿过此窗体操作上下面的窗体;
记得以前超级解霸那个软件具有屏幕上电影的功能,这样可以一点看电影一边操作其他软件, 我们可以用这个方法来实现同样的操作。
思路: 1. 窗体设置最顶层、工具类、层窗体属性; 2. 将每一帧图像图像做为数据源选入源DC中; 3. 调用此函数即可