Ejemplo n.º 1
0
        // this code is adapted from Icon.GetIconSize please take this into account when changing this
        private Size GetIconSize(IntPtr iconHandle)
        {
            Size iconSize = Size;

            NativeMethods.ICONINFO info = default;
            SafeNativeMethods.GetIconInfo(new HandleRef(this, iconHandle), ref info);
            NativeMethods.BITMAP bmp = new NativeMethods.BITMAP();

            if (info.hbmColor != IntPtr.Zero)
            {
                UnsafeNativeMethods.GetObject(new HandleRef(null, info.hbmColor), Marshal.SizeOf <NativeMethods.BITMAP>(), bmp);
                Interop.Gdi32.DeleteObject(info.hbmColor);
                iconSize = new Size(bmp.bmWidth, bmp.bmHeight);
            }
            else if (info.hbmMask != IntPtr.Zero)
            {
                UnsafeNativeMethods.GetObject(new HandleRef(null, info.hbmMask), Marshal.SizeOf <NativeMethods.BITMAP>(), bmp);
                iconSize = new Size(bmp.bmWidth, bmp.bmHeight / 2);
            }

            if (info.hbmMask != IntPtr.Zero)
            {
                Interop.Gdi32.DeleteObject(info.hbmMask);
            }
            return(iconSize);
        }
Ejemplo n.º 2
0
        // this code is adapted from Icon.GetIconSize please take this into account when changing this
        private Size GetIconSize(IntPtr iconHandle)
        {
            Size iconSize = Size;

            NativeMethods.ICONINFO info = new NativeMethods.ICONINFO();
            SafeNativeMethods.GetIconInfo(new HandleRef(this, iconHandle), info);
            NativeMethods.BITMAP bmp = new NativeMethods.BITMAP();

            if (info.hbmColor != IntPtr.Zero)
            {
                UnsafeNativeMethods.GetObject(new HandleRef(null, info.hbmColor), Marshal.SizeOf(typeof(NativeMethods.BITMAP)), bmp);
                SafeNativeMethods.IntDeleteObject(new HandleRef(null, info.hbmColor));
                iconSize = new Size(bmp.bmWidth, bmp.bmHeight);
            }
            else if (info.hbmMask != IntPtr.Zero)
            {
                UnsafeNativeMethods.GetObject(new HandleRef(null, info.hbmMask), Marshal.SizeOf(typeof(NativeMethods.BITMAP)), bmp);
                iconSize = new Size(bmp.bmWidth, bmp.bmHeight / 2);
            }

            if (info.hbmMask != IntPtr.Zero)
            {
                SafeNativeMethods.IntDeleteObject(new HandleRef(null, info.hbmMask));
            }
            return(iconSize);
        }
Ejemplo n.º 3
0
            // ported form VB6 (Ctls\PortUtil\StdCtl.cpp:6176)
            private unsafe bool DICopy(HandleRef hdcDest, IntPtr hdcSrc, RECT rect, bool bStretch)
            {
                long i;

                // Get the bitmap from the DC by selecting in a 1x1 pixel temp bitmap
                IntPtr hNullBitmap = SafeNativeMethods.CreateBitmap(1, 1, 1, 1, IntPtr.Zero);

                if (hNullBitmap == IntPtr.Zero)
                {
                    return(false);
                }

                try
                {
                    IntPtr hBitmap = Gdi32.SelectObject(hdcSrc, hNullBitmap);
                    if (hBitmap == IntPtr.Zero)
                    {
                        return(false);
                    }

                    // Restore original bitmap
                    Gdi32.SelectObject(hdcSrc, hBitmap);

                    NativeMethods.BITMAP bmp = new NativeMethods.BITMAP();
                    if (UnsafeNativeMethods.GetObject(new HandleRef(null, hBitmap), Marshal.SizeOf(bmp), bmp) == 0)
                    {
                        return(false);
                    }

                    NativeMethods.BITMAPINFO_FLAT lpbmi = new NativeMethods.BITMAPINFO_FLAT
                    {
                        bmiHeader_biSize          = Marshal.SizeOf <NativeMethods.BITMAPINFOHEADER>(),
                        bmiHeader_biWidth         = bmp.bmWidth,
                        bmiHeader_biHeight        = bmp.bmHeight,
                        bmiHeader_biPlanes        = 1,
                        bmiHeader_biBitCount      = bmp.bmBitsPixel,
                        bmiHeader_biCompression   = NativeMethods.BI_RGB,
                        bmiHeader_biSizeImage     = 0,           //Not needed since using BI_RGB
                        bmiHeader_biXPelsPerMeter = 0,
                        bmiHeader_biYPelsPerMeter = 0,
                        bmiHeader_biClrUsed       = 0,
                        bmiHeader_biClrImportant  = 0,
                        bmiColors = new byte[NativeMethods.BITMAPINFO_MAX_COLORSIZE * 4]
                    };

                    // Include the palette for 256 color bitmaps
                    long iColors = 1 << (bmp.bmBitsPixel * bmp.bmPlanes);
                    if (iColors <= 256)
                    {
                        byte[] aj = new byte[Marshal.SizeOf <NativeMethods.PALETTEENTRY>() * 256];
                        SafeNativeMethods.GetSystemPaletteEntries(hdcSrc, 0, (int)iColors, aj);

                        fixed(byte *pcolors = lpbmi.bmiColors)
                        {
                            fixed(byte *ppal = aj)
                            {
                                NativeMethods.RGBQUAD *     prgb = (NativeMethods.RGBQUAD *)pcolors;
                                NativeMethods.PALETTEENTRY *lppe = (NativeMethods.PALETTEENTRY *)ppal;

                                // Convert the palette entries to RGB quad entries
                                for (i = 0; i < (int)iColors; i++)
                                {
                                    prgb[i].rgbRed   = lppe[i].peRed;
                                    prgb[i].rgbBlue  = lppe[i].peBlue;
                                    prgb[i].rgbGreen = lppe[i].peGreen;
                                }
                            }
                        }
                    }

                    // Allocate memory to hold the bitmap bits
                    long   bitsPerScanLine  = bmp.bmBitsPixel * (long)bmp.bmWidth;
                    long   bytesPerScanLine = (bitsPerScanLine + 7) / 8;
                    long   totalBytesReqd   = bytesPerScanLine * bmp.bmHeight;
                    byte[] lpBits           = new byte[totalBytesReqd];

                    // Get the bitmap bits
                    int diRet = SafeNativeMethods.GetDIBits(hdcSrc, hBitmap, 0, bmp.bmHeight, lpBits,
                                                            ref lpbmi, NativeMethods.DIB_RGB_COLORS);
                    if (diRet == 0)
                    {
                        return(false);
                    }

                    // Set the destination coordiates depending on whether stretch-to-fit was chosen
                    int xDest, yDest, cxDest, cyDest;
                    if (bStretch)
                    {
                        xDest  = rect.left;
                        yDest  = rect.top;
                        cxDest = rect.right - rect.left;
                        cyDest = rect.bottom - rect.top;
                    }
                    else
                    {
                        xDest  = rect.left;
                        yDest  = rect.top;
                        cxDest = bmp.bmWidth;
                        cyDest = bmp.bmHeight;
                    }

                    // Paint the bitmap
                    int iRet = SafeNativeMethods.StretchDIBits(hdcDest,
                                                               xDest, yDest, cxDest, cyDest, 0, 0, bmp.bmWidth, bmp.bmHeight,
                                                               lpBits, ref lpbmi, NativeMethods.DIB_RGB_COLORS, NativeMethods.SRCCOPY);

                    if (iRet == NativeMethods.GDI_ERROR)
                    {
                        return(false);
                    }
                }
                finally
                {
                    Gdi32.DeleteObject(hNullBitmap);
                }

                return(true);
            }
Ejemplo n.º 4
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();
                }
            }
        }