Question

J'ai une application .net MDI écrite en vb.net. J'essaie de programmer un formulaire qui permettra à l'utilisateur de sélectionner un caractère spécial tel que °, µ, ², ³, ?, etc., et d'insérer ce caractère dans le contrôle ciblé avant son lancement du formulaire via un touche de raccourci ou le menu principal dans le parent MDI.

Pour ce faire, le moyen le plus simple consiste à déterminer quel contrôle est concentré sur le formulaire enfant MDI lorsque le formulaire de sélection de personnage est appelé, mais je ne trouve aucune information sur la procédure à suivre.

Des idées?

Était-ce utile?

La solution 3

Vous avez trouvé un moyen plus simple -

[Parent Form].ActiveMdiChild.ActiveControl

Autres conseils

On dirait que les messages WM_SETFOCUS ne parviennent pas ... Ma mauvaise. Je suis presque sûr qu'ils arriveraient dans Méthode Control.WndProc . Pour contourner le problème, je devais p / invoquer GetFocus. evertime un message est arrivé et stocke le handle du contrôle qui a le focus.

La 1ère section de code est la classe de filtre et la 2ème section de code est le code de 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);
        }
    }
}

Ajoutez un IMessageFilter et surveillez pour les messages Windows tels que WM_SETFOCUS ou < a href = "http://msdn.microsoft.com/en-us/library/ms646274%28VS.85%29.aspx" rel = "nofollow noreferrer"> WM_ACTIVATE . Vous pouvez utiliser Control.FromHandle . convertir IntPtrs en contrôles .NET.

Vous pouvez ajouter une classe comme celle-ci à votre projet:

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;
    }
}

Ensuite, pour tout contrôle sur un formulaire pour lequel vous souhaitez être candidat au "contrôle le plus récemment ciblé", procédez comme suit:

textBox1.GotFocus += FocusWatcher.GotFocus;

, puis accédez à FocusWatcher.FocusedControl pour obtenir le contrôle le plus récemment ciblé. Le suivi des messages fonctionnera, mais vous devrez ignorer les messages que vous ne voulez pas (comme WM_ACTIVATE à partir du formulaire Mdi).

Vous pouvez parcourir tous les contrôles de chaque formulaire et ajouter ce gestionnaire pour l'événement GotFocus, mais il existe sûrement des contrôles pour lesquels vous ne ne voulez pas ceci (comme les boutons, par exemple). Vous pouvez à la place itérer et ajouter uniquement le gestionnaire pour les zones de texte.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top