public unsafe static RECT[] GetRegionRects(RGNDATAHEADER *regionData)
            {
                if (regionData is null || regionData->nCount == 0)
                {
                    return(Array.Empty <RECT>());
                }

                // Region RECTs directly follow the header
                return(new Span <RECT>((byte *)regionData + regionData->dwSize, (int)regionData->nCount).ToArray());
            }
示例#2
0
        public static unsafe RECT[] RectsFromRegion(IntPtr hRgn)
        {
            RECT[] rects = new RECT[0];

            // First we call GetRegionData() with a null buffer.
            // The return from this call should be the size of buffer
            // we need to allocate in order to receive the data.
            int dataSize = WinGdiApi.GetRegionData(hRgn, 0, IntPtr.Zero);

            if (dataSize != 0)
            {
                IntPtr bytes = IntPtr.Zero;

                // Allocate as much space as the GetRegionData call
                // said was needed
                bytes = Marshal.AllocCoTaskMem(dataSize);

                // Now, make the call again to actually get the data
                int retValue = WinGdiApi.GetRegionData(hRgn, dataSize, bytes);

                // From here on out, we have the data in a buffer, and we
                // just need to convert it into a form that is more useful
                // Since pointers are used, this whole routine is 'unsafe'
                // It's a small sacrifice to make in order to get this to work.
                // [RBS] Added missing second pointer identifier
                RGNDATAHEADER *header = (RGNDATAHEADER *)bytes;

                if (header->iType == 1)
                {
                    rects = new RECT[header->nCount];

                    // The rectangle data follows the header, so we offset the specified
                    // header size and start reading rectangles.
                    int rectOffset = header->dwSize;
                    for (int i = 0; i < header->nCount; i++)
                    {
                        // simple assignment from the buffer to our array of rectangles
                        // will give us what we want.
                        rects[i] = *((RECT *)((byte *)bytes + rectOffset + (Marshal.SizeOf(typeof(RECT)) * i)));
                    }
                }
            }

            // Return the rectangles
            return(rects);
        }