C#でWindows Form で画面を作成しています。
そこで、画面上で右クリックしたときにコンテキストメニューが表示されないようにする方法がわかりません。
テキストボックスは、ShortcutsEnabledプロパティをfalseに設定すれば非表示にすることができたのですが、
コンボボックスは同じ方法は無理でした。
何方か、ご存じの方はいませんか?
コンボボックスには、ShortcutsEnabledプロパティが存在しませんでした。
でも、読み取り専用 DropDownStyle 以外の方法でコンテキストメニュー非表示にする方法はないでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ComboBox は、いくつかのウインドウの集合体なのですが、コンテキストメニューを表示しないようにするには、Edit ウインドウに飛んでくる WM_CONTEXTMENU を無視します。
(1) Edit ウインドウのウインドウハンドルは、GetComboBoxInfo API で求める
GetComboBoxInfo API は Windows 2000 以降でしか使えません。
.NET の ComBobox のソースでは、Windows 95 もターゲットに入っていたので GetWindow を使って求めていますが、いまさら Windows 95 や Me を選択することはないので問題ないでしょう。
(2) メッセージを監視するには NativeWindow クラスを継承したクラスを作成する。
(3) 操作するプロパティによってはウインドウが再作成されるのを考慮する。
以上をふまえて、以下のようなクラスを作成します。
C#
1using System; 2using System.Runtime.InteropServices; 3using System.Windows.Forms; 4 5public class ComboBoxEditWindow : NativeWindow 6{ 7 [StructLayout(LayoutKind.Sequential)] 8 private struct RECT 9 { 10 public int Left, Top, Right, Bottom; 11 } 12 13 [StructLayout(LayoutKind.Sequential)] 14 private class ComboBoxInfo 15 { 16 public int Size; 17 public RECT RectItem; 18 public RECT RectButton; 19 public int ButtonState; 20 public IntPtr ComboBoxHandle; 21 public IntPtr EditBoxHandle; 22 public IntPtr ListBoxHandle; 23 public ComboBoxInfo() { 24 this.Size = Marshal.SizeOf(this); 25 } 26 } 27 28 [DllImport("user32")] 29 private static extern bool GetComboBoxInfo(HandleRef hwndCombo, 30 ComboBoxInfo cbinfo); 31 32 private const int 33 WM_CONTEXTMENU = 0x007B, 34 WM_NCDESTROY = 0x0082; 35 36 public ComboBoxEditWindow(ComboBox owner) { 37 if (owner.IsHandleCreated) { 38 Owner_HandleCreated(owner, EventArgs.Empty); 39 } 40 owner.HandleCreated += Owner_HandleCreated; 41 } 42 43 private void Owner_HandleCreated(object sender, EventArgs e) { 44 var ci = new ComboBoxInfo(); 45 var hwnd = new HandleRef(sender, ((Control)sender).Handle); 46 if (GetComboBoxInfo(hwnd, ci)) { 47 AssignHandle(ci.EditBoxHandle); 48 } 49 } 50 51 protected override void WndProc(ref Message m) { 52 switch (m.Msg) { 53 case WM_NCDESTROY: 54 base.WndProc(ref m); 55 ReleaseHandle(); 56 break; 57 case WM_CONTEXTMENU: 58 // 無視 59 break; 60 default: 61 base.WndProc(ref m); 62 break; 63 } 64 } 65} 66
使い方は以下のとおりです。
C#
1public partial class Form1 : Form 2{ 3 private ComboBoxEditWindow m_EditWindow; 4 5 public Form1() { 6 InitializeComponent(); 7 m_EditWindow = new ComboBoxEditWindow(comboBox1); 8 } 9}
投稿2019/11/04 14:24
総合スコア2707
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。