1. 程式人生 > >windows桌面頻繁截圖時的滑鼠閃爍問題

windows桌面頻繁截圖時的滑鼠閃爍問題

因為需要共享桌面,所以要定時頻繁的擷取桌面圖片,然後編碼傳送出去。但是測試反饋,無法擷取桌面上的透明視窗,後來考慮在BitBlt時設定CAPTUREBLT,但是設定後滑鼠會頻繁的閃爍,這是咋回事呢?

我們在用BitBlt函式進行螢幕捕捉時,若傳遞了CAPTUREBLT(捕捉alpha blending,即半透明視窗)標誌,滑鼠就會閃爍,這是為什麼呢?

下文是本人閱讀英文解釋後的個人理解:
在windows2000及以後的系統上,滑鼠及半透明視窗這兩種圖形物件是浮於桌面其他圖形物件之上的,這裡我們稱它們為層疊視窗。層疊視窗並不存在於通常的顯示場景(具體是在顯示的哪一層,我也不清楚,姑且稱它為場景M)中,只有在顯示到螢幕的最後一刻,Windows才把層疊視窗繪製到螢幕上。

僅使用SRCCOPY標誌時,Windows只需要從M中拷貝螢幕影象就行了。而若使用了CAPTUREBLT標誌,導致的結果是滑鼠及半透明視窗均被捕捉下來。但在設計上,BitBlt函式是不允許捕捉滑鼠的。於是,系統只好先隱藏滑鼠,然後捕捉影象,再恢復滑鼠,結果就導致了滑鼠的閃爍。

附上英文原文:
You may have noticed that when you press the PrtSc key to take a screenshot, the cursor blinks briefly. Believe it or not, it actually does this for the same reason that the Windows XP fade-out shutdown screen does not include translucent windows.

These translucent windows, known as layered windows, are not normally included by the BitBlt function when reading pixels from the screen. In order to get them, you have to pass the CAPTUREBLT flag. When you do, you may also notice that the mouse cursor blinks. So why is that?

Once upon a time, the only graphical object that floated "above" the rest of the objects on your screen was the mouse cursor. Originally, the system supported only monochrome mouse cursors. These cursors were supported either in software or, if you happened to have an awesome video card, in hardware.

When you use a video card-supported cursor, the Graphics Device Interface (GDI) gives the video card a bitmap and a mask and says, "OK, this is the mouse cursor. Overlay this on the screen at the coordinates I specify." When the user moves the mouse, the GDI sends the video card updated coordinates, and the video card does the hard work of moving the pixels around the screen.

On the other hand, when you use a software-supported cursor, then the GDI is responsible for saving the pixels under the cursor before drawing it into the frame buffer. The procedure works in the following way: when the user moves the mouse, the GDI manually restores the original pixels, saves all of the pixels under the cursor's new position, and then it draws the cursor at that new position.

When a hardware cursor is employed, the pixels of the mouse cursor do not actually exist in the frame buffer because the hardware is responsible for performing the overlay. Consequently, the BitBlt function is able to just copy pixels from the frame buffer without fear of picking up pixels from the mouse cursor by mistake since those pixels don't exist in the frame buffer to begin with.

Conversely, if a software cursor is being used, then the GDI must remove the mouse cursor from the screen before performing a BitBlt from the screen if the region being copied overlaps the mouse cursor.

When animated cursors are employed, hardware cursors just don't quite cut the mustard, since hardware cursors don't animate. Therefore, animated cursors are implemented in software.

OK, great. But what does this have to do with CAPTUREBLT? Hang on, I'm getting there.

In Windows 2000, the composition mechanism that was used for software cursors was generalized so applications could also take advantage of it. These pseudo-cursors ultimately became known as layered windows. Like software cursors, layered windows don't show up when you do a BitBlt from the screen since they do not really exist in the usual sense. The pixels from the cursor and layered windows are composited onto the screen at the last moment.

But what if you want to capture the pixels of a layered window via BitBlt? That's where the new CAPTUREBLT flag comes into play. This captures the pixels after the composition engine has had its say. Since the code that generates the Windows XP dimmed shutdown screen doesn't pass the CAPTUREBLT, layered windows don't appear.

That still doesn't seem to explain why the cursor flickers, though. Actually, it does. The mouse cursor is just another composition object and therefore would be captured by the CAPTUREBLT flag. To prevent this from happening during a screen capture, the composition engine has to hide the cursor, do the CAPTUREBLT, and then re-show the cursor.

By exposing the Windows 2000 composition engine to applications, cursors have lost their special status. We've come full circle. It's now just like the good old days, back when all you had was a frame buffer and a software cursor.