internal static void GetIconInfo(HandleRef hIcon, out NativeMethods.ICONINFO piconinfo)
        {
            bool success = false;
            int error = 0;
            piconinfo = new NativeMethods.ICONINFO();
            ICONINFO_IMPL iconInfoImpl = new ICONINFO_IMPL();

            SRCS.RuntimeHelpers.PrepareConstrainedRegions(); // Mark the following as special
            try
            {
                // Intentionally empty
            }
            finally
            {
                // This block won't be interrupted by certain runtime induced failures or thread abort
                success = GetIconInfoImpl(hIcon, iconInfoImpl);
                error = Marshal.GetLastWin32Error();

                if (success)
                {
                    piconinfo.hbmMask = NativeMethods.BitmapHandle.CreateFromHandle(iconInfoImpl.hbmMask);
                    piconinfo.hbmColor = NativeMethods.BitmapHandle.CreateFromHandle(iconInfoImpl.hbmColor);
                    piconinfo.fIcon = iconInfoImpl.fIcon;
                    piconinfo.xHotspot = iconInfoImpl.xHotspot;
                    piconinfo.yHotspot = iconInfoImpl.yHotspot;
                }
            }

            if(!success)
            {
                Debug.WriteLine("GetIconInfo failed.  Error = " + error);

                throw new Win32Exception();
            }
        }
Ejemplo n.º 2
0
        internal static NativeMethods.IconHandle CreateIconCursor(
            byte[] colorArray, 
            int width, 
            int height,
            int xHotspot,
            int yHotspot,
            bool isIcon)
        {
            //   1. We are going to generate a WIN32 color bitmap which represents the color cursor.
            //   2. Then we need to create a monochrome bitmap which is used as the cursor mask.
            //   3. At last we create a WIN32 HICON from the above two bitmaps
            NativeMethods.BitmapHandle colorBitmap = null;
            NativeMethods.BitmapHandle maskBitmap = null;

            try
            {
                // 1) Create the color bitmap using colorArray
                // Fill in the header information
                NativeMethods.BITMAPINFO bi = new NativeMethods.BITMAPINFO(
                                                    width,      // width
                                                    -height,    // A negative value indicates the bitmap is top-down DIB
                                                    32          // biBitCount
                                                    );
                bi.bmiHeader_biCompression = NativeMethods.BI_RGB;

                IntPtr bits = IntPtr.Zero;
                colorBitmap = MS.Win32.UnsafeNativeMethods.CreateDIBSection(
                                        new HandleRef(null, IntPtr.Zero),   // A device context. Pass null in if no DIB_PAL_COLORS is used.
                                        ref bi,                             // A BITMAPINFO structure which specifies the dimensions and colors.
                                        NativeMethods.DIB_RGB_COLORS,       // Specifies the type of data contained in the bmiColors array member of the BITMAPINFO structure
                                        ref bits,                           // An out Pointer to a variable that receives a pointer to the location of the DIB bit values
                                        null,                        // Handle to a file-mapping object that the function will use to create the DIB. This parameter can be null.
                                        0                                   // dwOffset. This value is ignored if hSection is NULL
                                        );

                if ( colorBitmap.IsInvalid || bits == IntPtr.Zero)
                {
                    // Note we will release the GDI resources in the finally block.
                    return NativeMethods.IconHandle.GetInvalidIcon();
                }

                // Copy the color bits to the win32 bitmap
                Marshal.Copy(colorArray, 0, bits, colorArray.Length);


                // 2) Now create the mask bitmap which is monochrome
                byte[] maskArray = GenerateMaskArray(width, height, colorArray);
                Invariant.Assert(maskArray != null);

                maskBitmap = UnsafeNativeMethods.CreateBitmap(width, height, 1, 1, maskArray);
                if ( maskBitmap.IsInvalid )
                {
                    // Note we will release the GDI resources in the finally block.
                    return NativeMethods.IconHandle.GetInvalidIcon();
                }

                // Now create HICON from two bitmaps.
                NativeMethods.ICONINFO iconInfo = new NativeMethods.ICONINFO();
                iconInfo.fIcon = isIcon;            // fIcon == ture means creating an Icon, otherwise Cursor
                iconInfo.xHotspot = xHotspot;
                iconInfo.yHotspot = yHotspot;
                iconInfo.hbmMask = maskBitmap;
                iconInfo.hbmColor = colorBitmap;

                return UnsafeNativeMethods.CreateIconIndirect(iconInfo);
            }
            finally
            {
                if (colorBitmap != null)
                {
                    colorBitmap.Dispose();
                    colorBitmap = null;
                }

                if (maskBitmap != null)
                {
                    maskBitmap.Dispose();
                    maskBitmap = null;
                }
            }
        }
Ejemplo n.º 3
0
        private static void GetMouseCursorSize(out int width, out int height, out int hotX, out int hotY)
        {
            /*
                The code for this function is based upon
                shell\comctl32\v6\tooltips.cpp _GetHcursorPdy3
                -------------------------------------------------------------------------
                With the current mouse drivers that allow you to customize the mouse
                pointer size, GetSystemMetrics returns useless values regarding
                that pointer size.

                Assumption:
                1. The pointer's width is equal to its height. We compute
                   its height and infer its width.

                This function looks at the mouse pointer bitmap
                to find out the dimensions of the mouse pointer and the
                hot spot location.
                -------------------------------------------------------------------------
            */

            // If there is no mouse cursor, these should be 0
            width = height = hotX = hotY = 0;

            // First, retrieve the mouse cursor
            IntPtr hCursor = SafeNativeMethods.GetCursor();
            if (hCursor != IntPtr.Zero)
            {
                // In case we can't figure out the dimensions, this is a best guess
                width = height = 16;

                // Get the cursor information
                NativeMethods.ICONINFO iconInfo = new NativeMethods.ICONINFO();
                bool gotIconInfo = true;
                try
                {
                    UnsafeNativeMethods.GetIconInfo(new HandleRef(null, hCursor), out iconInfo);
                }
                catch(Win32Exception)
                {
                    gotIconInfo = false;
                }

                if(gotIconInfo)
                {
                    // Get a handle to the bitmap
                    NativeMethods.BITMAP bm = new NativeMethods.BITMAP();
                    int resultOfGetObject=0;


                    new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); //Blessed Assert
                    try
                    {
                        resultOfGetObject = UnsafeNativeMethods.GetObject(iconInfo.hbmMask.MakeHandleRef(null), Marshal.SizeOf(typeof(NativeMethods.BITMAP)), bm);
                    }
                    finally
                    {
                        SecurityPermission.RevertAssert();
                    }

                    if (resultOfGetObject != 0)
                    {
                        // Extract the bitmap bits
                        int max = (bm.bmWidth * bm.bmHeight / 8);
                        byte[] curMask = new byte[max * 2]; // Enough space for the mask and the xor mask
                        if (UnsafeNativeMethods.GetBitmapBits(iconInfo.hbmMask.MakeHandleRef(null), curMask.Length, curMask) != 0)
                        {
                            bool hasXORMask = false;
                            if (iconInfo.hbmColor.IsInvalid)
                            {
                                // if no color bitmap, then the hbmMask is a double height bitmap
                                // with the cursor and the mask stacked.
                                hasXORMask = true;
                                max /= 2;
                            }

                            // Go through the bitmap looking for the bottom of the image and/or mask
                            bool empty = true;
                            int bottom = max;
                            for (bottom--; bottom >= 0; bottom--)
                            {
                                if (curMask[bottom] != 0xFF || (hasXORMask && (curMask[bottom + max] != 0)))
                                {
                                    empty = false;
                                    break;
                                }
                            }

                            if (!empty)
                            {
                                // Go through the bitmap looking for the top of the image and/or mask
                                int top;
                                for (top = 0; top < max; top++)
                                {
                                    if (curMask[top] != 0xFF || (hasXORMask && (curMask[top + max] != 0)))
                                        break;
                                }

                                // Calculate the left, right, top, bottom points

                                // byteWidth = bytes per row AND bytes per vertical pixel
                                int byteWidth = bm.bmWidth / 8;
                                int right /*px*/ = (bottom /*bytes*/ % byteWidth) * 8 /*px/byte*/;
                                bottom /*px*/ = bottom /*bytes*/ / byteWidth /*bytes/px*/;
                                int left /*px*/ = top /*bytes*/ % byteWidth * 8 /*px/byte*/;
                                top /*px*/ = top /*bytes*/ / byteWidth /*bytes/px*/;

                                // (Final value) Convert LRTB to Width and Height
                                width = right - left + 1;
                                height = bottom - top + 1;

                                // (Final value) Calculate the hotspot relative to top/left
                                hotX = iconInfo.xHotspot - left;
                                hotY = iconInfo.yHotspot - top;
                            }
                            else
                            {
                                // (Final value) We didn't find anything in the bitmap.
                                // So, we'll make a guess with the information that we have.
                                // Note: This seems to happen on I-Beams and Cross-hairs -- cursors that
                                // are all inverted. Strangely, their hbmColor is non-null.
                                width = bm.bmWidth;
                                height = bm.bmHeight;
                                hotX = iconInfo.xHotspot;
                                hotY = iconInfo.yHotspot;
                            }
                        }
                    }

                    iconInfo.hbmColor.Dispose();
                    iconInfo.hbmMask.Dispose();
                }
            }
        }