views:

89

answers:

3

My app has an option to disable aero by calling DwmEnableComposition(0) before capturing a screen image. As you know, disabling aero makes the screen go black then return to normal afterwards. On different PCs this might take 2 to 3 seconds depending on how fast the system is.

Is there a better way of determining if aero has fully disabled before screen capture instead of Thread.Sleep()?

+1  A: 

You should be able to do this using the related API function DwmIsCompositionEnabled. The other option might be to listen for the WM_DWMCOMPOSITIONCHANGED event.

ho1
I'm already checking on DwmIsCompositionEnabled on a loop after disabling aero, but screen capture still goes before aero is completely disabled so I end up getting black images.I'll try WM_DWMCOMPOSITIONCHANGED
sjlewis
+1  A: 

Have you looked into DwmIsCompositionEnabled? This page also says Applications can listen for composition state changes by handling the WM_DWMCOMPOSITIONCHANGED notification.

Ivan
+1  A: 

Your form's Paint event will run. That doesn't mean all windows will be fully painted, but you can sleep less. Listening for the notification message by overriding WndProc() may work, not sure when it is sent. WM_DWMCOMPOSITIONCHANGED is message 0x31e. I suspect it will be sent too soon, all windows probably have to repaint themselves next. The only way to be sure is to enumerate the windows with EnumWindows and call UpdateWindow. Visit pinvoke.net for the P/Invoke declarations you'll need. Sleep() will work too but there's no way to guess an amount that's guaranteed to work everywhere.

Hans Passant
WM_DWMCOMPOSITIONCHANGED on WndProc does not ensure aero has been completely disabled. Parts of the screen are still black.
sjlewis
It's not that Aero isn't disabled yet, it's because the windows haven't had a chance to repaint themselves yet. Post updated.
Hans Passant