Управление окном перерисовки синхронно (с методом блокировки)

то, что я пытаюсь сделать, это заставить элемент управления (в том же процессе, но который я не контролирую) перерисовать себя,и для моего кода, чтобы заблокировать, пока он не закончил перерисовку.

Я попытался с помощью 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);
    }
}