Skip to content

Commit

Permalink
修正主窗口使用png背景时,插件项目自绘使用GDI绘制的文本变成透明的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
zhongyang219 committed Jan 14, 2025
1 parent 0c5e86e commit 4ef0022
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 2 deletions.
54 changes: 54 additions & 0 deletions TrafficMonitor/DrawCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,57 @@ void DrawCommonHelper::ImageDrawAreaConvert(CSize image_size, CPoint& start_poin
}
}
}

void DrawCommonHelper::FixBitmapTextAlpha(HBITMAP hBitmap, BYTE alpha, const std::vector<CRect>& 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);
}
3 changes: 3 additions & 0 deletions TrafficMonitor/DrawCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<CRect>& rects);
};
20 changes: 18 additions & 2 deletions TrafficMonitor/SkinFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<CRect> 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);
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 4ef0022

Please sign in to comment.