문제

vb.net으로 작성된 .NET MDI 응용 프로그램이 있습니다. 사용자가 °, µ, ², ³, ɑ 등과 같은 특수 문자를 선택할 수있는 양식을 프로그래밍하려고합니다. MDI 부모의 핫 키 또는 메인 메뉴.

이를 수행하는 쉬운 방법은 캐릭터 선택 양식이 호출 될 때 어떤 MDI 하위 형태에 초점을 맞추 었는지 알아내는 것이지만,이를 수행하는 방법에 대한 정보는 찾을 수 없습니다.

어떤 아이디어?

도움이 되었습니까?

해결책 3

더 쉬운 방법을 찾았습니다.

[Parent Form].ActiveMdiChild.ActiveControl

다른 팁

WM_SETFOCUS 메시지가 나오지 않는 것 같습니다 .... 내 나쁜. 나는 그들이 안에 올 것이라고 확신합니다 Control.wndproc 방법. 주변의 작업으로, 나는 p/호출해야했다 getfocus 메시지가 와서 초점이 맞는 컨트롤의 손잡이를 저장합니다.

첫 번째 코드 섹션은 필터 클래스이고 두 번째 코드 섹션은 테스트 코드입니다.



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

추가 ImessageFilter 및 Windows 메시지를 모니터링합니다 WM_SETFOCUS 또는 wm_activate. 당신이 사용할 수있는 컨트롤 intptrs를 .NET 컨트롤로 변환합니다.

프로젝트에 이와 같은 수업을 추가 할 수 있습니다.

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

그런 다음 "가장 최근에 중심적인 통제"의 후보자가 되고자하는 모든 형태의 통제는 다음과 같습니다.

textBox1.GotFocus += FocusWatcher.GotFocus;

그런 다음 액세스합니다 FocusWatcher.FocusedControl 가장 최근에 초점을 맞춘 제어를 얻으려면. 메시지 모니터링은 작동하지만 MDI 양식에서 WM_Activate와 같이 원하지 않는 메시지를 무시해야합니다.

모든 양식의 모든 컨트롤을 반복하고 GotFocus 이벤트 에이 핸들러를 추가 할 수 있지만 확실히 귀하의 컨트롤이 있습니다. ~하지 않다 (예 : 버튼과 같은)에 대해 원합니다. 대신 텍스트 상자에 대한 핸들러 만 반복하고 추가 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top