다음을 통해 공유


방법: 양식 수준에서 키보드 입력 처리

Windows Forms에서는 메시지가 컨트롤에 도달하기 전에 폼 수준에서 키보드 메시지를 처리하는 기능을 제공합니다. 이 항목에서는 다음 작업을 수행하는 방법에 대해 설명합니다.

폼 수준에서 키보드 메시지를 처리하려면 다음을 수행합니다.

  • 시작 폼의 KeyPress 또는 KeyDown 이벤트를 처리하고 키보드 메시지가 폼의 컨트롤에 도달하기 전에 폼이 이 메시지를 수신하도록 폼의 KeyPreview 속성을 true로 설정합니다. 다음 코드 예제에서는 모든 숫자 키를 감지하고 '1', '4', '7'을 사용하여 the 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가 포함됩니다. 기본 FormKeyPress 이벤트는 '1', '4', '7'을 사용하고 TextBoxKeyPress 이벤트는 '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 어셈블리에 대한 참조

참고 항목