操作說明:處理表單層級的鍵盤輸入
在訊息到達控制項之前,Windows Form 提供在表單層級處理鍵盤訊息的能力。 本主題將示範如何完成這些工作。
處理表單層級的鍵盤訊息
處理啟動表單的 KeyPress 或 KeyDown 事件,並將表單的 KeyPreview 屬性設為
true
,讓鍵盤訊息到達表單上的任何控制項之前先由表單所接收。 下列程式碼範例會偵測所有數字鍵並使用 '1'、'4' 和 '7' 來處理 KeyPress 事件。// Detect all numeric characters at the form level and consume 1, // 4, and 7. Note that Form.KeyPreview must be set to true for this // event handler to be called. private: void Form1_KeyPress(Object^ sender, KeyPressEventArgs^ e) { if ((e->KeyChar >= '0') && (e->KeyChar <= '9')) { MessageBox::Show("Form.KeyPress: '" + e->KeyChar.ToString() + "' pressed."); switch (e->KeyChar) { case '1': case '4': case '7': MessageBox::Show("Form.KeyPress: '" + e->KeyChar.ToString() + "' consumed."); e->Handled = true; break; } } }
// Detect all numeric characters at the form level and consume 1, // 4, and 7. Note that Form.KeyPreview must be set to true for this // event handler to be called. void Form1_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar >= 48 && e.KeyChar <= 57) { MessageBox.Show("Form.KeyPress: '" + e.KeyChar.ToString() + "' pressed."); switch (e.KeyChar) { case (char)49: case (char)52: case (char)55: MessageBox.Show("Form.KeyPress: '" + e.KeyChar.ToString() + "' consumed."); e.Handled = true; break; } } }
' Detect all numeric characters at the form level and consume 1, ' 4, and 7. Note that Form.KeyPreview must be set to true for this ' event handler to be called. Sub Form1_KeyPress(ByVal sender As Object, _ ByVal e As KeyPressEventArgs) Handles Me.KeyPress If e.KeyChar >= ChrW(48) And e.KeyChar <= ChrW(57) Then MessageBox.Show(("Form.KeyPress: '" + _ e.KeyChar.ToString() + "' pressed.")) Select Case e.KeyChar Case ChrW(49), ChrW(52), ChrW(55) MessageBox.Show(("Form.KeyPress: '" + _ e.KeyChar.ToString() + "' consumed.")) e.Handled = True End Select End If End Sub
範例
下列程式碼範例是上述程式碼範例的完整應用。 此應用程式包括 TextBox 以及數個其他控制項,可讓您將焦點從 TextBox 移動。 當顯示剩餘的按鍵時,主要 Form 的 KeyPress 事件會使用 '1'、'4' 和 '7' ,而 TextBox 的 KeyPress 事件會使用 '2'、'5' 和 '8'。 當您按數字鍵時的焦點是其他控制項的其中一個時,TextBox 具有 MessageBox 輸出的焦點,此時您按下數字鍵,請比較 MessageBox 輸出。
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#using <System.dll>
using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
using namespace System::Security::Permissions;
namespace KeyboardInputForm
{
public ref class Form1 sealed: public Form, public IMessageFilter
{
// The following Windows message value is defined in Winuser.h.
private:
static const int WM_KEYDOWN = 0x100;
private:
TextBox^ inputTextBox;
public:
Form1()
{
inputTextBox = gcnew TextBox();
this->AutoSize = true;
Application::AddMessageFilter(this);
FlowLayoutPanel^ panel = gcnew FlowLayoutPanel();
panel->AutoSize = true;
panel->FlowDirection = FlowDirection::TopDown;
panel->Controls->Add(gcnew Button());
panel->Controls->Add(gcnew RadioButton());
panel->Controls->Add(inputTextBox);
this->Controls->Add(panel);
this->KeyPreview = true;
this->KeyPress +=
gcnew KeyPressEventHandler(this, &Form1::Form1_KeyPress);
inputTextBox->KeyPress +=
gcnew KeyPressEventHandler(this,
&Form1::inputTextBox_KeyPress);
}
// Detect all numeric characters at the
// application level and consume 0.
virtual bool PreFilterMessage(Message% m)
{
// Detect key down messages.
if (m.Msg == WM_KEYDOWN)
{
Keys keyCode = (Keys)((int)m.WParam) & Keys::KeyCode;
// Determine whether the keystroke is a number from the top of
// the keyboard, or a number from the keypad.
if (((keyCode >= Keys::D0) && (keyCode <= Keys::D9))
||((keyCode >= Keys::NumPad0)
&& (keyCode <= Keys::NumPad9)))
{
MessageBox::Show(
"IMessageFilter.PreFilterMessage: '" +
keyCode.ToString() + "' pressed.");
if ((keyCode == Keys::D0) || (keyCode == Keys::NumPad0))
{
MessageBox::Show(
"IMessageFilter.PreFilterMessage: '" +
keyCode.ToString() + "' consumed.");
return true;
}
}
}
// Forward all other messages.
return false;
}
// Detect all numeric characters at the form level and consume 1,
// 4, and 7. Note that Form.KeyPreview must be set to true for this
// event handler to be called.
private:
void Form1_KeyPress(Object^ sender, KeyPressEventArgs^ e)
{
if ((e->KeyChar >= '0') && (e->KeyChar <= '9'))
{
MessageBox::Show("Form.KeyPress: '" +
e->KeyChar.ToString() + "' pressed.");
switch (e->KeyChar)
{
case '1':
case '4':
case '7':
MessageBox::Show("Form.KeyPress: '" +
e->KeyChar.ToString() + "' consumed.");
e->Handled = true;
break;
}
}
}
// Detect all numeric characters at the TextBox level and consume
// 2, 5, and 8.
private:
void inputTextBox_KeyPress(Object^ sender, KeyPressEventArgs^ e)
{
if ((e->KeyChar >= '0') && (e->KeyChar <= '9'))
{
MessageBox::Show("Control.KeyPress: '" +
e->KeyChar.ToString() + "' pressed.");
switch (e->KeyChar)
{
case '2':
case '5':
case '8':
MessageBox::Show("Control.KeyPress: '" +
e->KeyChar.ToString() + "' consumed.");
e->Handled = true;
break;
}
}
}
};
}
[STAThread]
int main()
{
Application::EnableVisualStyles();
Application::Run(gcnew KeyboardInputForm::Form1());
}
using System;
using System.Drawing;
using System.Windows.Forms;
namespace KeyboardInputForm
{
class Form1 : Form
{
TextBox TextBox1 = new TextBox();
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
public Form1()
{
this.AutoSize = true;
FlowLayoutPanel panel = new FlowLayoutPanel();
panel.AutoSize = true;
panel.FlowDirection = FlowDirection.TopDown;
panel.Controls.Add(TextBox1);
this.Controls.Add(panel);
this.KeyPreview = true;
this.KeyPress +=
new KeyPressEventHandler(Form1_KeyPress);
TextBox1.KeyPress +=
new KeyPressEventHandler(TextBox1_KeyPress);
}
// Detect all numeric characters at the form level and consume 1,
// 4, and 7. Note that Form.KeyPreview must be set to true for this
// event handler to be called.
void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar >= 48 && e.KeyChar <= 57)
{
MessageBox.Show("Form.KeyPress: '" +
e.KeyChar.ToString() + "' pressed.");
switch (e.KeyChar)
{
case (char)49:
case (char)52:
case (char)55:
MessageBox.Show("Form.KeyPress: '" +
e.KeyChar.ToString() + "' consumed.");
e.Handled = true;
break;
}
}
}
// Detect all numeric characters at the TextBox level and consume
// 2, 5, and 8.
void TextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar >= 48 && e.KeyChar <= 57)
{
MessageBox.Show("Control.KeyPress: '" +
e.KeyChar.ToString() + "' pressed.");
switch (e.KeyChar)
{
case (char)50:
case (char)53:
case (char)56:
MessageBox.Show("Control.KeyPress: '" +
e.KeyChar.ToString() + "' consumed.");
e.Handled = true;
break;
}
}
}
}
}
Imports System.Drawing
Imports System.Windows.Forms
Namespace KeyboardInputForm
Class Form1
Inherits Form
Private WithEvents TextBox1 As New TextBox()
<STAThread()> _
Public Shared Sub Main()
Application.EnableVisualStyles()
Application.Run(New Form1())
End Sub
Public Sub New()
Me.AutoSize = True
Dim panel As New FlowLayoutPanel()
panel.AutoSize = True
panel.FlowDirection = FlowDirection.TopDown
panel.Controls.Add(TextBox1)
Me.Controls.Add(panel)
Me.KeyPreview = True
End Sub
' Detect all numeric characters at the form level and consume 1,
' 4, and 7. Note that Form.KeyPreview must be set to true for this
' event handler to be called.
Sub Form1_KeyPress(ByVal sender As Object, _
ByVal e As KeyPressEventArgs) Handles Me.KeyPress
If e.KeyChar >= ChrW(48) And e.KeyChar <= ChrW(57) Then
MessageBox.Show(("Form.KeyPress: '" + _
e.KeyChar.ToString() + "' pressed."))
Select Case e.KeyChar
Case ChrW(49), ChrW(52), ChrW(55)
MessageBox.Show(("Form.KeyPress: '" + _
e.KeyChar.ToString() + "' consumed."))
e.Handled = True
End Select
End If
End Sub
' Detect all numeric characters at the TextBox level and consume
' 2, 5, and 8.
Sub TextBox1_KeyPress(ByVal sender As Object, _
ByVal e As KeyPressEventArgs) Handles TextBox1.KeyPress
If e.KeyChar >= ChrW(48) And e.KeyChar <= ChrW(57) Then
MessageBox.Show(("Control.KeyPress: '" + _
e.KeyChar.ToString() + "' pressed."))
Select Case e.KeyChar
Case ChrW(50), ChrW(53), ChrW(56)
MessageBox.Show(("Control.KeyPress: '" + _
e.KeyChar.ToString() + "' consumed."))
e.Handled = True
End Select
End If
End Sub
End Class
End Namespace
編譯程式碼
這個範例需要:
- System、System.Drawing 和 System.Windows.Forms 組件的參考。