我有一個.net MDI應用程序在vb.net編寫。我試圖編寫一個表單,允許用戶選擇一個特殊的字符,如°,μ,²,³,ɑ等,並將這個字符插入到通過熱鍵或MDI父級的主菜單。如何找到關注哪個控件?
執行此操作的簡單方法是找出在調用字符選擇表單時哪個控件集中在哪個MDI子表單上,但我找不到任何有關如何執行此操作的信息。
任何想法?
我有一個.net MDI應用程序在vb.net編寫。我試圖編寫一個表單,允許用戶選擇一個特殊的字符,如°,μ,²,³,ɑ等,並將這個字符插入到通過熱鍵或MDI父級的主菜單。如何找到關注哪個控件?
執行此操作的簡單方法是找出在調用字符選擇表單時哪個控件集中在哪個MDI子表單上,但我找不到任何有關如何執行此操作的信息。
任何想法?
找到一個更簡單的方法 -
[Parent Form].ActiveMdiChild.ActiveControl
添加一個IMessageFilter並監視窗口消息,如WM_SETFOCUS或WM_ACTIVATE。您可以使用Control.FromHandle將IntPtrs轉換爲.NET控件。
它通過添加的Application.AddMessageFilter應用程序消息循環。有關示例,請參閱http://blogs.msdn.com/csharpfaq/archive/2004/10/20/245412.aspx。 – 2009-10-27 15:03:32
試圖 如果m.Msg = H7或m.Msg = H6然後「WM SetFocus的 FocusedControl = Control.FromHandle(m.WParam) 結束如果 它簡化版,似乎永遠被觸發。我收到各種消息,只是沒有與這些消息相匹配的消息 - 我在做什麼錯了? – 2009-10-27 15:07:52
我會在一些例子中發佈 – 2009-10-27 15:11:13
你可以像這樣添加一個類項目:
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事件添加此處理程序,但肯定有控件不需要(例如按鈕)。您可以改爲迭代並僅添加TextBoxes的處理程序。
看起來像WM_SETFOCUS消息沒有通過....我的壞。我很確定他們會通過Control.WndProc的方法。作爲一種解決方法,我不得不通過p/invoke 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);
}
}
}
很棒的答案!感謝你付出的努力! – 2009-10-27 18:02:17
那麼確定,如果你認爲*一行代碼*是「更容易」。 :) – MusiGenesis 2009-10-27 20:39:53
只是更容易,哈哈。 雖然這種方法對於非MDI應用程序來說非常棒,所以我仍然投票贊成。 – 2009-10-29 15:22:23