2015년 10월 5일 월요일

C#으로 윈폼 만들기(Application 클래스 – 메시지 필터링)

C#으로 윈폼 만들기(Application 클래스 메시지 필터링)

C# 윈도우 프로그램은 이벤트(Event, 사건)에 반응해서 코드가 실행되는 이벤트 기반으로 만들어지며 이러한 이벤트는 사용자가 일으키는것이 아니라 윈도우 운영체제가 일으키는 것이다.
사용자가 키보드나 마우스를 제어하면 인터럽트가 발생되고 이를 운영체제가 받아 들이는 것이고 운영체제는 이 인터럽트를 바탕으로 윈도우 메시지를 만든 뒤 이벤트를 받아야 하는 응용프로그램에 보내는 것이다.
윈도우 메시지는 종류가 다양하다. 윈도우 응용프로그램은 마우스 이동이나 클릭, 키보드 입력처럼 미리 등록되어 있는 메시지를 받지만 다른 응용프로그램은 자체적으로 정의한 메시지도 받을 수 있다.
Application클래스는 응용프로그램이 받고 있는 수많은 메시지 중 관심 있는 메시지만 걸러낼 수 있는 메시지 필터링 기능이 있다. 예를 들어 윈도우 응용프로그램에서 ALT+F4를 눌러 윈도우가 종료되는 것을 막고 싶다면 필터링 기능을 이용하여 이를 차단하는 것도 가능하다.


일반적으로 윈도우 메시지는 식별번호가 붙어 있는데 WM_LBUTTONDOWN 메시지 ID0x201로 정의되어 있는데 Application 클래스는 특정 ID를 갖는 메시지를 필터를 등록해 두었다가 응용프로그램에 메시지가 전달되면 해당 필터를 동작시키며 필터링 되지 않는다면 해당 메시지를 폼이나 컨트롤로 보내 이벤트를 발생시킨다.

Application 클래스의 AddMessageFilter() 메소드는 응용프로그램에 메시지 필터를 등록하며 이 메소드의 매개변수로 IMessageFilter를 구현한 클래스의 인스턴스를 매개변수로 받으며 IMessageFilterPreFilterMessage를 구현해야 한다.
public class MessageFilter : IMessageFilter {
  public bool PreFilterMessage(ref Message m) {//m.Msg는 메시지 ID
         //마우스 왼쪽, 오른쪽, 가운데 버튼동작, 마우스 휠굴림 메시지
               if (m.Msg >= 0x200 && m.Msg <= 0x20E) {
                    Console.WriteLine(“메시지 : “ + m.Msg);
                    return true; //메시지처리했으니관심가질 필요없다.
               }
                return false;   //메시지를 건드리지 않았으니 응용프로그램에서 처리해라
  }
}

위와 같이 메시지 필터를 구현했다면 AddMessageFilter() 메소드를 호출해서 등록하면 된다.


Application.AddMessageFilter( new MessageFilter());


using System;
using System.Windows.Forms;
namespace ConsoleApplication9
{
    class OnjMessageFilter : IMessageFilter
    {
        //응용프로그램에서 받은 모든 베시지를 출력
        public bool PreFilterMessage(ref Message m)
        {
            //WM_PAINT(0x0f), WM_MOUSEMOVE(0x200), WM_TIMER(0x113)은 너무자주 발생하므로 제외
            //아래 코드을 주석으로 막고 실행해 보라.
            if (m.Msg == 0x0f || m.Msg == 0x200 || m.Msg == 0x113) return true;
            Console.WriteLine("{0}, {1}", m.ToString(), m.Msg);
            //마우스 클릭 시 윈도우 종료시킴
            if (m.Msg == 0x201) Application.Exit();
            return true;
        }
    }
    class Program : Form
    {       
        static void Main(string[] args)
        {
            Application.AddMessageFilter( new OnjMessageFilter() );
            Application.Run( new Program());           
        }
    }

}

댓글 없음:

댓글 쓰기