Esempio n. 1
0
        /// <devdoc>
        ///     Draws this image to a graphics object.  The drawing command originates on the graphics
        ///     object, but a graphics object generally has no idea how to render a given image.  So,
        ///     it passes the call to the actual image.  This version crops the image to the given
        ///     dimensions and allows the user to specify a rectangle within the image to draw.
        /// </devdoc>
        // This method is way more powerful than what we expose, but I'll leave it in place.
        private void DrawImageCore(Graphics graphics, Rectangle imageRect, Rectangle targetRect, bool stretch)
        {
            // Support GDI+ Translate method
            targetRect.X += (int)graphics.Transform.OffsetX;
            targetRect.Y += (int)graphics.Transform.OffsetY;

            int    rop = 0xcc0020; // RasterOp.SOURCE.GetRop();
            IntPtr dc  = graphics.GetHdc();

            try { // want finally clause to release dc
                int imageX = 0;
                int imageY = 0;
                int imageWidth;
                int imageHeight;
                int targetX      = 0;
                int targetY      = 0;
                int targetWidth  = 0;
                int targetHeight = 0;

                Size cursorSize = Size;

                // compute the dimensions of the icon, if needed
                //
                if (!imageRect.IsEmpty)
                {
                    imageX      = imageRect.X;
                    imageY      = imageRect.Y;
                    imageWidth  = imageRect.Width;
                    imageHeight = imageRect.Height;
                }
                else
                {
                    imageWidth  = cursorSize.Width;
                    imageHeight = cursorSize.Height;
                }

                if (!targetRect.IsEmpty)
                {
                    targetX      = targetRect.X;
                    targetY      = targetRect.Y;
                    targetWidth  = targetRect.Width;
                    targetHeight = targetRect.Height;
                }
                else
                {
                    targetWidth  = cursorSize.Width;
                    targetHeight = cursorSize.Height;
                }

                int drawWidth, drawHeight;
                int clipWidth, clipHeight;

                if (stretch)
                {
                    // Short circuit the simple case of blasting an icon to the
                    // screen
                    //
                    if (targetWidth == imageWidth && targetHeight == imageHeight &&
                        imageX == 0 && imageY == 0 && rop == NativeMethods.SRCCOPY &&
                        imageWidth == cursorSize.Width && imageHeight == cursorSize.Height)
                    {
                        SafeNativeMethods.DrawIcon(new HandleRef(graphics, dc), targetX, targetY, new HandleRef(this, handle));
                        return;
                    }

                    drawWidth  = cursorSize.Width * targetWidth / imageWidth;
                    drawHeight = cursorSize.Height * targetHeight / imageHeight;
                    clipWidth  = targetWidth;
                    clipHeight = targetHeight;
                }
                else
                {
                    // Short circuit the simple case of blasting an icon to the
                    // screen
                    //
                    if (imageX == 0 && imageY == 0 && rop == NativeMethods.SRCCOPY &&
                        cursorSize.Width <= targetWidth && cursorSize.Height <= targetHeight &&
                        cursorSize.Width == imageWidth && cursorSize.Height == imageHeight)
                    {
                        SafeNativeMethods.DrawIcon(new HandleRef(graphics, dc), targetX, targetY, new HandleRef(this, handle));
                        return;
                    }

                    drawWidth  = cursorSize.Width;
                    drawHeight = cursorSize.Height;
                    clipWidth  = targetWidth < imageWidth ? targetWidth : imageWidth;
                    clipHeight = targetHeight < imageHeight ? targetHeight : imageHeight;
                }

                if (rop == NativeMethods.SRCCOPY)
                {
                    // The ROP is SRCCOPY, so we can be simple here and take
                    // advantage of clipping regions.  Drawing the cursor
                    // is merely a matter of offsetting and clipping.
                    //
                    SafeNativeMethods.IntersectClipRect(new HandleRef(this, Handle), targetX, targetY, targetX + clipWidth, targetY + clipHeight);
                    SafeNativeMethods.DrawIconEx(new HandleRef(graphics, dc), targetX - imageX, targetY - imageY,
                                                 new HandleRef(this, handle), drawWidth, drawHeight, 0, NativeMethods.NullHandleRef, NativeMethods.DI_NORMAL);
                    // Let GDI+ restore clipping
                    return;
                }

                Debug.Fail("Cursor.Draw does not support raster ops.  How did you even pass one in?");
            }
            finally {
                graphics.ReleaseHdcInternal(dc);
            }
        }