簡體   English   中英

Win32-使用GDI對象的正確方法是什么?

[英]Win32 - What is the proper way to use GDI objects?

我正在Win32中制作一個簡單的游戲。 當前,我的大多數繪圖對象都在主文件中全局聲明,因此我不必刪除它們或重新加載位圖。 因此,基本上我所有的位圖都加載在WM_CREATE中,因此什么都不需要刪除-有人告訴我,我可以僅依靠系統清理項目終止時的資源。 在WM_PAINT(每秒被調用大約10次)中,我有很多BitBlt()調用以及很多SelectObject()調用。 運行大約10-15分鍾后,請選擇SelectObject()。 是什么會導致SelectObject()失敗,並且我使用GDI對象的方式不正確?

例:

// Top of the file
HDC hdc;
HDC hdcmem;
HDC hbcmem;
HBITMAP colorsprites, blackwhitesprites, nums;
HBITMAP hdcold, hdcbmold, hdcbm;

// Some functions to get the window ready

// More variables used for drawing:
HBITMAP bg, side, mainCont, tmpbm, tmpold, bm_left, bm_right, sidebg, win_bm;
PAINTSTRUCT ps;
RECT rc;
HDC tmphdc;
HDC tmp;
HFONT font;
HBRUSH hbr;
HPEN pen;
BITMAP structBitmapHeader;
HGDIOBJ hBitmap;
HCURSOR crosshairs = LoadCursorW(hInst, IDC_CROSS);
HCURSOR normal = LoadCursorW(hInst, IDC_ARROW);
POINT cursor;
bool addPass = false, ignorePass;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_CREATE:
            hdc = GetDC(hWnd);
            hdcmem = CreateCompatibleDC(hdc);
            GetClientRect(hWnd, &rc);
            hdcbm = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
            hbcmem = CreateCompatibleDC(hdcmem);
            hdcbmold = (HBITMAP)SelectObject(hdcmem, hdcbm);

            // Load bitmaps
            bg                  = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BACKGROUND));
            mainCont            = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_GAME_CONT));
            side                = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SIDEINFO));
            colorsprites        = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_COLOR_SPRITES));
            blackwhitesprites   = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BLACKWHITE_SPRITES));
            sidebg              = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SIDEBG));
            nums                = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_NUMBERS));
            bm_left             = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_LEFT));
            bm_right            = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_RIGHT));
            win_bm              = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_VICTORY));
            if(bg == NULL || mainCont == NULL || side == NULL || colorsprites == NULL 
            || blackwhitesprites == NULL || sidebg == NULL || nums == NULL || bm_left == NULL 
            || bm_right == NULL)
                ThrowError("A bitmap failed to load.");

            break;

        case WM_PAINT:
            BeginPaint(hWnd, &ps);

            // SelectObject() and BitBlt() are called a lot in here

            EndPaint(hWnd, &ps);

            break;

        case WM_DESTROY:
            // System will clean up all GDI stuff - no need to delete anything
            PostQuitMessage(0);
            break;
    }
}

確保銷毀DC時,已將原始位圖重新選擇回去。 當位圖仍處於選中狀態時,切勿破壞DC。

通過在BeginPaint之后立即調用SaveDC,在EndPaint之前立即調用RestoreDC,可以使生活變得更加輕松。 這會將DC恢復到釋放之前的原始狀態。

http://msdn.microsoft.com/zh-CN/library/windows/desktop/dd162945(v=vs.85).aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM