2012-12-27 21 views
5

Ne yapmaya çalışıyorum bir denetim neden olan (aynı süreçte, fakat ben hiçbir kontrole sahip), kendisini yeniden çizmek için ve benim kod kendisine kadar engellemek için için yeniden çizmeyi bitirdi. Yeniden Çiz Pencere Kontrol Eş Zamanlı Olarak

Ben UpdateWindow kullanarak çalıştı ama o yeniden çizme bitirmesini bekleyin görünmüyor.

Yeniden çizmeyi bitirmesini beklemem gerekçesi, daha sonra ekranı kapmak istiyorum.

Denetim bir dotNet denetimi değil, normal bir pencere denetimi.

  • kolu doğrudur:

    ben teyit ediyoruz.

  • UpdateWindow, doğru döndürür.
  • Pencerenin geçerliliğini yitirmesini sağlamak için UpdateWindow numaralı çağrıdan hemen önce InvalidateRect(hWnd, IntPtr.Zero, true) göndermeyi denedim.
  • Kontrolün ana penceresinde aynı şeyi denedim. kullanılan

Kodu:

[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 
+0

Belki WM_PAINT durumda oluşturmayı devre dışı bırakabilir ve o yeniden etkinleştirin sonra sonra. –

+0

@ S.A.Parkhid Ayrıntılı bilgi verir misiniz lütfen? – Rotem

+0

Hmm .. Neden _UpdateWindow, yeniden çizmenin bitmesini beklemiyor gibi görünmüyor? –

cevap

1

Sen zorlayabilir uygulama tüm kuyruğa mesajları işlemek için Application.DoEvents kullanarak (WM_PAINT dahil!). Böyle bir şey:

public bool PaintWindow(IntPtr hWnd) 
{ 
    InvalidateRect(hWnd, IntPtr.Zero, true); 
    if (UpdateWindow(hWnd)) 
    { 
     Application.DoEvents(); 
     return true; 
    } 

    return false; 
} 

Ama bunun daha iyi WM_PRINT mesajı göndererek bir taşla iki kuş vurmak olmaz, zaten ekran kapmak için gidiyoruz?

Aşağıdaki kodu ile yapabilirsiniz:

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); 
    } 
} 
+0

Teşekkürler, bunu deneyeceğim ve bilmenizi sağlayacağım. – Rotem

+0

@Rotem, sorununuzu çözdünüz mü? –

+0

Yalnızca yarın test edebilecek olursam, en kısa zamanda güncellenir. – Rotem