簡體   English   中英

為什么我的窗口在運行多個實例時會滯后?

[英]Why does my window lag when I run multiple instances of it?

我創建了一個偶爾在屏幕上移動的 win32 窗口應用程序,有點像寵物。 當它移動時,它會在 2 個位圖之間切換以顯示它移動的“動畫”。 該實現涉及多個WM_TIMER消息:一個計時器移動窗口,另一個計時器在移動時更改位圖和窗口區域(僅顯示沒有透明部分的位圖),另一個更改窗口移動的方向。

該窗口本身運行非常流暢,但是當我打開多個實例時,動畫和移動開始滯后 - 在 2 個窗口中不是很明顯,但 3 個及以上實例導致每個窗口開始非常明顯地滯后。 動作和動畫起伏不定,甚至偶爾會凍結。

我已經嘗試刪除部分代碼以查明問題的原因,顯然這只會在放入以下代碼的一部分時發生(我已用注釋將其標記出來):

 HBITMAP hBitMap = NULL;
                BITMAP infoBitMap;
                hBitMap = LoadBitmap(GetModuleHandle(NULL), IDB_BITMAP2);
                if (hBitMap == NULL)
                {
                    MessageBoxA(NULL, "COULD NOT LOAD PET BITMAP", "ERROR", MB_OK);
                }

                HRGN BaseRgn = CreateRectRgn(0, 0, 0, 0);
                HDC winDC = GetDC(hwnd);
                HDC hMem = CreateCompatibleDC(winDC);
                GetObject(hBitMap, sizeof(infoBitMap), &infoBitMap);
                HDC hMemOld = SelectObject(hMem, hBitMap);
                COLORREF transparentCol = RGB(255, 255, 255);
                for (int y = 0; y < infoBitMap.bmHeight; y++) //<<<< THIS SECTION ONWARDS
                {

                    int x, xLeft, xRight;
                    x = 0;
                    do {
                        xLeft = xRight = 0;
                        while (x < infoBitMap.bmWidth && (GetPixel(hMem, x, y) == transparentCol))
                        {
                            x++;
                        }
                        xLeft = x;
                        while (x < infoBitMap.bmWidth && (GetPixel(hMem, x, y) != transparentCol))
                        {
                            x++;
                        }
                        xRight = x;
                        HRGN TempRgn;
                        TempRgn = CreateRectRgn(xLeft, y, xRight, y + 1);
                        int ret = CombineRgn(BaseRgn, BaseRgn, TempRgn, RGN_OR);
                        if (ret == ERROR)
                        {
                            MessageBoxA(NULL, "COMBINE REGION FAILED", "ERROR", MB_OK);
                        }
                        DeleteObject(TempRgn);
                    } while (x < infoBitMap.bmWidth);
                }
                SetWindowRgn(hwnd, BaseRgn, TRUE);   //<<<<---- UNTIL HERE
                BitBlt(winDC, 0, 0, infoBitMap.bmWidth, infoBitMap.bmHeight, hMem, 0, 0, SRCCOPY);
                SelectObject(hMem, hMemOld);
                DeleteDC(hMem);
                ReleaseDC(hwnd, winDC);

注釋部分是我用來消除位圖透明部分不顯示在窗口客戶區域中的代碼。 每次應用程序更改位圖以顯示動畫時都會運行它。

如果我刪除該代碼,該應用程序可以正常運行,因此我懷疑這是導致問題的原因。 有人知道為什么這部分代碼會導致滯后,而且只有在打開多個實例的情況下才會這樣嗎? 有沒有辦法解決這種滯后? 非常感謝您花時間閱讀本文。

您在每次更新中迭代每個像素(如果我錯了請糾正我。)這是一個相當緩慢的過程(相對而言)。

更好的選擇是使用類似這樣的方法: https ://stackoverflow.com/a/3970218/19192256 創建遮罩顏色並簡單地使用遮罩去除透明像素。

創建多個區域並將它們連接起來是一個非常緩慢且資源/CPU 密集型的操作。 相反,使用ExtCreateRegion()從矩形數組創建單個區域。

或者,完全忘記使用區域。 只需在窗口上正常顯示您的位圖,並使用您可以使用SetLayeredWindowAttributes()使其透明的獨特顏色填充窗口的所需區域,如@Substitute的答案中所述。

暫無
暫無

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

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