C++ 异形窗口

编程入门 行业动态 更新时间:2024-10-26 06:25:34

C++ <a href=https://www.elefans.com/category/jswz/34/1733542.html style=异形窗口"/>

C++ 异形窗口

本文参考:Duilib源码

原理:分层窗口,通过定时器和手动触发绘画窗口
由于GDI对透明通道支持不是很好,最好选择GDI+进行绘画。

1.设置窗口属性WS_EX_LAYERED和绘画定时器
 DWORD dwStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE);SetWindowLong(hWnd, GWL_EXSTYLE, dwStyle | WS_EX_LAYERED);::SetTimer(hWnd, LAYEREDUPDATE_TIMERID, 10L, NULL);
2.UpdateLayeredWindow绘画窗口并且支持透明度设置
void onPaint()
{if (::IsIconic(hWnd))return 0;RECT rtWindow;GetWindowRect(hWnd, &rtWindow);COLORREF *pOffscreenBits = NULL;PAINTSTRUCT ps;HDC hdc = BeginPaint(hWnd, &ps);HDC hDcOffscreen = ::CreateCompatibleDC(hdc);//创建支持透明通道的BITMAP,pOffscreenBits位图的起始位置,默认色值为ARGB。默认值为0HBITMAP hbmpOffscreen = CreateARGB32Bitmap(hdc, rtWindow.right - rtWindow.left, rtWindow.bottom - rtWindow.top, &pOffscreenBits);HBITMAP hOldBitmap = (HBITMAP) ::SelectObject(hDcOffscreen, hbmpOffscreen);RECT rtPaint = { 0,0,rtWindow.right - rtWindow.left, rtWindow.bottom - rtWindow.top };PaintContent(hDcOffscreen, rtPaint);//绘画分层窗口,将BITMAP展示出来,如果PaintContent内容为空,则整个界面什么都没有,因为完全透明BLENDFUNCTION bf = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };SIZE sizeWnd = { rtWindow.right - rtWindow.left, rtWindow.bottom - rtWindow.top };POINT ptPos = { rtWindow.left, rtWindow.top };POINT ptSrc = { 0,0 };UpdateLayeredWindow(hWnd, hdc, &ptPos, &sizeWnd, hDcOffscreen, &ptSrc, 0, &bf, ULW_ALPHA);DeleteDC(hDcOffscreen);DeleteObject(hbmpOffscreen);EndPaint(hWnd, &ps);
}
//创建32位支持透明通道的位图
HBITMAP CreateARGB32Bitmap(HDC hDC, int cx, int cy, COLORREF** pBits)
{LPBITMAPINFO lpbiSrc = NULL;lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];if (lpbiSrc == NULL) return NULL;lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);lpbiSrc->bmiHeader.biWidth = cx;lpbiSrc->bmiHeader.biHeight = cy;lpbiSrc->bmiHeader.biPlanes = 1;lpbiSrc->bmiHeader.biBitCount = 32;lpbiSrc->bmiHeader.biCompression = BI_RGB;lpbiSrc->bmiHeader.biSizeImage = cx * cy;lpbiSrc->bmiHeader.biXPelsPerMeter = 0;lpbiSrc->bmiHeader.biYPelsPerMeter = 0;lpbiSrc->bmiHeader.biClrUsed = 0;lpbiSrc->bmiHeader.biClrImportant = 0;HBITMAP hBitmap = CreateDIBSection(hDC, lpbiSrc, DIB_RGB_COLORS, (void**)pBits, NULL, NULL);delete[] lpbiSrc;return hBitmap;
}
//通过gdi的方式实现支持Alpha填充背景色的功能
void DrawColor(HDC hDC, const RECT& rc, DWORD color)
{COLORREF* pColors = nullptr;HDC hMemDC = ::CreateCompatibleDC(hDC);HBITMAP hBitMap = CreateARGB32Bitmap(hDC, rc.right - rc.left, rc.bottom - rc.top, &pColors);::SelectObject(hMemDC, hBitMap);COLORREF* pTempOffscreenBits = NULL;for (LONG y = 0; y < rc.bottom - rc.top; ++y) {for (LONG x = 0; x < rc.right - rc.left; ++x) {pTempOffscreenBits = pColors + y * (rc.right - rc.left) + x;*pTempOffscreenBits = color;}}BLENDFUNCTION bf = { AC_SRC_OVER, 0, GetAValue(color), AC_SRC_ALPHA };AlphaBlend(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hMemDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, bf);DeleteObject(hBitMap);DeleteDC(hMemDC);
}
void PaintContent(HDC hDc, RECT rcPaint)
{RECT rtPaint = { 0,0,rcPaint.right - rcPaint.left, rcPaint.bottom - rcPaint.top };RECT rcItem1 = { rtPaint.left + 10,rtPaint.top + 10,rcItem1.left + 100,rcItem1.top + 100 };RECT rcItem2 = { rcItem1.right + 10,rtPaint.top + 10,rcItem2.left + 100,rcItem2.top + 100 };//DrawColor(hDc, rcItem1, 0xad00ff00);HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_SMALL));DrawIcon(hDc, rcItem2.right + 10, rcItem2.top, hIcon);::SetBkMode(hDc, TRANSPARENT);::SetTextColor(hDc, RGB(255, 0, 0));std::wstring strText = L"Hellow word!!中国";DrawText(hDc, strText.c_str(), strText.size(), &rcItem2, DT_SINGLELINE | DT_VCENTER);RECT rcItem3 = { rcItem1.right + 10,rcItem1.bottom + 10,rcItem3.left + 100,rcItem3.top + 100 };Gdiplus::Image img(L"E:\\work\\PMS\\yiletu\\xiaoyi\\xyBar\\binx86\\Debug\\skin\\res\\yiletoo.png");Gdiplus::Graphics g(hDc);g.DrawImage(&img, (INT)rcItem3.left, (INT)rcItem3.top);Gdiplus::Font ft(L"宋体", 18);Gdiplus::PointF pt = { (REAL)rcItem3.right + 10.0f,(REAL)rcItem3.top };Gdiplus::SolidBrush b(Color(0x99, 0xff, 0, 0));g.SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);g.SetPixelOffsetMode(PixelOffsetModeDefault);g.SetCompositingMode(CompositingModeSourceOver);g.SetCompositingQuality(CompositingQualityDefault);g.DrawString(strText.c_str(), strText.size(), &ft, pt, &b);Gdiplus::RectF rtf = { (REAL)rcItem1.left,(REAL)rcItem1.top,(REAL)rcItem1.right - rcItem1.left,(REAL)rcItem1.bottom - rcItem1.top };g.FillRectangle(&b, rtf);
}

效果图:

更多推荐

C++ 异形窗口

本文发布于:2023-12-08 07:29:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1672456.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:异形   窗口

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!