2012-12-27 8 views
5

Quello che sto cercando di fare è un controllo (nello stesso processo, ma di cui non ho il controllo) per ridisegnare se stesso, e per il mio codice da bloccare finché non lo si finito di ridisegnare.Ridisegna il controllo della finestra in modo sincrono (con metodo di blocco)

Ho provato a utilizzare UpdateWindow ma ciò non sembra attendere il completamento del ridisegno.

Il motivo per cui ho bisogno di aspettare che finisca il ridisegno è che mi piacerebbe prendere lo schermo in seguito.

Il controllo non è un controllo dotNet, è un normale controllo di Windows.

ho confermato che:

  • Il manico è corretta.
  • UpdateWindow restituisce true.
  • Provato a inviare InvalidateRect(hWnd, IntPtr.Zero, true) appena prima della chiamata a UpdateWindow per assicurarsi che la finestra abbia bisogno di invalidare.
  • Ho provato a fare la stessa cosa nella finestra principale del controllo.

codice utilizzato:

[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

Forse è possibile disattivare il rendering in caso WM_PAINT e poi, dopo che riattivare questo. –

+0

@ S.A.Parkhid Potresti elaborare per favore? – Rotem

+0

Hmm .. Perché pensi che _UpdateWindow non sembra aspettare il completamento del redraw_? –

risposta

1

È possibile forzare l'applicazione per elaborare tutti i messaggi accodato usando Application.DoEvents (compreso il WM_PAINT!). Qualcosa di simile a questo:

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

    return false; 
} 

Ma se avete intenzione di afferrare schermo in ogni caso, non sarebbe meglio prendere due piccioni con una fava con l'invio di un messaggio WM_PRINT?

Puoi farlo dal seguente codice:

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

Grazie, ti faccio una prova e ti faccio sapere. – Rotem

+0

@Rotem, quindi, hai risolto il tuo problema? –

+0

Sarà in grado di testarlo solo domani, aggiornerò appena lo faccio. – Rotem

Problemi correlati