From 4ef0022f87f095d1fe901af33a0044661981d251 Mon Sep 17 00:00:00 2001 From: zhongyang219 Date: Tue, 14 Jan 2025 14:48:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=BB=E7=AA=97=E5=8F=A3?= =?UTF-8?q?=E4=BD=BF=E7=94=A8png=E8=83=8C=E6=99=AF=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E9=A1=B9=E7=9B=AE=E8=87=AA=E7=BB=98=E4=BD=BF?= =?UTF-8?q?=E7=94=A8GDI=E7=BB=98=E5=88=B6=E7=9A=84=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E5=8F=98=E6=88=90=E9=80=8F=E6=98=8E=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TrafficMonitor/DrawCommon.cpp | 54 +++++++++++++++++++++++++++++++++++ TrafficMonitor/DrawCommon.h | 3 ++ TrafficMonitor/SkinFile.cpp | 20 +++++++++++-- 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/TrafficMonitor/DrawCommon.cpp b/TrafficMonitor/DrawCommon.cpp index 57cf1ff5..b1be0bfe 100644 --- a/TrafficMonitor/DrawCommon.cpp +++ b/TrafficMonitor/DrawCommon.cpp @@ -298,3 +298,57 @@ void DrawCommonHelper::ImageDrawAreaConvert(CSize image_size, CPoint& start_poin } } } + +void DrawCommonHelper::FixBitmapTextAlpha(HBITMAP hBitmap, BYTE alpha, const std::vector& rects) +{ + if (rects.empty()) + return; + BITMAP bm; + GetObject(hBitmap, sizeof(BITMAP), &bm); + + int width = bm.bmWidth; + int height = bm.bmHeight; + + // 获取位图的像素数据 + BITMAPINFO bmpInfo = { 0 }; + bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmpInfo.bmiHeader.biWidth = width; + bmpInfo.bmiHeader.biHeight = -height; // top-down DIB + bmpInfo.bmiHeader.biPlanes = 1; + bmpInfo.bmiHeader.biBitCount = 32; + bmpInfo.bmiHeader.biCompression = BI_RGB; + + HDC hdc = CreateCompatibleDC(NULL); + SelectObject(hdc, hBitmap); + + // 分配内存存储位图像素 + RGBQUAD* pPixels = new RGBQUAD[width * height]; + GetDIBits(hdc, hBitmap, 0, height, pPixels, &bmpInfo, DIB_RGB_COLORS); + + // 遍历所有矩形区域 + for (const auto& rect : rects) + { + int startX = max(0, rect.left); + int startY = max(0, rect.top); + int endX = min(width, rect.right); + int endY = min(height, rect.bottom); + + // 遍历当前矩形内的像素 + for (int y = startY; y < endY; ++y) + { + for (int x = startX; x < endX; ++x) + { + int index = y * width + x; + //如果检测到alpha值为0,则可能是被错误地设置成透明的文本部分,将其修正为正确的alpha值 + if (pPixels[index].rgbReserved == 0) + pPixels[index].rgbReserved = alpha; // 设置Alpha通道 + } + } + } + + // 将修改后的像素数据写回位图 + SetDIBits(hdc, hBitmap, 0, height, pPixels, &bmpInfo, DIB_RGB_COLORS); + + delete[] pPixels; + DeleteDC(hdc); +} diff --git a/TrafficMonitor/DrawCommon.h b/TrafficMonitor/DrawCommon.h index e6429c38..af763375 100644 --- a/TrafficMonitor/DrawCommon.h +++ b/TrafficMonitor/DrawCommon.h @@ -111,4 +111,7 @@ namespace DrawCommonHelper //stretch_mode[int]:拉伸模式 void ImageDrawAreaConvert(CSize image_size, CPoint& start_point, CSize& size, IDrawCommon::StretchMode stretch_mode); + //修正位图中文本部分的Alpha通道 + //使用了UpdateLayeredWindow后,使用GDI绘制的文本也会变得透明,此函数会遍历bitmap中alpha值为0的部分,将其修正为正确的alpha值 + void FixBitmapTextAlpha(HBITMAP hBitmap, BYTE alpha, const std::vector& rects); }; diff --git a/TrafficMonitor/SkinFile.cpp b/TrafficMonitor/SkinFile.cpp index 3f106375..9a014f7d 100644 --- a/TrafficMonitor/SkinFile.cpp +++ b/TrafficMonitor/SkinFile.cpp @@ -527,9 +527,24 @@ void CSkinFile::DrawInfo(CDC* pDC, bool show_more_info, CFont& font) //绘制显示项目 DrawItemsInfo(gdiplus_drawer, layout, font); + //重新设置自绘插件区域的alpha值。 + //插件自绘时可能会使用GDI绘制文本,由于使用了UpdateLayeredWindow函数,使用GDI的绘图函数绘制文本时会导致文本变得透明。 + //这里遍历所有插件自绘区域,将alpha值为0的部分修正为正确的alpha值。 + std::vector rects; + for (const auto& plugin_item : theApp.m_plugins.GetPluginItems()) + { + const auto& layout_item = layout.GetItem(plugin_item); + if (plugin_item->IsCustomDraw() && layout_item.show) + { + CRect rect(CPoint(layout_item.x, layout_item.y), CSize(layout_item.width, m_layout_info.text_height)); + rects.push_back(rect); + } + } + DrawCommonHelper::FixBitmapTextAlpha(hBitMap, m_alpha, rects); + SIZE sizeWindow = rect.Size(); POINT ptSrc = { 0,0 }; - ::UpdateLayeredWindow(hWnd, pDC->GetSafeHdc(), nullptr, &sizeWindow, hdcMemory, &ptSrc, RGB(255, 0, 255), &bf, ULW_ALPHA); + ::UpdateLayeredWindow(hWnd, pDC->GetSafeHdc(), nullptr, &sizeWindow, hdcMemory, &ptSrc, 0, &bf, ULW_ALPHA); gdiplus_drawer.GetGraphics()->ReleaseHDC(hdcMemory); DeleteObject(hBitMap); @@ -672,7 +687,8 @@ void CSkinFile::DrawItemsInfo(IDrawCommon& drawer, Layout& layout, CFont& font) plugin->OnExtenedInfo(ITMPlugin::EI_VALUE_TEXT_COLOR, std::to_wstring(cl).c_str()); plugin->OnExtenedInfo(ITMPlugin::EI_DRAW_TASKBAR_WND, L"0"); } - drawer.SetTextColor(cl); + drawer.GetDC()->SetTextColor(cl); + drawer.GetDC()->SetBkMode(TRANSPARENT); plugin_item->DrawItem(drawer.GetDC()->GetSafeHdc(), layout_item.x, layout_item.y, layout_item.width, m_layout_info.text_height, brightness >= 128); } else