简体   繁体   English

为什么我的窗口在运行多个实例时会滞后?

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

I created a win32 window app that moves around the screen occasionally, sort of like a pet.我创建了一个偶尔在屏幕上移动的 win32 窗口应用程序,有点像宠物。 As it moves, it switches between 2 bitmaps to show 'animation' of it moving.当它移动时,它会在 2 个位图之间切换以显示它移动的“动画”。 The implementation involves multiple WM_TIMER messages: One timer Moves the window, Another changes the bitmap and windows region (to only display the bitmap without the transparent parts) as it is moving, and another changes the direction the window moves.该实现涉及多个WM_TIMER消息:一个计时器移动窗口,另一个计时器在移动时更改位图和窗口区域(仅显示没有透明部分的位图),另一个更改窗口移动的方向。

The window runs perfectly smoothly by itself, but when I open multiple instances, the animations and movements start to lag - it is not so noticeable at 2 windows, but 3 instances and above causes every single window to start lagging very noticably.该窗口本身运行非常流畅,但是当我打开多个实例时,动画和移动开始滞后 - 在 2 个窗口中不是很明显,但 3 个及以上实例导致每个窗口开始非常明显地滞后。 The movement and animations are choppy and even freeze occasionaly.动作和动画起伏不定,甚至偶尔会冻结。

I have tried removing portions of the code to pinpoint the cause of the issue, and apparently this only occurs when a section of the following code is put in (I have marked it out with comments):我已经尝试删除部分代码以查明问题的原因,显然这只会在放入以下代码的一部分时发生(我已用注释将其标记出来):

 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);

The commented section is the code I use to eliminate the transparent parts of the bitmap from being displayed in the window client region.注释部分是我用来消除位图透明部分不显示在窗口客户区域中的代码。 It is run every time the app changes bitmap to display animation.每次应用程序更改位图以显示动画时都会运行它。

The app works perfectly fine if I remove that code, so I suspect this is causing the issue.如果我删除该代码,该应用程序可以正常运行,因此我怀疑这是导致问题的原因。 Does someone know why this section of code causes lag, and ONLY with multiple instances open?有人知道为什么这部分代码会导致滞后,而且只有在打开多个实例的情况下才会这样吗? Is there a way to deal with this lag?有没有办法解决这种滞后? Thank you very much for taking the time to read through this.非常感谢您花时间阅读本文。

You're iterating over each pixel in each update (correct me if I'm wrong.) which is a fairly slow process (relatively.)您在每次更新中迭代每个像素(如果我错了请纠正我。)这是一个相当缓慢的过程(相对而言)。

A better option would be to use something like this: https://stackoverflow.com/a/3970218/19192256 to create a mask color and simply use masking to remove the transparent pixels.更好的选择是使用类似这样的方法: https ://stackoverflow.com/a/3970218/19192256 创建遮罩颜色并简单地使用遮罩去除透明像素。

creating multiple regions and concatenating them is a very slow and resource/cpu-intensive operation.创建多个区域并将它们连接起来是一个非常缓慢且资源/CPU 密集型的操作。 Instead, use ExtCreateRegion() to create a single region from an array of rectangles.相反,使用ExtCreateRegion()从矩形数组创建单个区域。

Alternatively, forget using a region at all.或者,完全忘记使用区域。 Simply display your bitmap on the window normally and fill in the desired areas of the window with a unique color that you can make transparent using SetLayeredWindowAttributes() , as described in @Substitute's answer .只需在窗口上正常显示您的位图,并使用您可以使用SetLayeredWindowAttributes()使其透明的独特颜色填充窗口的所需区域,如@Substitute的答案中所述。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM