Microsoft MVP성태의 닷넷 이야기
.NET Framework: 161. WPF - 윈도우 이벤트 가로채기 [링크 복사], [링크+제목 복사],
조회: 28210
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
(연관된 글이 1개 있습니다.)

WPF - 윈도우 이벤트 가로채기


WinForm 프로그래밍을 해봤다면, 아마도 이런 경우 IMessageFilter를 구현한 인스턴스에 대해 AddMessageFilter를 호출하던 것을 생각할 텐데요.

그렇다면 WPF에서는 어떤 방법들이 있을까요?

우선, 쉽게 검색되는 방법으로 다음과 같은 HwndSource.AddHook을 이용하는 것이 있습니다.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
    source.AddHook(new HwndSourceHook(WndProc));
}

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    return IntPtr.Zero;
}

해보면 알겠지만, 이 방법에는 단점이 있습니다.

  • 반응이 한 박자(?) 느리다.
  • HwndSource.FromHwnd로 얻어낸 HWND 윈도우에서 발생하는 메시지만 수신된다.

별로 만족스럽지 않지요? ^^ 대신에, MSDN 문서를 뒤져보면 아주 좋은 방법이 하나 더 공개되어 있습니다. 바로 ^^ ComponentDispatcher.ThreadFilterMessage 이벤트입니다.

코드는 다음과 같이 매우 간단합니다.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    ComponentDispatcher.ThreadFilterMessage 
        += new ThreadMessageEventHandler(ComponentDispatcher_ThreadFilterMessage);
}

void ComponentDispatcher_ThreadFilterMessage(ref MSG msg, ref bool handled)
{
}

ComponentDispatcher.ThreadFilterMessage 방식은 위에서 언급한 2가지 단점이 없습니다. 말 그대로 프로세스 전역적으로 발생하는 윈도우 메시지를 수신할 수 있습니다. 물론, 프로세스 전역적이라는 말은 다소 무리가 있지요. 하지만 윈도우즈 프로그래밍의 특성상, 해당 UI를 생성한 스레드에 종속되는 것을 감안하면 최초 App/Shell을 생성한 Primary Thread에 대해서 ThreadFilterMessage 이벤트를 걸어두면 거의 모든 요구 사항 수준을 만족할 수 있습니다. 행여나, 별도의 스레드에서 UI를 생성한다면 그 스레드의 Dispatcher에 대해 ThreadFilterMessage를 수신하도록 하면 그만입니다.

첨부한 프로젝트는 위의 내용을 곧바로 확인할 수 있는 코드를 담고 있습니다.



[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 3/19/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2009-09-10 09시48분
[맨날맑음] Win32 API 이용하는 방법 밖에 몰랐는데 잘배워갑니다^^
[guest]

... 136  137  138  139  140  141  142  [143]  144  145  146  147  148  149  150  ...
NoWriterDateCnt.TitleFile(s)
1512정성태10/18/201328897개발 환경 구성: 200. IIS AppPool의 실행 계정을 변경하는 방법
1511정성태10/12/201326864.NET Framework: 389. The 3n + 1 problem의 C#/Java 버전 풀이 [2]
1510정성태10/8/201327865오류 유형: 190. 윈도우 서버 2012 R2 설치 후 인텔 NIC으로 인한 WMI 오류 발생
1509정성태10/8/201333177오류 유형: 189. Windows Server 8.1/2012 R2 - IME 비정상 종료 현상 [1]
1508정성태10/4/201328062.NET Framework: 388. 일반 닷넷 프로젝트에서 WinRT API를 호출하는 방법 [2]파일 다운로드1
1507정성태9/30/201326008오류 유형: 188. The key 'LocalizedPerfCounter' does not exist in the appSettings configuration section.
1506정성태9/30/201328283오류 유형: 187. Parameter "basePath" cannot be a relative path
1505정성태9/26/201376839기타: 35. Microsoft Office 2007 인증 생략하는 방법 [10]
1504정성태9/24/201331209.NET Framework: 387. UDP 브로드캐스팅을 이용해 서비스 측의 IP 주소를 구하는 방법 [1]파일 다운로드1
1503정성태9/21/201336652개발 환경 구성: 199. Visual Studio - github 연동 [7]
1502정성태9/21/201340282개발 환경 구성: 198. Visual Studio - git을 이용한 로컬 소스 컨트롤
1501정성태9/21/201347914개발 환경 구성: 197. Visual Studio를 위한 Git 환경 설정 [5]
1500정성태9/20/201346279.NET Framework: 386. C# 버전의 한글 형태소 분석기 [1]파일 다운로드1
1499정성태9/20/201322798개발 환경 구성: 196. Windows Azure - Cloud Service의 인스턴스 타입 변경하는 방법
1498정성태9/20/201329138Windows: 76. 윈도우 8.1 / 서버 2012 R2 마이그레이션 [5]
1497정성태9/20/201361513웹: 28. IE 11로 바꾼 후 발생하는 문제 정리
1496정성태9/20/201333702Windows: 75. 윈도우 8.1, 2012 R2 설치 후 원격 접속이 안 되는 문제
1495정성태9/20/201324694웹: 27. IE 11 - YBM Sisa.com에서 검색된 영단어의 발음 기호가 안 나오는 문제
1494정성태9/13/201334683.NET Framework: 385. Html Agility Pack 소개 - 웹 문서에서 텍스트만 분리하는 방법 [2]파일 다운로드1
1493정성태9/13/201336129.NET Framework: 384. WebClient.DownloadString 문자열 인코딩 문제
1492정성태9/13/201323701오류 유형: 186. The .NET assembly 'Microsoft.Vsa' could not be found.
1491정성태9/9/201326638.NET Framework: 383. RSAParameters의 ToXmlString과 ExportParameters의 결과 비교
1490정성태9/7/201361999기타: 34. 도서: 시작하세요! C# 프로그래밍: 기본 문법부터 실전 예제까지 [7]
1489정성태9/4/201346591오류 유형: 185. 오피스 워드 파일이 저장되지 않는 문제 [2]
1488정성태8/27/201330508.NET Framework: 382. WCF에서 DataSet을 binary encoding으로 직렬화하는 방법파일 다운로드1
1487정성태8/27/201332771개발 환경 구성: 195. 로컬 PC에서의 WCF 통신을 Fiddler로 보는 방법 [1]
... 136  137  138  139  140  141  142  [143]  144  145  146  147  148  149  150  ...