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

无需使用*.DLL库能否开发显示PNG图片的启动闪屏?

可行性结论

完全可以实现,无需额外引入第三方DLL,仅依赖Windows系统内置的GDI+和Win32 API即可完成PNG闪屏开发,同时支持自定义显示位置、自定义显示时长的需求。

支持特性
  • 完整支持带透明通道的PNG图片渲染
  • 支持两种位置配置:屏幕自动居中、任意指定左上角坐标
  • 支持自定义显示时长,精度为毫秒级
  • 可选支持点击闪屏提前关闭
  • 无额外DLL分发需求,系统内置组件即可运行
完整实现代码(C++ Win32)
#include <windows.h>
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")

// 配置参数,可自行修改
#define SPLASH_PNG_RES_ID  IDR_PNG1 // 你的PNG资源ID
#define SPLASH_DISPLAY_TIME 3000    // 显示时长,单位毫秒,3000=3秒
#define SPLASH_CUSTOM_POS_X  CW_USEDEFAULT // 自定义X坐标,CW_USEDEFAULT为居中
#define SPLASH_CUSTOM_POS_Y  CW_USEDEFAULT // 自定义Y坐标,CW_USEDEFAULT为居中

ULONG_PTR g_gdiplusToken = 0;
HWND g_hSplashWnd = NULL;

// 从资源加载PNG图片
Gdiplus::Bitmap* LoadPngFromResource(UINT resId)
{
    HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(resId), L"PNG");
    HGLOBAL hGlobal = LoadResource(NULL, hRes);
    DWORD resSize = SizeofResource(NULL, hRes);
    HGLOBAL hBuffer = GlobalAlloc(GMEM_MOVEABLE, resSize);
    LPVOID pBuffer = GlobalLock(hBuffer);
    CopyMemory(pBuffer, LockResource(hGlobal), resSize);
    GlobalUnlock(hBuffer);
    
    IStream* pStream = NULL;
    CreateStreamOnHGlobal(hBuffer, TRUE, &pStream);
    Gdiplus::Bitmap* pBitmap = Gdiplus::Bitmap::FromStream(pStream);
    pStream->Release();
    return pBitmap;
}

// 闪屏窗口过程
LRESULT CALLBACK SplashWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CREATE:
        {
            Gdiplus::Bitmap* pBitmap = LoadPngFromResource(SPLASH_PNG_RES_ID);
            if(!pBitmap) break;
            
            int width = pBitmap->GetWidth();
            int height = pBitmap->GetHeight();
            
            // 计算窗口位置
            int x = SPLASH_CUSTOM_POS_X;
            int y = SPLASH_CUSTOM_POS_Y;
            if(x == CW_USEDEFAULT || y == CW_USEDEFAULT)
            {
                int screenW = GetSystemMetrics(SM_CXSCREEN);
                int screenH = GetSystemMetrics(SM_CYSCREEN);
                x = (screenW - width) / 2;
                y = (screenH - height) / 2;
            }
            SetWindowPos(hWnd, HWND_TOPMOST, x, y, width, height, SWP_NOACTIVATE);
            
            // 配置分层窗口实现透明PNG渲染
            HDC hdcScreen = GetDC(NULL);
            HDC hdcMem = CreateCompatibleDC(hdcScreen);
            HBITMAP hBmp = NULL;
            pBitmap->GetHBITMAP(Gdiplus::Color(0), &hBmp);
            HBITMAP hOldBmp = (HBITMAP)SelectObject(hdcMem, hBmp);
            
            BLENDFUNCTION blend = {0};
            blend.BlendOp = AC_SRC_OVER;
            blend.SourceConstantAlpha = 255;
            blend.AlphaFormat = AC_SRC_ALPHA;
            UpdateLayeredWindow(hWnd, hdcScreen, NULL, &SIZE{width, height}, hdcMem, &POINT{0,0}, 0, &blend, ULW_ALPHA);
            
            SelectObject(hdcMem, hOldBmp);
            DeleteObject(hBmp);
            DeleteDC(hdcMem);
            ReleaseDC(NULL, hdcScreen);
            delete pBitmap;
            
            // 设置定时器到点关闭闪屏
            SetTimer(hWnd, 1, SPLASH_DISPLAY_TIME, NULL);
            break;
        }
        case WM_TIMER:
        case WM_LBUTTONDOWN: // 点击鼠标左键提前关闭
            DestroyWindow(hWnd);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    return 0;
}

// 入口函数,你可以在程序启动时调用ShowSplash()来显示闪屏
void ShowSplash()
{
    // 初始化GDI+
    Gdiplus::GdiplusStartupInput input;
    Gdiplus::GdiplusStartup(&g_gdiplusToken, &input, NULL);
    
    // 注册窗口类
    WNDCLASSEX wc = {0};
    wc.cbSize = sizeof(wc);
    wc.lpfnWndProc = SplashWndProc;
    wc.hInstance = GetModuleHandle(NULL);
    wc.lpszClassName = L"SplashWindowClass";
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    RegisterClassEx(&wc);
    
    // 创建分层窗口
    g_hSplashWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
                                  wc.lpszClassName, L"Splash", WS_POPUP,
                                  0, 0, 0, 0, NULL, NULL, wc.hInstance, NULL);
    ShowWindow(g_hSplashWnd, SW_SHOW);
    UpdateWindow(g_hSplashWnd);
    
    // 消息循环
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    
    // 清理资源
    Gdiplus::GdiplusShutdown(g_gdiplusToken);
}
配置说明
  • 资源导入:将PNG图片添加到项目资源中,资源类型设置为PNG,修改SPLASH_PNG_RES_ID宏为你实际的资源ID即可
  • 位置配置:如果需要指定固定位置,修改SPLASH_CUSTOM_POS_X和SPLASH_CUSTOM_POS_Y为你需要的坐标值即可,默认的CW_USEDEFAULT为自动居中显示
  • 时长配置:修改SPLASH_DISPLAY_TIME的数值即可调整显示时长,单位为毫秒
  • 功能调整:如果不需要点击提前关闭,删除WM_LBUTTONDOWN的响应分支即可

注意:代码依赖的gdiplus.dll为Windows Vista及以上系统内置组件,无需额外随程序分发,完全符合无第三方DLL的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 08:21:04