Domanda

Ho un'applicazione MDI .net scritta in vb.net. Sto cercando di programmare un modulo che consentirà all'utente di selezionare un carattere speciale come °, µ, ², ³, ? e così via e di avere quel carattere inserito in qualsiasi controllo focalizzato prima dell'avvio del modulo tramite un tasto di scelta rapida o il menu principale nel genitore MDI.

Il modo semplice per farlo sarebbe capire quale controllo era focalizzato su quale modulo MDI Child quando veniva invocato il modulo di selezione del personaggio, ma non trovo alcuna informazione su come farlo.

Qualche idea?

È stato utile?

Soluzione 3

Trovato un modo più semplice -

[Parent Form].ActiveMdiChild.ActiveControl

Altri suggerimenti

Sembra che i messaggi WM_SETFOCUS non arrivino .... Mio cattivo. Sono abbastanza sicuro che sarebbero arrivati ??nel Control.WndProc . Per aggirare, ho dovuto p / invocare GetFocus è arrivato un messaggio straordinario e memorizza l'handle del controllo che ha il focus.

La sezione del 1o codice è la classe del filtro e la sezione del 2o codice è il codice del test.



    public class LastFocusedControlFilter : IMessageFilter
    {
        [DllImport("user32")]
        private static extern IntPtr GetFocus();

        private IntPtr? _lastCtrl;
        private readonly Control _ctrlToIgnore;

        public LastFocusedControlFilter(Control controlToIgnore)
        {
            _ctrlToIgnore = controlToIgnore;
        }

        public bool PreFilterMessage(ref Message m)
        {
            if (!_ctrlToIgnore.IsHandleCreated || _ctrlToIgnore.Disposing || _ctrlToIgnore.IsDisposed)
            {
                return false;
            }
            IntPtr handle = GetFocus();
            if (handle != _ctrlToIgnore.Handle)
            {
                _lastCtrl = handle;
            }
            return false;
        }

        public Control GetLastFocusedControl()
        {
            return _lastCtrl.HasValue ? Control.FromHandle(_lastCtrl.Value) : null;
        }
    }
static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        using (Form form = new Form())
        {
            Action resetBackColor = null;
            for (int i = 0; i < 10; i++)
            {
                TextBox textBox = new TextBox();
                resetBackColor += delegate { textBox.BackColor = Color.White; };
                textBox.Text = ((char)('a' + i)).ToString();
                textBox.Location = new Point(0, textBox.Height * i);
                form.Controls.Add(textBox);
            }
            Button showTextButton = new Button();
            LastFocusedControlFilter msgFilter = new LastFocusedControlFilter(showTextButton);
            showTextButton.Dock = DockStyle.Bottom;
            showTextButton.Text = "Show text of last selected control";
            showTextButton.Click += delegate(object sender, EventArgs e)
             {
                 resetBackColor();
                 Control lastControl = msgFilter.GetLastFocusedControl();
                 if (lastControl == null)
                 {
                     MessageBox.Show("No control previous had focus.");
                 }
                 else
                 {
                     lastControl.BackColor = Color.Red;
                     MessageBox.Show(string.Format("Control of type {0} had focus with text '{1}'.", lastControl.GetType(), lastControl.Text));
                 }
             };
            form.Controls.Add(showTextButton);

            Application.AddMessageFilter(msgFilter);
            Application.Run(form);
        }
    }
}

Aggiungi un IMessageFilter e monitora per i messaggi di Windows come WM_SETFOCUS o < a href = "http://msdn.microsoft.com/en-us/library/ms646274%28VS.85%29.aspx" rel = "nofollow noreferrer"> WM_ACTIVATE . Puoi utilizzare Control.FromHandle per convertire IntPtrs in controlli .NET.

Puoi aggiungere una classe come questa al tuo progetto:

public class FocusWatcher
{
    private static System.Windows.Forms.Control _focusedControl;
    public static System.Windows.Forms.Control FocusedControl
    {
        get
        {
            return _focusedControl;
        }
    }

    public static void GotFocus(object sender, EventArgs e)
    {
        _focusedControl = (System.Windows.Forms.Control)sender;
    }
}

Quindi, per qualsiasi controllo su qualsiasi modulo per il quale desideri essere candidato al "controllo focalizzato più di recente", dovresti farlo:

textBox1.GotFocus += FocusWatcher.GotFocus;

e quindi accedi a FocusWatcher.FocusedControl per ottenere il controllo focalizzato più di recente. Il monitoraggio dei messaggi funzionerà, ma devi ignorare i messaggi che non desideri (come WM_ACTIVATE dal modulo Mdi).

Potresti scorrere tutti i controlli in ogni modulo e aggiungere questo gestore per l'evento GotFocus, ma sicuramente ci sono controlli per cui non lo desideri (come ad esempio Buttons). Potresti invece ripetere e aggiungere solo il gestore per TextBox.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top