| File: System\Windows\Forms\ComponentModel\COM2Interop\COM2ComponentEditor.cs | Web Access |
| Project: src\winforms\src\System.Windows.Forms\System.Windows.Forms.csproj (System.Windows.Forms) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; using System.Runtime.InteropServices; using System.Windows.Forms.Design; using Windows.Win32.System.Com; using Windows.Win32.System.Ole; namespace System.Windows.Forms.ComponentModel.Com2Interop; internal sealed class Com2ComponentEditor : WindowsFormsComponentEditor { public static unsafe bool NeedsComponentEditor(object comObject) { using var propertyBrowsing = ComHelpers.TryGetComScope<IPerPropertyBrowsing>(comObject, out HRESULT hr); if (hr.Succeeded) { // Check for a property page. Guid guid = Guid.Empty; hr = propertyBrowsing.Value->MapPropertyToPage(PInvoke.MEMBERID_NIL, &guid); if (hr.Succeeded && !guid.Equals(Guid.Empty)) { return true; } } using var propertyPages = ComHelpers.TryGetComScope<ISpecifyPropertyPages>(comObject, out hr); if (hr.Succeeded) { CAUUID uuids = default; try { hr = propertyPages.Value->GetPages(&uuids); return hr.Succeeded && uuids.cElems > 0; } finally { if (uuids.pElems is not null) { Marshal.FreeCoTaskMem((IntPtr)uuids.pElems); } } } return false; } public override unsafe bool EditComponent(ITypeDescriptorContext? context, object obj, IWin32Window? parent) { HWND handle = parent is null ? HWND.Null : (HWND)parent.Handle; // Try to get the page guid using var propertyBrowsing = ComHelpers.TryGetComScope<IPerPropertyBrowsing>(obj, out HRESULT hr); if (hr.Succeeded) { // Check for a property page. Guid guid = Guid.Empty; hr = propertyBrowsing.Value->MapPropertyToPage(PInvoke.MEMBERID_NIL, &guid); if (hr.Succeeded & !guid.Equals(Guid.Empty)) { using var unknown = ComHelpers.GetComScope<IUnknown>(obj); fixed (char* c = "PropertyPages") { PInvoke.OleCreatePropertyFrame( handle, 0, 0, (PCWSTR)c, 1, unknown, 1, &guid, PInvokeCore.GetThreadLocale(), 0, null).ThrowOnFailure(); } return true; } } using var propertyPages = ComHelpers.TryGetComScope<ISpecifyPropertyPages>(obj, out hr); if (hr.Succeeded) { try { CAUUID uuids = default; hr = propertyPages.Value->GetPages(&uuids); if (!hr.Succeeded || uuids.cElems == 0) { return false; } using var unknown = ComHelpers.GetComScope<IUnknown>(obj); try { fixed (char* c = "PropertyPages") { PInvoke.OleCreatePropertyFrame( handle, 0, 0, (PCWSTR)c, 1, unknown, uuids.cElems, uuids.pElems, PInvokeCore.GetThreadLocale(), 0, null).ThrowOnFailure(); return true; } } finally { if (uuids.pElems is not null) { Marshal.FreeCoTaskMem((nint)uuids.pElems); } } } catch (Exception ex) { if (!context.TryGetService(out IUIService? uiService)) { RTLAwareMessageBox.Show( null, SR.ErrorPropertyPageFailed, SR.PropertyGridTitle, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0); } else { uiService.ShowError(ex, SR.ErrorPropertyPageFailed); } } } return false; } }