Esempio n. 1
0
        private DrawingGroup GetDrawingHelper()
        {
            DrawingGroup drawingGroup = null;

            if (_hwnd.Handle != IntPtr.Zero && UnsafeNativeMethods.IsWindow(_hwnd))
            {
                NativeMethods.RECT rc = new NativeMethods.RECT();
                SafeNativeMethods.GetWindowRect(_hwnd, ref rc);
                int width  = rc.right - rc.left;
                int height = rc.bottom - rc.top;

                HandleRef hdcScreen = new HandleRef(this, UnsafeNativeMethods.GetDC(new HandleRef(this, IntPtr.Zero)));
                if (hdcScreen.Handle != IntPtr.Zero)
                {
                    HandleRef hdcBitmap = new HandleRef(this, IntPtr.Zero);
                    HandleRef hBitmap   = new HandleRef(this, IntPtr.Zero);

                    try
                    {
                        hdcBitmap = new HandleRef(this, UnsafeNativeMethods.CriticalCreateCompatibleDC(hdcScreen));
                        if (hdcBitmap.Handle != IntPtr.Zero)
                        {
                            hBitmap = new HandleRef(this, UnsafeNativeMethods.CriticalCreateCompatibleBitmap(hdcScreen, width, height));

                            if (hBitmap.Handle != IntPtr.Zero)
                            {
                                // Select the bitmap into the DC so that we draw to it.
                                IntPtr hOldBitmap = UnsafeNativeMethods.CriticalSelectObject(hdcBitmap, hBitmap.Handle);
                                try
                                {
                                    // Clear the bitmap to white (so we don't waste toner printing a black bitmap something fails).
                                    NativeMethods.RECT rcPaint  = new NativeMethods.RECT(0, 0, width, height);
                                    IntPtr             hbrWhite = UnsafeNativeMethods.CriticalGetStockObject(NativeMethods.WHITE_BRUSH);
                                    UnsafeNativeMethods.CriticalFillRect(hdcBitmap.Handle, ref rcPaint, hbrWhite);

                                    // First try to use the PrintWindow API.
                                    bool result = UnsafeNativeMethods.CriticalPrintWindow(_hwnd, hdcBitmap, 0);
                                    if (result == false)
                                    {
                                        // Fall back to sending a WM_PRINT message to the window.
                                        //
                                        // Note: there are known cases where WM_PRINT is not implemented
                                        // to provide visual parity with WM_PAINT.  However, since the
                                        // GetDrawing method is virtual, the derived class can override
                                        // this default implementation and provide a better implementation.
                                        UnsafeNativeMethods.SendMessage(_hwnd.Handle, WindowMessage.WM_PRINT, hdcBitmap.Handle, (IntPtr)(NativeMethods.PRF_CHILDREN | NativeMethods.PRF_CLIENT | NativeMethods.PRF_ERASEBKGND | NativeMethods.PRF_NONCLIENT));
                                    }
                                    else
                                    {
                                        // There is a know issue where calling PrintWindow on a window will
                                        // clear all dirty regions (but since it is redirected, the screen
                                        // won't be updated).  As a result we can leave unpainted pixels on
                                        // the screen if PrintWindow is called when the window was dirty.
                                        //
                                        // To fix this, we just force the child window to repaint.
                                        //
                                        UnsafeNativeMethods.CriticalRedrawWindow(_hwnd, IntPtr.Zero, IntPtr.Zero, NativeMethods.RDW_INVALIDATE | NativeMethods.RDW_ALLCHILDREN);
                                    }

                                    // Create a DrawingGroup that only contains an ImageDrawing that wraps the bitmap.
                                    drawingGroup = new DrawingGroup();
                                    System.Windows.Media.Imaging.BitmapSource bitmapSource = Imaging.CriticalCreateBitmapSourceFromHBitmap(hBitmap.Handle, IntPtr.Zero, Int32Rect.Empty, null, WICBitmapAlphaChannelOption.WICBitmapIgnoreAlpha);
                                    Rect rectElement = new Rect(RenderSize);
                                    drawingGroup.Children.Add(new ImageDrawing(bitmapSource, rectElement));
                                    drawingGroup.Freeze();
                                }
                                finally
                                {
                                    // Put the old bitmap back into the DC.
                                    UnsafeNativeMethods.CriticalSelectObject(hdcBitmap, hOldBitmap);
                                }
                            }
                        }
                    }
                    finally
                    {
                        UnsafeNativeMethods.ReleaseDC(new HandleRef(this, IntPtr.Zero), hdcScreen);
                        hdcScreen = new HandleRef(null, IntPtr.Zero);

                        if (hBitmap.Handle != IntPtr.Zero)
                        {
                            UnsafeNativeMethods.DeleteObject(hBitmap);
                            hBitmap = new HandleRef(this, IntPtr.Zero);
                        }

                        if (hdcBitmap.Handle != IntPtr.Zero)
                        {
                            UnsafeNativeMethods.CriticalDeleteDC(hdcBitmap);
                            hdcBitmap = new HandleRef(this, IntPtr.Zero);
                        }
                    }
                }
            }

            return(drawingGroup);
        }
Esempio n. 2
0
        private DrawingGroup GetDrawingHelper()
        {
            SecurityHelper.DemandUIWindowPermission();
            DrawingGroup drawingGroup = null;

            if (this._hwnd.Handle != IntPtr.Zero && UnsafeNativeMethods.IsWindow(this._hwnd))
            {
                NativeMethods.RECT rect = default(NativeMethods.RECT);
                SafeNativeMethods.GetWindowRect(this._hwnd, ref rect);
                int       num  = rect.right - rect.left;
                int       num2 = rect.bottom - rect.top;
                HandleRef hDC  = new HandleRef(this, UnsafeNativeMethods.GetDC(new HandleRef(this, IntPtr.Zero)));
                if (hDC.Handle != IntPtr.Zero)
                {
                    HandleRef handleRef = new HandleRef(this, IntPtr.Zero);
                    HandleRef hObject   = new HandleRef(this, IntPtr.Zero);
                    try
                    {
                        handleRef = new HandleRef(this, UnsafeNativeMethods.CriticalCreateCompatibleDC(hDC));
                        if (handleRef.Handle != IntPtr.Zero)
                        {
                            hObject = new HandleRef(this, UnsafeNativeMethods.CriticalCreateCompatibleBitmap(hDC, num, num2));
                            if (hObject.Handle != IntPtr.Zero)
                            {
                                IntPtr obj = UnsafeNativeMethods.CriticalSelectObject(handleRef, hObject.Handle);
                                try
                                {
                                    NativeMethods.RECT rect2 = new NativeMethods.RECT(0, 0, num, num2);
                                    IntPtr             brush = UnsafeNativeMethods.CriticalGetStockObject(0);
                                    UnsafeNativeMethods.CriticalFillRect(handleRef.Handle, ref rect2, brush);
                                    if (!UnsafeNativeMethods.CriticalPrintWindow(this._hwnd, handleRef, 0))
                                    {
                                        UnsafeNativeMethods.SendMessage(this._hwnd.Handle, WindowMessage.WM_PRINT, handleRef.Handle, (IntPtr)30);
                                    }
                                    else
                                    {
                                        UnsafeNativeMethods.CriticalRedrawWindow(this._hwnd, IntPtr.Zero, IntPtr.Zero, 129);
                                    }
                                    drawingGroup = new DrawingGroup();
                                    BitmapSource imageSource = Imaging.CriticalCreateBitmapSourceFromHBitmap(hObject.Handle, IntPtr.Zero, Int32Rect.Empty, null, WICBitmapAlphaChannelOption.WICBitmapIgnoreAlpha);
                                    Rect         rect3       = new Rect(base.RenderSize);
                                    drawingGroup.Children.Add(new ImageDrawing(imageSource, rect3));
                                    drawingGroup.Freeze();
                                }
                                finally
                                {
                                    UnsafeNativeMethods.CriticalSelectObject(handleRef, obj);
                                }
                            }
                        }
                    }
                    finally
                    {
                        UnsafeNativeMethods.ReleaseDC(new HandleRef(this, IntPtr.Zero), hDC);
                        hDC = new HandleRef(null, IntPtr.Zero);
                        if (hObject.Handle != IntPtr.Zero)
                        {
                            UnsafeNativeMethods.DeleteObject(hObject);
                            hObject = new HandleRef(this, IntPtr.Zero);
                        }
                        if (handleRef.Handle != IntPtr.Zero)
                        {
                            UnsafeNativeMethods.CriticalDeleteDC(handleRef);
                            handleRef = new HandleRef(this, IntPtr.Zero);
                        }
                    }
                }
            }
            return(drawingGroup);
        }