Rot*_*tem 6 c# winapi gdi redraw invalidation
我想要做的是导致一个控件(在同一个过程中,但我无法控制)重绘自己,并让我的代码阻塞,直到它完成重绘.
我尝试过使用,UpdateWindow
但似乎并不等待重绘完成.
我需要等待它完成重绘的原因是我想在之后抓住屏幕.
该控件不是dotNet控件,它是常规的Windows控件.
我已经确认:
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
Run Code Online (Sandbox Code Playgroud)
您可以使用Application.DoEvents强制应用程序处理所有排队的消息(包括 WM_PAINT!)。像这样的东西:
public bool PaintWindow(IntPtr hWnd)
{
InvalidateRect(hWnd, IntPtr.Zero, true);
if (UpdateWindow(hWnd))
{
Application.DoEvents();
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
但如果你无论如何都要抢屏,那么通过发消息一石二鸟不是更好吗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);
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2924 次 |
最近记录: |