어떤 컨트롤이 집중되어 있는지 어떻게 찾을 수 있습니까?
문제
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 이벤트 에이 핸들러를 추가 할 수 있지만 확실히 귀하의 컨트롤이 있습니다. ~하지 않다 (예 : 버튼과 같은)에 대해 원합니다. 대신 텍스트 상자에 대한 핸들러 만 반복하고 추가 할 수 있습니다.