Управление окном перерисовки синхронно (с методом блокировки)
то, что я пытаюсь сделать, это заставить элемент управления (в том же процессе, но который я не контролирую) перерисовать себя,и для моего кода, чтобы заблокировать, пока он не закончил перерисовку.
Я попытался с помощью UpdateWindow
но это, похоже, не ждет завершения перерисовки.
причина, по которой мне нужно подождать, пока он закончит перерисовку, заключается в том, что я хотел бы захватить экран после этого.
элемент управления не является элементом управления dotNet, это контроль над обычными окнами.
Я подтвердил, что:
- ручка правильная.
-
UpdateWindow
возвращает true. - попытался направить
InvalidateRect(hWnd, IntPtr.Zero, true)
непосредственно перед вызовомUpdateWindow
чтобы убедиться, что окно нуждается в аннулировании. - попробовал сделать то же самое в Родительском окне элемента управления.
код:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool InvalidateRect(IntPtr hWnd, IntPtr rect, bool bErase);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UpdateWindow(IntPtr hWnd);
public bool PaintWindow(IntPtr hWnd)
{
InvalidateRect(hWnd, IntPtr.Zero, true);
return UpdateWindow(hWnd);
}
//returns true
1 ответов
вы можете заставить приложение обрабатывать все сообщения в очереди (включая WM_PAINT!) с помощью приложение.Функция doevents. Что-то вроде этого:--6-->
public bool PaintWindow(IntPtr hWnd)
{
InvalidateRect(hWnd, IntPtr.Zero, true);
if (UpdateWindow(hWnd))
{
Application.DoEvents();
return true;
}
return false;
}
но если вы собираетесь захватить экран в любом случае, не лучше ли убить двух птиц одним камнем, отправив WM_PRINT
сообщение?
вы можете сделать это следующим кодом:
internal static class NativeWinAPI
{
[Flags]
internal enum DrawingOptions
{
PRF_CHECKVISIBLE = 0x01,
PRF_NONCLIENT = 0x02,
PRF_CLIENT = 0x04,
PRF_ERASEBKGND = 0x08,
PRF_CHILDREN = 0x10,
PRF_OWNED = 0x20
}
internal const int WM_PRINT = 0x0317;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg,
IntPtr wParam, IntPtr lParam);
}
public static void TakeScreenshot(IntPtr hwnd, Graphics g)
{
IntPtr hdc = IntPtr.Zero;
try
{
hdc = g.GetHdc();
NativeWinAPI.SendMessage(hwnd, NativeWinAPI.WM_PRINT, hdc,
new IntPtr((int)(
NativeWinAPI.DrawingOptions.PRF_CHILDREN |
NativeWinAPI.DrawingOptions.PRF_CLIENT |
NativeWinAPI.DrawingOptions.PRF_NONCLIENT |
NativeWinAPI.DrawingOptions.PRF_OWNED
))
);
}
finally
{
if (hdc != IntPtr.Zero)
g.ReleaseHdc(hdc);
}
}