BitBlt 位图到启动画面

Posted

技术标签:

【中文标题】BitBlt 位图到启动画面【英文标题】:BitBlt a bitmap onto a splash screen 【发布时间】:2013-07-20 13:32:18 【问题描述】:

我正在为一个简单的 Direct3D 游戏制作初始屏幕,尽管屏幕本身已正确创建和销毁,但本应投影到初始屏幕上的 BITMAP 并未显示。到目前为止我有这个:

//variable declarations
HWND splashWindow = NULL;
BITMAP bm;

//window procedure
LRESULT WINAPI SplashProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )

    switch( msg )
    
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_PAINT:
        
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(splashWindow, &ps);
            HDC hdcMem = CreateCompatibleDC(hdc);
            BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
            DeleteDC(hdcMem);
            EndPaint(splashWindow, &ps);
        
    
    return DefWindowProc( hWnd, msg, wParam, lParam );


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

    //initialize splash window settings
    WNDCLASSEX wc;
    wc.cbSize = sizeof(WNDCLASSEX); 
    wc.style         = CS_VREDRAW | CS_HREDRAW;
    wc.lpfnWndProc   = SplashProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = NULL;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = "Splash Window";
    wc.hIconSm       = NULL;
    RegisterClassEx(&wc);

    //create and draw the splash window
    HBITMAP splashBMP = (HBITMAP)LoadImage(hInstance, "assets\\textures\\splash.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    GetObject(splashBMP, sizeof(bm), &bm);
    //^-splashBMP to bm - used here so the window has proper dimensions
    splashWindow = CreateWindow("Splash Window", NULL,
        WS_POPUPWINDOW | WS_EX_TOPMOST, CW_USEDEFAULT, CW_USEDEFAULT,
        bm.bmWidth, bm.bmHeight, NULL, NULL, hInstance, NULL);
    if (splashWindow == 0) return 0;

    ShowWindow(splashWindow, nCmdShow);
    UpdateWindow(splashWindow);
    //after the game loads the splash screen is destroyed through DestroyWindow(splashWindow);
    //and splashBMP is released by calling DeleteObject(splashBMP);

真的,唯一重要的代码是SplashProc 处理WM_PAINT 消息。位图bm 正在加载,通过窗口的 900x600 尺寸(与 splash.bmp 相同)显示。但是,该窗口只是一个黑屏,而不是 splash.bmp xD 中包含的 herobrine 脸

【问题讨论】:

注意:我搞砸了隔离代码。 wc.lpfnWndProc 不再是 DefWindowProc... 【参考方案1】:

这是您几乎可以肯定地盯着代码看很久而忽略了明显的代码之一。

您正在创建hdcMem,然后立即BitBlting 进入初始屏幕。在那些你无疑想要一个SelectObject 来选择你的位图到hdcMem 之间。

PAINTSTRUCT ps;
HDC hdc = BeginPaint(splashWindow, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);

// You need to add this
HBITMAP oldBmp = SelectObject(hdcMem, splashBMP);    

BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);

// ...and this
SelectObject(hdcMem, OldBmp);

DeleteDC(hdcMem);
EndPaint(splashWindow, &ps);

【讨论】:

抱歉,直到今天我都在避免使用 GDI……创建oldBmp 的目的到底是什么?我不能只在 SelectObject 中使用 splashBMP 吗? 您应该在删除之前将 DC 恢复到“原始”状态(即,没有选择任何“东西”)。为此,您保存原始位图并在销毁 DC 之前将其选回 DC。我不确定它有多大真正的不同,但这是微软说你应该做的。

以上是关于BitBlt 位图到启动画面的主要内容,如果未能解决你的问题,请参考以下文章

将子视图添加到启动画面

如何创建第二个启动画面(在 ios 中的默认启动画面之后)?

MainActivity 应在启动画面期间加载

xcode 6.2 中 IOS 的启动画面

Android:如何在启动画面上加载主要活动

电脑开机启动后到xp画面后不断自动重启怎么处理