トップ回答者
フォームのBackColor選択した際のコンボボックスに独自の色を追加したい。

質問
-
回答
-
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : FormBase // Formを継承していないとデザイナ上では反映できない { public Form1() { InitializeComponent(); } } public class FormBase : System.Windows.Forms.Form { //PropertyGridのドロップダウン時のエディタを変更する [Editor(typeof(ColorEditorEx), typeof(System.Drawing.Design.UITypeEditor))] [ColorEditorColors(0xff010203, 0xffff0000)] public override Color BackColor { get { return base.BackColor; } set { base.BackColor = value; } } } class ColorEditorColorsAttribute : Attribute { public ColorEditorColorsAttribute(params uint[] colors) { List<Color> list = new List<Color>(); foreach (uint ui in colors) { int i = unchecked((int)ui); list.Add(Color.FromArgb(i)); } Colors = new System.Collections.ObjectModel.ReadOnlyCollection<Color>(list); } public IList<Color> Colors { get; } } public class ColorEditorEx : System.Drawing.Design.ColorEditor //System.Drawing.Design.dll { public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { var item=(System.Windows.Forms.GridItem)context; var colors=item.PropertyDescriptor.Attributes.OfType<ColorEditorColorsAttribute>().FirstOrDefault()?.Colors; var editor = (System.Windows.Forms.Design.IWindowsFormsEditorService)provider.GetService(typeof(System.Windows.Forms.Design.IWindowsFormsEditorService)); var threadContext = System.Threading.SynchronizationContext.Current; if (threadContext == null) { threadContext = new System.Threading.SynchronizationContext(); System.Threading.SynchronizationContext.SetSynchronizationContext(threadContext); } TabControl tab = null; TabPage page = new TabPage(); page.Text = "てすと"; ListBox listBox = new ListBox(); listBox.SelectedIndexChanged += (s, e) => editor.CloseDropDown(); if (colors != null) { foreach (Color c in colors) { listBox.Items.Add(c); } } page.Controls.Add(listBox); threadContext.Post((o) => { var list = Win32API.GetCurrentThreadWindows(); foreach (IntPtr hwnd in list) { IntPtr owner = Win32API.GetOwnerWindow(hwnd); if (owner != IntPtr.Zero) { var control = System.Windows.Forms.Control.FromChildHandle(owner); if (control != null) { var children = Win32API.EnumChildWindows(hwnd); var controls = children.Select(h => System.Windows.Forms.Control.FromHandle(h)).OfType<Control>().ToArray(); if (controls.Count() > 0) { tab = controls.OfType<TabControl>().FirstOrDefault(); if (tab != null) { tab.TabPages.Add(page); break; } } } } } }, null); var ret = base.EditValue(context, provider, value); if (tab != null && page != null) { if (tab.SelectedTab == page) { ret = (Color)listBox.SelectedItem; } tab.TabPages.Remove(page); } return ret; } } } namespace WindowsFormsApp1 { using System.Runtime.InteropServices; class Win32API { private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [DllImport("kernel32.dll")] private static extern uint GetCurrentThreadId(); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd); public static IntPtr GetOwnerWindow(IntPtr hwnd) { return GetWindow(hwnd, 4); } public static List<IntPtr> GetCurrentThreadWindows() { List<IntPtr> list = new List<IntPtr>(); var id = GetCurrentThreadId(); EnumWindows((h, p) => { uint pid; uint tid; tid = GetWindowThreadProcessId(h, out pid); if (tid == id) { list.Add(h); } return true; }, IntPtr.Zero); return list; } public static List<IntPtr> EnumChildWindows(IntPtr hwnd) { List<IntPtr> list = new List<IntPtr>(); EnumChildWindows(hwnd, (h, p) => { list.Add(h); return true; }, IntPtr.Zero); return list; } } }
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク mogja 2020年9月25日 12:38
すべての返信
-
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : FormBase // Formを継承していないとデザイナ上では反映できない { public Form1() { InitializeComponent(); } } public class FormBase : System.Windows.Forms.Form { //PropertyGridのドロップダウン時のエディタを変更する [Editor(typeof(ColorEditorEx), typeof(System.Drawing.Design.UITypeEditor))] [ColorEditorColors(0xff010203, 0xffff0000)] public override Color BackColor { get { return base.BackColor; } set { base.BackColor = value; } } } class ColorEditorColorsAttribute : Attribute { public ColorEditorColorsAttribute(params uint[] colors) { List<Color> list = new List<Color>(); foreach (uint ui in colors) { int i = unchecked((int)ui); list.Add(Color.FromArgb(i)); } Colors = new System.Collections.ObjectModel.ReadOnlyCollection<Color>(list); } public IList<Color> Colors { get; } } public class ColorEditorEx : System.Drawing.Design.ColorEditor //System.Drawing.Design.dll { public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { var item=(System.Windows.Forms.GridItem)context; var colors=item.PropertyDescriptor.Attributes.OfType<ColorEditorColorsAttribute>().FirstOrDefault()?.Colors; var editor = (System.Windows.Forms.Design.IWindowsFormsEditorService)provider.GetService(typeof(System.Windows.Forms.Design.IWindowsFormsEditorService)); var threadContext = System.Threading.SynchronizationContext.Current; if (threadContext == null) { threadContext = new System.Threading.SynchronizationContext(); System.Threading.SynchronizationContext.SetSynchronizationContext(threadContext); } TabControl tab = null; TabPage page = new TabPage(); page.Text = "てすと"; ListBox listBox = new ListBox(); listBox.SelectedIndexChanged += (s, e) => editor.CloseDropDown(); if (colors != null) { foreach (Color c in colors) { listBox.Items.Add(c); } } page.Controls.Add(listBox); threadContext.Post((o) => { var list = Win32API.GetCurrentThreadWindows(); foreach (IntPtr hwnd in list) { IntPtr owner = Win32API.GetOwnerWindow(hwnd); if (owner != IntPtr.Zero) { var control = System.Windows.Forms.Control.FromChildHandle(owner); if (control != null) { var children = Win32API.EnumChildWindows(hwnd); var controls = children.Select(h => System.Windows.Forms.Control.FromHandle(h)).OfType<Control>().ToArray(); if (controls.Count() > 0) { tab = controls.OfType<TabControl>().FirstOrDefault(); if (tab != null) { tab.TabPages.Add(page); break; } } } } } }, null); var ret = base.EditValue(context, provider, value); if (tab != null && page != null) { if (tab.SelectedTab == page) { ret = (Color)listBox.SelectedItem; } tab.TabPages.Remove(page); } return ret; } } } namespace WindowsFormsApp1 { using System.Runtime.InteropServices; class Win32API { private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [DllImport("kernel32.dll")] private static extern uint GetCurrentThreadId(); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd); public static IntPtr GetOwnerWindow(IntPtr hwnd) { return GetWindow(hwnd, 4); } public static List<IntPtr> GetCurrentThreadWindows() { List<IntPtr> list = new List<IntPtr>(); var id = GetCurrentThreadId(); EnumWindows((h, p) => { uint pid; uint tid; tid = GetWindowThreadProcessId(h, out pid); if (tid == id) { list.Add(h); } return true; }, IntPtr.Zero); return list; } public static List<IntPtr> EnumChildWindows(IntPtr hwnd) { List<IntPtr> list = new List<IntPtr>(); EnumChildWindows(hwnd, (h, p) => { list.Add(h); return true; }, IntPtr.Zero); return list; } } }
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク mogja 2020年9月25日 12:38
-
mogjaさん、こんにちは。フォーラムオペレーターのKumoです。
MSDNフォーラムにご投稿くださいましてありがとうございます。
ご質問いただいた件ですが、その後いかがでしょうか。
gekkaさんから寄せられた投稿はお役に立ちましたか。
参考になった投稿には [回答としてマーク] をお願い致します。
設定いただくことで、
他のユーザーもお役に立つ回答を見つけやすくなります。
お手数ですが、ご協力の程どうかよろしくお願いいたします。MSDN/ TechNet Community Support Kumo ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~