티스토리 뷰

Application/C#

C# 메세지 처리

알 수 없는 사용자 2010. 7. 16. 04:00

출처 : http://blog.naver.com/mcgyver3/40016726487

 

저자: 한동훈
C#에서 이벤트를 처리하는 방법에는 크게 두 가지가 있다(정확히는 세 가지 던가?). 한 가지는 클래스에 정의된 메소드를 오버라이드하는 방법이다. 이 경우에는 사용 언어가 VB.NET이냐 C#이냐에 따라 차이는 있지만 이벤트를 이용한 것이다. 다른 한 가지는 EventHandler 클래스를 이용하여 위임하는 것이다.
마우스 왼쪽 버튼을 클릭하면 윈도우에서는 버튼을 누르는 순간에 WM_LBUTTONDOWN과 버튼을 떼는 순간에 WM_LBUTTONUP이라는 메시지가 전달된다. 우리가 흔히 생각하는 클릭이라는 것은 이 두 가지 메시지가 빠르게 전달되는 것을 뜻한다.
폼에 있는 컨트롤을 클릭하면 이러한 메시지가 재빨리 윈도우에 전달되고 반응한다. 이러한 메시지가 윈도우에 전달되기 전에 특별한 처리를 할 필요가 있다. 예를 들어서 키보드를 사용할 수 없게 하는 경우라든가 마우스 클릭을 하지 못하게 하는 경우, 포토샵과 같은 그래픽 드로잉 프로그램에서 도형의 크기를 조절하는 것과 같은 것을 직접 구현하는 경우를 들수 있다.
닷넷에서는 메시지를 가로채려면 IMessageFilter를 사용한다.
먼저 아무것도 하지 않는 닷넷 윈도우 폼 응용 프로그램의 코드는 다음과 같다. 이 코드에는 하나의 버튼이 있고, 버튼을 클릭하면 클릭했음을 알리는 대화창이 나타난다.

이름 : MessageFilter.cs

using System;
using System.Windows.Forms;

class AppMain
{
  public static void Main(string[] args)
  {
    Application.Run(new MyForm());
  }

  public class MyForm : System.Windows.Forms.Form
  {
    private Button btnOk;

    public MyForm()
    {
      btnOk = new Button();
      btnOk.Text = "&Ok";
      btnOk.Click += new System.EventHandler(btnOk_Clicked);
      btnOk.Location = new System.Drawing.Point(100, 100);

      this.Controls.Add(btnOk);


      this.Text = "My Message Filter";
    }

    private void btnOk_Clicked(object sender, System.EventArgs e)
    {
      MessageBox.Show("clicked");
    }
  }
}

메시지 필터를 구현하려면 IMessageFilter를 구현하면 된다. IMessageFilter에서 구현해야하는 메소드는 다음과 같다.

bool PreFilterMessage(ref Message msg)

IMessageFilter를 구현하는 MyMessageFilter 클래스를 위 예제에 추가한다.

public class MyMessageFilter : IMessageFilter
  {
    public bool PreFilterMessage(ref Message msg)
    {
      // 왼쪽 마우스 버튼 이벤트를 가로챈다.
      if ( 513 == msg.Msg )     // WM_LBUTTONDOWN = 513
      {
        MessageBox.Show("WM_LBUTTONDOWN is : " + msg.Msg.ToString());
        return true;
      }
      return false;
    } // end of method PreFilterMessage
} // end of class MyMessageFilter

WM_LBUTTONDOWN에서 WM은 윈도우 메시지(Window Message)를 뜻한다. LBUTTONDOWN이므로 마우스의 왼쪽 버튼을 누르는 순간을 가로채도록 지시한다.
MyMessageFilter 클래스를 추가했으면 윈폼 응용 프로그램에서 이 메시지 필터를 사용하도록 해야한다. MyForm()을 다음과 같이 수정한다.(굵은 글씨로 표시된 부분)

private MyMessageFilter msgFilter = new MyMessageFilter();

public MyForm()
{
  btnOk = new Button();
  btnOk.Text = "&Ok";
  btnOk.Click += new System.EventHandler(btnOk_Clicked);
  btnOk.Location = new System.Drawing.Point(100, 100);
  this.Controls.Add(btnOk);
  Application.AddMessageFilter(msgFilter); 
  this.Text = "My Message Filter";
}

실행하고 버튼을 클릭하면 "clicked" 대신에 다른 메시지가 나타나는 것을 볼 수 있을 것이다. 마우스와 관련하여 자주 사용되는 윈도우 메시지는 다음과 같다.

윈도우 메시지 16진수 10진수 내용
WM_MOUSEMOVE 0x0200 512 마우스 이동
WM_LBUTTONDOWN 0x0201 513 마우스 왼쪽 버튼을 누르고 있는 상태
WM_LBUTTONUP 0x0202 514 마우스 왼쪽 버튼을 떼었을 때
WM_LBUTTONDBLCLK 0x0203 515 마우스 왼쪽 버튼을 더블 클릭할 때
WM_RBUTTONDOWN 0x0204 516 마우스 오른쪽 버튼을 누르고 있는 상태
WM_RBUTTONUP 0x0205 517 마우스 오른쪽 버튼을 떼었을 때
WM_RBUTTONDBLCLK 0x0206 518 마우스 오른쪽 버튼을 더블 클릭할 때
WM_MOUSEWHEEL 0x020A 522 마우스 휠을 움직일 때

 

나 머지 윈도우 메시지들은 여러분이 직접 필터를 만들어서 테스트 해보기 바란다. 휠 마우스와 응용 프로그램의 스크롤바와 관련된 메시지를 처리하여 슬라이딩 스크롤링을 만들 수도 있다.

자료출처:한빛미디어