C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

■94192 / 1階層)  コンボボックスの自動変換について
□投稿者/ KOZ (97回)-(2020/03/24(Tue) 15:22:58)
No94186 (sin さん) に返信
> 入力時の内容を保存し、リストオープン時に内容が変更された場合に
> もとに戻す方法以外で、「あい」のままで表示させる方法はないでしょうか?

ドロップダウンリスト表示中に、EDIT への WM_SETTEXT を無視すれば良いです。

このようなクラスを用意して

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

class ComboBoxHooker : NativeWindow
{
    public ComboBoxHooker(ComboBox owner) {
        Owner = owner;
        if (owner.IsHandleCreated) {
            Owner_HandleCreated(owner, EventArgs.Empty);
        }
        owner.HandleCreated += Owner_HandleCreated;
        owner.DropDown += Owner_DropDown;
        owner.DropDownClosed += Owner_DropDownClosed;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }

    [StructLayout(LayoutKind.Sequential)]
    class COMBOBOXINFO
    {
        public int cbSize;
        public RECT rcItem;
        public RECT rcButton;
        public int stateButton;
        public IntPtr hwndCombo;
        public IntPtr hwndItem;
        public IntPtr hwndList;
        public COMBOBOXINFO() {
            this.cbSize = Marshal.SizeOf(this);
        }
    }

    [DllImport("user32")]
    static extern bool GetComboBoxInfo(IntPtr hwndCombo, COMBOBOXINFO cbinfo);

    private bool dropDowned = false;

    private void Owner_DropDownClosed(object sender, EventArgs e) {
        dropDowned = false;
    }

    private void Owner_DropDown(object sender, EventArgs e) {
        dropDowned = true;
    }

    public ComboBox Owner { get; }

    private void Owner_HandleCreated(object sender, EventArgs e) {
        var cb = new COMBOBOXINFO();
        if (GetComboBoxInfo(((ComboBox)sender).Handle, cb)) {
            AssignHandle(cb.hwndItem);
        }
    }

    protected override void WndProc(ref Message m) {
        const int WM_NCDESTROY = 0x0082;
        const int WM_SETTEXT = 0x000C;
        switch (m.Msg) {
            case WM_NCDESTROY:
                base.WndProc(ref m);
                ReleaseHandle();
                break;
            case WM_SETTEXT:
                if (!dropDowned) {
                    base.WndProc(ref m);
                }
                break;

            default:
                base.WndProc(ref m);
                break;
        }
    }
}

こう使います。

public partial class Form1 : Form
{
    readonly ComboBoxHooker hooker;

    public Form1() {
        InitializeComponent();
        hooker = new ComboBoxHooker(comboBox1);
    }
}

編集キー/

前の記事(元になった記事) 次の記事(この記事の返信)
←コンボボックスの自動変換について /sin →Re[2]: コンボボックスの自動変換について /sin
 
上記関連ツリー

コンボボックスの自動変換について / sin (20/03/24(Tue) 11:49) #94186
コンボボックスの自動変換について / KOZ (20/03/24(Tue) 15:22) #94192 ←Now
  └ Re[2]: コンボボックスの自動変換について / sin (20/03/24(Tue) 16:44) #94199
    └ Re[3]: コンボボックスの自動変換について / KOZ (20/03/24(Tue) 17:16) #94200
      └ Re[4]: コンボボックスの自動変換について / sin (20/03/25(Wed) 13:20) #94214 解決済み

上記ツリーを一括表示 / 上記ツリーをトピック表示
 
上記の記事へ返信