6

WinForms でカスタム AutoCompleteTextBox コントロールを作成しようとしています。基本的な TextBox によって提供される AutoComplete は、 ではなく のみで結果を提供し(string).StartsWithます(string).Contains

オートコンプリートの検索結果をListBox別の にドッキングして表示していFormます。Form次を使用して、最初にフォーカスを盗むのを防ぐことができます。

protected override bool ShowWithoutActivation
{
   get { return true; }
}

次に、次の方法でメソッドをFormオーバーライドすることで、 が完全にフォーカスされるのを防ぐことができます。WndProc

protected override void WndProc( ref Message m )
{
    base.WndProc( ref m );
    switch ( m.Msg )
    {
        case WM_MOUSEACTIVATE:
            m.Result = ( IntPtr ) MA_NOACTIVATEANDEAT;
            break;

        default:
            break;
    }

これを行うと、 にListBox含まれる はイベントFormを受け取りますが、イベントは受け取りMouseMovedませんMouseClicked

justMA_NOACTIVATEANDEATに変更するMA_NOACTIVATEと、マウス イベントが に渡されListBoxますが、 をクリックすると、 が存在するListBoxからフォーカスが奪われます -Formが存在する 'フローティング'にListBox渡されます。FormListBox

内でイベントを取得しながら、「フローティング」Formが「メイン」からフォーカスを奪うのを防ぐ方法はありますか?FormMouseClickListBox

4

3 に答える 3

0

フローティングフォームを次のように変換Usercontrolします:-リストボックスをプルしてClickイベントにフックし、フォーカスのシナリオをシミュレートします。

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

namespace WindowsFormsApplication3
{
    public partial class InactiveForm : UserControl
    {
        private const int WS_EX_TOOLWINDOW = 0x00000080;
        private const int WS_EX_NOACTIVATE = 0x08000000;
        private const int WS_EX_TOPMOST = 0x00000008;


        [DllImport("user32")]
        public static extern int SetParent
         (IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32")]
        public static extern int ShowWindow
         (IntPtr hWnd, int nCmdShow);


        protected override CreateParams CreateParams
        {
            get
            {

                CreateParams p = base.CreateParams;
                p.ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST);
                p.Parent = IntPtr.Zero;
                return p;
            }
        }

        public InactiveForm()
        {
            InitializeComponent();
        }

        public new void Show()
        {
            if (this.Handle == IntPtr.Zero) base.CreateControl();

            SetParent(base.Handle, IntPtr.Zero);
            ShowWindow(base.Handle, 1);
        }


        private void OnListBoxClicked(object sender, EventArgs e)
        {
            MessageBox.Show("Clicked List Box on floating control");

        }
    }
}

MainFormのコード(ボタンとそのクリックハンドラーがアタッチされている):-

これにより、ListBoxを使用してフローティングコントロールが呼び出されます。

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            InactiveForm f = new InactiveForm();
             f.Show();
        }
    }
}

UserControl(ボーダーレスフォーム)をフローティングフォームとして表示すると、に気付くでしょうit wont receive focus even if you clicked (selected) any of its children。この場合、子はユーザーコントロールのリストボックスです。

ここここを参照してください。

于 2012-06-21T22:33:15.657 に答える
0

Angshuman Agarwal による以前の回答に加えて: UserControl がフローティング フォームとして表示されているときにメイン フォームが非アクティブにならないようにする場合は、UserControl のコードをいくつか変更します。

private Control _mControl;

[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

public new void Show(Control c)
{
    if (c == null) throw new ArgumentNullException();
    _mControl = c;
    if (this.Handle == IntPtr.Zero) base.CreateControl();
    SetParent(base.Handle, IntPtr.Zero);
    ShowWindow(base.Handle, 1);
}

protected override void WndProc(ref Message m)
{
    if (m.Msg == 0x86)  //WM_NCACTIVATE
    {
        if (m.WParam != IntPtr.Zero) //activate
        {
            SendMessage(_mControl.Handle, 0x86, (IntPtr)1, IntPtr.Zero);
        }
        this.DefWndProc(ref m);
        return;
    }
    base.WndProc(ref m);
}
于 2013-01-29T15:58:50.907 に答える
0

私は似たようなものを作成しましたが、私の解決策はlAbstractが示唆するものと似ています。floatin フォームには、カスタム TextBox (この場合は AutoCompleteTextBox コントロール) がサブスクライブするイベント DoReturnFocus があり、フォーカスをそれ自体に戻すだけです。メイン フォームがフローティング フォームの前に表示されないようにするために、メイン フォームをフローティング フォームの所有者として設定しました。

Form.Owner プロパティの詳細

于 2014-01-30T16:08:12.913 に答える