You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinAPI中使用GDI+绘制图片时如何将宿主窗口设为透明仅显示图片

实现仅显示绘制图片的窗口方案

你可以通过分层窗口(Layered Window) + 无边框窗口样式的组合实现需求,核心逻辑是去掉窗口默认的标题栏、边框等装饰,再将窗口背景区域设为完全透明,仅保留你绘制的图片区域可见。


具体修改步骤

  • 修改窗口创建参数:开启分层窗口扩展样式,替换默认的带标题栏边框的窗口样式为无边框样式
  • 设置窗口透明色:通过SetLayeredWindowAttributes指定某一颜色为透明键,所有使用该颜色绘制的区域都会被系统自动设为透明
  • 修改窗口背景填充色为上述指定的透明键色,调整窗口尺寸和图片尺寸匹配,避免多余透明区域

修改后完整示例代码

#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>

using namespace Gdiplus;
#pragma comment (lib, "Gdiplus.lib")

// 定义透明键色,选择极少会用到的洋红色避免和图片内容冲突
#define TRANSPARENT_COLOR RGB(255, 0, 255)
Image* pImage = nullptr; // 全局存储图片指针方便获取尺寸

void Example_DrawImage9(HDC hdc) {
    Graphics graphics(hdc);
    graphics.DrawImage(pImage, 0, 0); // 从窗口左上角开始绘制,避免偏移
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR pCmdLine, int nCmdShow) {
    ULONG_PTR token;
    GdiplusStartupInput input = { 0 };
    input.GdiplusVersion = 1;
    GdiplusStartup(&token, &input, NULL);

    // 提前加载图片获取宽高
    pImage = new Image(L"C:/Users/Darek/Fallout2/data/art/iface/armor_info.bmp");
    int imgWidth = pImage->GetWidth();
    int imgHeight = pImage->GetHeight();

    const wchar_t CLASS_NAME[] = L"Sample Window Class";
    WNDCLASS wc = {};
    wc.lpfnWndProc = &WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    // 设置窗口背景刷为透明键色,避免刷新时闪烁
    wc.hbrBackground = CreateSolidBrush(TRANSPARENT_COLOR);
    RegisterClass(&wc);

    // 扩展样式添加WS_EX_LAYERED开启分层窗口,可选添加WS_EX_TOOLWINDOW隐藏任务栏图标
    HWND hwnd = CreateWindowEx(
        WS_EX_LAYERED | WS_EX_TOOLWINDOW,
        CLASS_NAME,
        L"",
        WS_POPUP, // 无边框样式,去掉标题栏、边框等装饰
        CW_USEDEFAULT, CW_USEDEFAULT,
        imgWidth, imgHeight, // 窗口尺寸和图片完全匹配
        NULL, NULL, hInstance, NULL
    );

    if (hwnd != NULL)   {
        // 设置透明键,所有TRANSPARENT_COLOR颜色的区域都会透明
        SetLayeredWindowAttributes(hwnd, TRANSPARENT_COLOR, 0, LWA_COLORKEY);
        ShowWindow(hwnd, nCmdShow);

        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0) > 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    delete pImage;
    GdiplusShutdown(token);
    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;

        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            // 背景填充为透明键色,会被自动穿透
            FillRect(hdc, &ps.rcPaint, (HBRUSH)GetStockObject(GRAY_BRUSH));
            Example_DrawImage9(hdc);
            EndPaint(hwnd, &ps);
            return 0;
        }
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

补充说明

  • 如果你的图片本身带alpha透明通道,需要更精细的透明效果,可以使用UpdateLayeredWindow直接将带alpha的图片内容贴到窗口上,不需要指定透明键色,效果更平滑
  • 如果你需要允许用户拖拽图片移动,可以在WindowProc中响应WM_NCHITTEST消息,返回HTCAPTION即可实现点击图片任意位置拖动窗口的效果
  • 不需要的话可以去掉WS_EX_TOOLWINDOW扩展样式,窗口会正常显示在任务栏中

内容的提问来源于stack exchange,提问作者Daros911

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 07:54:06