C++屏幕水印实现遇到问题

查看 5|回复 0
作者:koomox   
C++用得不多,并且对 GDIPLUS 也不是很了解。想实现一个屏幕水印得工具,下面得代码运行后,Graphics 创建得对象背景非透明,并且程序无法正常关闭退出。大佬们帮忙看看,指定迷津
代码如下:
#include
#include
#include
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")
const std::wstring watermarkText = L"Your Watermark Text";
const int watermarkFontSize = 38;
const int watermarkSpacing = 100;
void DrawWatermark(HDC hdc, int windowWidth, int windowHeight)
{
    // 初始化 GDI+
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    SetBkMode(hdc, TRANSPARENT);
    // 创建 Graphics 对象
    Graphics graphics(hdc);
   
    // 创建字体
    FontFamily fontFamily(L"Arial");
    Font font(&fontFamily, watermarkFontSize, FontStyleRegular, UnitPixel);
    // 设置文本颜色
    SolidBrush textBrush(Color(255, 0, 0, 0)); // 文本颜色为黑色
    // 获取文本尺寸
    RectF layoutRect;
    graphics.MeasureString(watermarkText.c_str(), -1, &font, PointF(0, 0), &layoutRect);
    // 计算水印文本块的总数以填满整个屏幕
    int numBlocksX = (windowWidth + watermarkSpacing) / (static_cast[i](layoutRect.Width) + watermarkSpacing);
    int numBlocksY = (windowHeight + watermarkSpacing) / (static_cast[i](layoutRect.Height) + watermarkSpacing);
    // 计算实际的间距
    int actualSpacingX = (windowWidth - numBlocksX * static_cast[i](layoutRect.Width)) / (numBlocksX - 1);
    int actualSpacingY = (windowHeight - numBlocksY * static_cast[i](layoutRect.Height)) / (numBlocksY - 1);
    // 保存当前的世界变换矩阵
    Matrix oldTransform;
    graphics.GetTransform(&oldTransform);
    // 绘制水印文本块
    for (int y = 0; y (textX), static_cast(textY));
            graphics.RotateTransform(-45.0f);
            // 绘制水印文本
            graphics.DrawString(watermarkText.c_str(), -1, &font, PointF(0, 0), &textBrush);
            // 恢复原始的世界变换矩阵
            graphics.SetTransform(&oldTransform);
        }
    }
    // 关闭 GDI+
    GdiplusShutdown(gdiplusToken);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE:
    {
        // 设置窗口样式为 WS_EX_LAYERED
        SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED | WS_EX_TRANSPARENT);
        // 设置窗口为完全透明
        SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 0, LWA_COLORKEY);
        // 设置窗口大小为屏幕大小
        int windowWidth = GetSystemMetrics(SM_CXSCREEN);
        int windowHeight = GetSystemMetrics(SM_CYSCREEN);
        SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, windowWidth, windowHeight, SWP_SHOWWINDOW);
        break;
    }
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        int windowWidth = GetSystemMetrics(SM_CXSCREEN);
        int windowHeight = GetSystemMetrics(SM_CYSCREEN);
        // 绘制水印
        DrawWatermark(hdc, windowWidth, windowHeight);
        EndPaint(hwnd, &ps);
        break;
    }
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        break;
    }
    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wcex;
    ZeroMemory(&wcex, sizeof(WNDCLASSEX));
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.lpfnWndProc = WndProc;
    wcex.hInstance = hInstance;
    wcex.lpszClassName = L"WatermarkWindowClass";
    RegisterClassEx(&wcex);
    HWND hwnd = CreateWindow(L"WatermarkWindowClass", L"", WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);
    if (hwnd == NULL)
    {
        return 0;
    }
    ShowWindow(hwnd, nCmdShow);
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return static_cast[i](msg.wParam);
}
您需要登录后才可以回帖 登录 | 立即注册

返回顶部