예제 #1
0
        public static ColorProfile FromMemory(byte[] buffer)
        {
            if (buffer == null)
            {
                throw new ArgumentException(nameof(buffer));
            }

            using (var mem = new ComMemory(buffer))
            {
                var prof = new PROFILE();
                prof.dwType       = PROFILE_MEMBUFFER;
                prof.pProfileData = mem.Pointer;
                prof.cbDataSize   = mem.Size;
                var handle = OpenColorProfile(ref prof, PROFILE_READ, FILE_SHARE_READ, OPEN_EXISTING);
                if (handle == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                try
                {
                    return(new ColorProfile(handle));
                }
                finally
                {
                    CloseColorProfile(handle);
                }
            }
        }
예제 #2
0
            public HRESULT GetCurrentFontFile(out IDWriteFontFile fontFile)
            {
                DWriteFontFile file;

                try
                {
                    file = _enumerator.Current;
                }
                catch (Exception e)
                {
                    ComError.SetError(e.GetAllMessages());
                    fontFile = null;
                    return(HRESULTS.DISP_E_EXCEPTION);
                }

                if (file is DWriteFontStreamFile sf && sf.FilePath != null)
                {
                    using (var mem = new ComMemory(Marshal.SizeOf <long>()))
                    {
                        if (sf.LastWriteTime.HasValue)
                        {
                            Marshal.WriteInt64(mem.Pointer, sf.LastWriteTime.Value.ToFileTime());
                        }

                        var ptr = sf.LastWriteTime.HasValue ? mem.Pointer : IntPtr.Zero;
                        return(_factory.CreateFontFileReference(sf.FilePath, ptr, out fontFile));
                    }
                }

                var stream = new FontFileStream(file);

                _loader.AddStream(stream);
                return(_factory.CreateCustomFontFileReference(stream.Key, (uint)stream.KeySize, _loader, out fontFile));
            }
예제 #3
0
        public static IComObject <IWICBitmapDecoder> CreateDecoderFromFilename(this IWICImagingFactory factory, string fileName, Guid?guidVendor = null, FileAccess desiredAccess = FileAccess.Read, WICDecodeOptions metadataOptions = WICDecodeOptions.WICDecodeMetadataCacheOnDemand)
        {
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            if (fileName == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            const uint GENERIC_READ  = 0x80000000;
            const uint GENERIC_WRITE = 0x40000000;

            using (var guid = new ComMemory(guidVendor))
            {
                uint acc = 0;
                if (desiredAccess.HasFlag(FileAccess.Read))
                {
                    acc |= GENERIC_READ;
                }

                if (desiredAccess.HasFlag(FileAccess.Read))
                {
                    acc |= GENERIC_WRITE;
                }

                factory.CreateDecoderFromFilename(fileName, guid.Pointer, acc, metadataOptions, out var value).ThrowOnError();
                return(new ComObject <IWICBitmapDecoder>(value));
            }
        }
예제 #4
0
        public static string GetFontFamilyName(this IDWriteTextLayout format, uint currentPosition = 0, DWRITE_TEXT_RANGE?range = null)
        {
            if (format == null)
            {
                throw new ArgumentNullException(nameof(format));
            }

            if (range == null)
            {
                return(call(IntPtr.Zero));
            }

            using (var mem = new ComMemory(range.Value))
            {
                return(call(mem.Pointer));
            }

            string call(IntPtr ptr)
            {
                format.GetFontFamilyNameLength(currentPosition, out var len, ptr).ThrowOnError();
                var s = new string('\0', (int)len);

                format.GetFontFamilyName(currentPosition, s, len + 1, ptr).ThrowOnError();
                return(s);
            }
        }
예제 #5
0
        public static IReadOnlyList <ColorProfile> GetColorProfiles(string machineName = null)
        {
            var list     = new List <ColorProfile>();
            var size     = 0;
            var enumType = new ENUMTYPE();

            enumType.dwSize    = Marshal.SizeOf(enumType);
            enumType.dwVersion = ENUM_TYPE_VERSION;
            if (!EnumColorProfiles(machineName, ref enumType, IntPtr.Zero, ref size, out var count))
            {
                var gle = Marshal.GetLastWin32Error();
                if (gle != ERROR_INSUFFICIENT_BUFFER)
                {
                    throw new Win32Exception(gle);
                }
            }

            if (count > 0)
            {
                using (var mem = new ComMemory(size))
                {
                    if (!EnumColorProfiles(machineName, ref enumType, mem.Pointer, ref size, out count))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    var ptr = mem.Pointer;
                    do
                    {
                        var str = Marshal.PtrToStringUni(ptr);
                        if (string.IsNullOrEmpty(str))
                        {
                            break;
                        }

                        try
                        {
                            var profile = FromFileName(str, machineName);
                            if (profile != null)
                            {
                                list.Add(profile);
                            }
                        }
                        catch
                        {
                            // do nothing
                        }
                        ptr += (str.Length + 1) * 2;
                    }while (true);
                }
            }
            return(list);
        }
예제 #6
0
        public static void SetDebugObjectName(this ID3D11DeviceChild child, string name)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException(null, nameof(name));
            }

            using (var mem = new ComMemory(name))
            {
                child.SetPrivateData(WKPDID_D3DDebugObjectNameW, (uint)(name.Length * 2), mem.Pointer).ThrowOnError();
            }
        }
예제 #7
0
        public static IComObject <IWICBitmapLock> Lock(this IWICBitmap bitmap, WICBitmapLockFlags flags, WICRect?rect = null)
        {
            if (bitmap == null)
            {
                throw new ArgumentNullException(nameof(bitmap));
            }

            using (var mem = new ComMemory(rect))
            {
                bitmap.Lock(mem.Pointer, flags, out var value).ThrowOnError();
                return(new ComObject <IWICBitmapLock>(value));
            }
        }
예제 #8
0
        public static IComObject <IWICBitmapDecoder> CreateDecoderFromFileHandle(this IWICImagingFactory factory, IntPtr handle, Guid?guidVendor = null, WICDecodeOptions metadataOptions = WICDecodeOptions.WICDecodeMetadataCacheOnDemand)
        {
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            using (var guid = new ComMemory(guidVendor))
            {
                factory.CreateDecoderFromFileHandle(handle, guid.Pointer, metadataOptions, out var value).ThrowOnError();
                return(new ComObject <IWICBitmapDecoder>(value));
            }
        }
예제 #9
0
        public static IComObject <ID3D11Buffer> CreateBuffer(this ID3D11Device device, D3D11_BUFFER_DESC desc, D3D11_SUBRESOURCE_DATA?initialData = null)
        {
            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }

            using (var mem = new ComMemory(initialData))
            {
                device.CreateBuffer(ref desc, mem.Pointer, out var buffer).ThrowOnError();
                return(new ComObject <ID3D11Buffer>(buffer));
            }
        }
예제 #10
0
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposedValue)
            {
                if (disposing)
                {
                    // dispose managed state (managed objects).
                }

                ComMemory.Free(ref _vtablePointer);
                ComMemory.Free(ref _unk);
                _disposedValue = true;
            }
        }
예제 #11
0
        public static void SetDebugObjectName(this ID3D11DeviceChild child, string name)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException(null, nameof(name));
            }

            using (var mem = new ComMemory(name))
            {
#pragma warning disable CA1062 // Validate arguments of public methods
                _ = child.SetPrivateData(WKPDID_D3DDebugObjectNameW, (uint)(name.Length * 2), mem.Pointer).ThrowOnError();
#pragma warning restore CA1062 // Validate arguments of public methods
            }
        }
예제 #12
0
        public static ComObject <IDXGIOutputDuplication> DuplicateOutput(this IDXGIOutput1 output, object device, bool throwOnError = true)
        {
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }

            device = ComObject.Unwrap(device);

            // this wonderful magic (mess) is because of a horrible bug in DXGI
            // https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/0c28328a-100a-4d6f-9a08-44a452d3ca6a/idxgioutputduplication-implementation-bug?forum=windowssdk#0c28328a-100a-4d6f-9a08-44a452d3ca6a
            output.DuplicateOutput(device, out var unk).ThrowOnError(throwOnError);
            if (unk == IntPtr.Zero)
            {
                return(null);
            }

            // we copy the original COM's vtable to our process
            var vtablePtr = Marshal.ReadIntPtr(unk);
            var vtable    = new IDXGIOutputDuplicationVTable();

            Marshal.PtrToStructure(vtablePtr, vtable);

            // patch QueryInterface so it works (route to our code)
            var wrapper = new Wrapper(unk);

            vtable.QueryInterfacePtr = Marshal.GetFunctionPointerForDelegate <QueryInterfaceFn>(wrapper.QueryInterface);
            using (var newVtablePtr = new ComMemory(Marshal.SizeOf <IDXGIOutputDuplicationVTable>()))
            {
                Marshal.StructureToPtr(vtable, newVtablePtr.Pointer, false);

                // create a new vtable for the CLR
                using (var newUnk = new ComMemory(IntPtr.Size))
                {
                    Marshal.WriteIntPtr(newUnk.Pointer, newVtablePtr.Pointer);

                    var dup = (IDXGIOutputDuplication)Marshal.GetObjectForIUnknown(newUnk.Pointer);
                    return(new ComObject <IDXGIOutputDuplication>(dup));
                }
            }
        }
예제 #13
0
        public static void WriteSource(this IWICBitmapFrameEncode frame, IWICBitmapSource source, WICRect?sourceRectangle = null)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            using (var mem = new ComMemory(sourceRectangle))
            {
                frame.WriteSource(source, mem.Pointer).ThrowOnError();
            }
        }
예제 #14
0
        public static IComObject <ID3D11UnorderedAccessView> CreateUnorderedAccessView(this ID3D11Device device, ID3D11Resource resource, D3D11_UNORDERED_ACCESS_VIEW_DESC?desc = null)
        {
            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }

            if (resource == null)
            {
                throw new ArgumentNullException(nameof(resource));
            }

            using (var mem = new ComMemory(desc))
            {
                device.CreateUnorderedAccessView(resource, mem.Pointer, out var view).ThrowOnError();
                return(new ComObject <ID3D11UnorderedAccessView>(view));
            }
        }
        public static D3D11_MAPPED_SUBRESOURCE Map(this ID3D11DeviceContext context, ID3D11Resource resource, int subResource, D3D11_MAP mapType, D3D11_MAP_FLAG mapFlag = 0)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (resource == null)
            {
                throw new ArgumentNullException(nameof(resource));
            }

            using (var ptr = new ComMemory(Marshal.SizeOf <D3D11_MAPPED_SUBRESOURCE>()))
            {
                context.Map(resource, (uint)subResource, mapType, (uint)mapFlag, ptr.Pointer).ThrowOnError();
                return(ptr.ToStructure <D3D11_MAPPED_SUBRESOURCE>());
            }
        }
예제 #16
0
        public static IComObject <ID3D11DepthStencilView> CreateDepthStencilView(this ID3D11Device device, ID3D11Resource resource, D3D11_DEPTH_STENCIL_VIEW_DESC?desc = null)
        {
            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }

            if (resource == null)
            {
                throw new ArgumentNullException(nameof(resource));
            }

            using (var mem = new ComMemory(desc))
            {
                device.CreateDepthStencilView(resource, mem.Pointer, out var view).ThrowOnError();
                return(new ComObject <ID3D11DepthStencilView>(view));
            }
        }
예제 #17
0
        public static IComObject <ID3D11ShaderResourceView> CreateShaderResourceView(this ID3D11Device device, ID3D11Resource resource, D3D11_SHADER_RESOURCE_VIEW_DESC?desc = null)
        {
            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }

            if (resource == null)
            {
                throw new ArgumentNullException(nameof(resource));
            }

            using (var mem = new ComMemory(desc))
            {
                device.CreateShaderResourceView(resource, mem.Pointer, out var view).ThrowOnError();
                return(new ComObject <ID3D11ShaderResourceView>(view));
            }
        }
예제 #18
0
        public static IComObject <ID2D1BitmapRenderTarget> CreateCompatibleRenderTarget(this ID2D1RenderTarget context, D2D_SIZE_F?desiredSize = null, D2D_SIZE_U?desiredPixelSize = null, D2D1_PIXEL_FORMAT?desiredFormat = null, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options = D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS.D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            using (var desiredSizeMem = new ComMemory(desiredSize))
            {
                using (var desiredPixelSizeMem = new ComMemory(desiredPixelSize))
                {
                    using (var desiredFormatMem = new ComMemory(desiredFormat))
                    {
                        context.CreateCompatibleRenderTarget(desiredSizeMem.Pointer, desiredPixelSizeMem.Pointer, desiredFormatMem.Pointer, options, out var target).ThrowOnError();
                        return(new ComObject <ID2D1BitmapRenderTarget>(target));
                    }
                }
            }
        }
예제 #19
0
        public static IComObject <IDWriteFontCollection> GetFontCollection(this IDWriteTextLayout format, uint currentPosition = 0, DWRITE_TEXT_RANGE?range = null)
        {
            if (format == null)
            {
                throw new ArgumentNullException(nameof(format));
            }

            if (range == null)
            {
                return(call(IntPtr.Zero));
            }

            using (var mem = new ComMemory(range.Value))
            {
                return(call(mem.Pointer));
            }

            ComObject <IDWriteFontCollection> call(IntPtr ptr)
            {
                format.GetFontCollection(currentPosition, out var coll, ptr).ThrowOnError();
                return(new ComObject <IDWriteFontCollection>(coll));
            }
        }
예제 #20
0
        public TextHostThunk(TextHost host)
        {
            if (host == null)
            {
                throw new ArgumentNullException(nameof(host));
            }

            _host  = host;
            _table = new ITextHost2VTable();
            _table.QueryInterface                 = Marshal.GetFunctionPointerForDelegate(_queryInterface);
            _table.AddRef                         = Marshal.GetFunctionPointerForDelegate(_addRef);
            _table.Release                        = Marshal.GetFunctionPointerForDelegate(_release);
            _table.TxGetDC                        = Marshal.GetFunctionPointerForDelegate(_txGetDC);
            _table.TxReleaseDC                    = Marshal.GetFunctionPointerForDelegate(_txReleaseDC);
            _table.TxShowScrollBar                = Marshal.GetFunctionPointerForDelegate(_txShowScrollBar);
            _table.TxEnableScrollBar              = Marshal.GetFunctionPointerForDelegate(_txEnableScrollBar);
            _table.TxSetScrollRange               = Marshal.GetFunctionPointerForDelegate(_txSetScrollRange);
            _table.TxSetScrollPos                 = Marshal.GetFunctionPointerForDelegate(_txSetScrollPos);
            _table.TxInvalidateRect               = Marshal.GetFunctionPointerForDelegate(_txInvalidateRect);
            _table.TxViewChange                   = Marshal.GetFunctionPointerForDelegate(_txViewChange);
            _table.TxCreateCaret                  = Marshal.GetFunctionPointerForDelegate(_txCreateCaret);
            _table.TxShowCaret                    = Marshal.GetFunctionPointerForDelegate(_txShowCaret);
            _table.TxSetCaretPos                  = Marshal.GetFunctionPointerForDelegate(_txSetCaretPos);
            _table.TxSetTimer                     = Marshal.GetFunctionPointerForDelegate(_txSetTimer);
            _table.TxKillTimer                    = Marshal.GetFunctionPointerForDelegate(_txKillTimer);
            _table.TxScrollWindowEx               = Marshal.GetFunctionPointerForDelegate(_txScrollWindowEx);
            _table.TxSetCapture                   = Marshal.GetFunctionPointerForDelegate(_txSetCapture);
            _table.TxSetFocus                     = Marshal.GetFunctionPointerForDelegate(_txSetFocus);
            _table.TxSetCursor                    = Marshal.GetFunctionPointerForDelegate(_txSetCursor);
            _table.TxScreenToClient               = Marshal.GetFunctionPointerForDelegate(_txScreenToClient);
            _table.TxClientToScreen               = Marshal.GetFunctionPointerForDelegate(_txClientToScreen);
            _table.TxActivate                     = Marshal.GetFunctionPointerForDelegate(_txActivate);
            _table.TxDeactivate                   = Marshal.GetFunctionPointerForDelegate(_txDeactivate);
            _table.TxGetClientRect                = Marshal.GetFunctionPointerForDelegate(_txGetClientRect);
            _table.TxGetViewInset                 = Marshal.GetFunctionPointerForDelegate(_txGetViewInset);
            _table.TxGetCharFormat                = Marshal.GetFunctionPointerForDelegate(_txGetCharFormat);
            _table.TxGetParaFormat                = Marshal.GetFunctionPointerForDelegate(_txGetParaFormat);
            _table.TxGetSysColor                  = Marshal.GetFunctionPointerForDelegate(_txGetSysColor);
            _table.TxGetBackStyle                 = Marshal.GetFunctionPointerForDelegate(_txGetBackStyle);
            _table.TxGetMaxLength                 = Marshal.GetFunctionPointerForDelegate(_txGetMaxLength);
            _table.TxGetScrollBars                = Marshal.GetFunctionPointerForDelegate(_txGetScrollBars);
            _table.TxGetPasswordChar              = Marshal.GetFunctionPointerForDelegate(_txGetPasswordChar);
            _table.TxGetAcceleratorPos            = Marshal.GetFunctionPointerForDelegate(_txGetAcceleratorPos);
            _table.TxGetExtent                    = Marshal.GetFunctionPointerForDelegate(_txGetExtent);
            _table.OnTxCharFormatChange           = Marshal.GetFunctionPointerForDelegate(_onTxCharFormatChange);
            _table.OnTxParaFormatChange           = Marshal.GetFunctionPointerForDelegate(_onTxParaFormatChange);
            _table.TxGetPropertyBits              = Marshal.GetFunctionPointerForDelegate(_txGetPropertyBits);
            _table.TxNotify                       = Marshal.GetFunctionPointerForDelegate(_txNotify);
            _table.TxImmGetContext                = Marshal.GetFunctionPointerForDelegate(_txImmGetContext);
            _table.TxImmReleaseContext            = Marshal.GetFunctionPointerForDelegate(_txImmReleaseContext);
            _table.TxGetSelectionBarWidth         = Marshal.GetFunctionPointerForDelegate(_txGetSelectionBarWidth);
            _table.TxIsDoubleClickPending         = Marshal.GetFunctionPointerForDelegate(_txIsDoubleClickPending);
            _table.TxGetWindow                    = Marshal.GetFunctionPointerForDelegate(_txGetWindow);
            _table.TxSetForegroundWindow          = Marshal.GetFunctionPointerForDelegate(_txSetForegroundWindow);
            _table.TxGetPalette                   = Marshal.GetFunctionPointerForDelegate(_txGetPalette);
            _table.TxGetEastAsianFlags            = Marshal.GetFunctionPointerForDelegate(_txGetEastAsianFlags);
            _table.TxSetCursor2                   = Marshal.GetFunctionPointerForDelegate(_txSetCursor2);
            _table.TxFreeTextServicesNotification = Marshal.GetFunctionPointerForDelegate(_txFreeTextServicesNotification);
            _table.TxGetEditStyle                 = Marshal.GetFunctionPointerForDelegate(_txGetEditStyle);
            _table.TxGetWindowStyles              = Marshal.GetFunctionPointerForDelegate(_txGetWindowStyles);
            _table.TxShowDropCaret                = Marshal.GetFunctionPointerForDelegate(_txShowDropCaret);
            _table.TxDestroyCaret                 = Marshal.GetFunctionPointerForDelegate(_txDestroyCaret);
            _table.TxGetHorzExtent                = Marshal.GetFunctionPointerForDelegate(_txGetHorzExtent);

            _vtablePointer = ComMemory.AllocAndCopy(_table);
            _unk           = ComMemory.AllocAndCopy(_vtablePointer);
            _hosts[_unk]   = this;
        }
예제 #21
0
        public static void SetValueByName(this ID2D1Properties properties, string name, object value)
        {
            if (properties == null)
            {
                throw new ArgumentNullException(nameof(properties));
            }

            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (value is null)
            {
                SetValueByName(properties, name, null);
                return;
            }

            var type = value.GetType();

            if (type.IsEnum)
            {
                value = (int)value;
            }

            if (value is bool bv)
            {
                SetValueByName(properties, name, bv);
                return;
            }

            if (value is Guid gv)
            {
                SetValueByName(properties, name, gv);
                return;
            }

            if (value is float fv)
            {
                SetValueByName(properties, name, fv);
                return;
            }

            if (value is uint uiv)
            {
                SetValueByName(properties, name, uiv);
                return;
            }

            if (value is int iv)
            {
                SetValueByName(properties, name, iv);
                return;
            }

            if (value is byte[] byv)
            {
                SetValueByName(properties, name, byv);
                return;
            }

            if (value is string sv)
            {
                SetValueByName(properties, name, sv);
                return;
            }

            if (value is ValueType vt) // matrix & vector types
            {
                using (var mem = new ComMemory(vt))
                {
                    SetValueByName(properties, name, mem.ToArray());
                    return;
                }
            }
            throw new NotSupportedException("Value of type '" + value.GetType().FullName + "' is not supported.");
        }
예제 #22
0
        public static void SetValue(this ID2D1Properties properties, int index, object value)
        {
            if (properties == null)
            {
                throw new ArgumentNullException(nameof(properties));
            }

            if (value is null)
            {
                SetValue(properties, index, null);
                return;
            }

            if (value is bool bv)
            {
                SetValue(properties, index, bv);
                return;
            }

            if (value is Guid gv)
            {
                SetValue(properties, index, gv);
                return;
            }

            if (value is float fv)
            {
                SetValue(properties, index, fv);
                return;
            }

            if (value is uint uiv)
            {
                SetValue(properties, index, uiv);
                return;
            }

            if (value is int iv)
            {
                SetValue(properties, index, iv);
                return;
            }

            if (value is byte[] byv)
            {
                SetValue(properties, index, byv);
                return;
            }

            if (value is string sv)
            {
                SetValue(properties, index, sv);
                return;
            }

            if (value is ValueType vt)
            {
                using (var mem = new ComMemory(vt))
                {
                    SetValue(properties, index, mem.ToArray());
                    return;
                }
            }
            throw new NotSupportedException("Value of type '" + value.GetType().FullName + "' is not supported.");
        }