성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <br /> <div style='font-family: 맑은 고딕, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>WPF - 윈도우 이벤트 가로채기</div><br /> <br /> WinForm 프로그래밍을 해봤다면, 아마도 이런 경우 <a target='tab' href='https://www.sysnet.pe.kr/2/0/11615#add_msg_filter'>IMessageFilter를 구현한 인스턴스에 대해 AddMessageFilter를 호출</a>하던 것을 생각할 텐데요.<br /> <br /> 그렇다면 WPF에서는 어떤 방법들이 있을까요?<br /> <br /> 우선, 쉽게 검색되는 방법으로 다음과 같은 HwndSource.AddHook을 이용하는 것이 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > private void Window_Loaded(object sender, RoutedEventArgs e) { HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); source.<b style='COLOR: blue'>AddHook</b>(new <b style='COLOR: blue'>HwndSourceHook</b>(WndProc)); } private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { return IntPtr.Zero; } </pre> <br /> 해보면 알겠지만, 이 방법에는 단점이 있습니다.<br /> <br /> <ul> <li>반응이 한 박자(?) 느리다.</li> <li>HwndSource.FromHwnd로 얻어낸 HWND 윈도우에서 발생하는 메시지만 수신된다.</li> </ul> <br /> 별로 만족스럽지 않지요? ^^ 대신에, MSDN 문서를 뒤져보면 아주 좋은 방법이 하나 더 공개되어 있습니다. 바로 ^^ ComponentDispatcher.ThreadFilterMessage 이벤트입니다.<br /> <br /> 코드는 다음과 같이 매우 간단합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > private void Window_Loaded(object sender, RoutedEventArgs e) { <b style='COLOR: blue'>ComponentDispatcher.ThreadFilterMessage += new ThreadMessageEventHandler(ComponentDispatcher_ThreadFilterMessage);</b> } void ComponentDispatcher_ThreadFilterMessage(ref MSG msg, ref bool handled) { } </pre> <br /> ComponentDispatcher.ThreadFilterMessage 방식은 위에서 언급한 2가지 단점이 없습니다. 말 그대로 프로세스 전역적으로 발생하는 윈도우 메시지를 수신할 수 있습니다. 물론, 프로세스 전역적이라는 말은 다소 무리가 있지요. 하지만 윈도우즈 프로그래밍의 특성상, 해당 UI를 생성한 스레드에 종속되는 것을 감안하면 최초 App/Shell을 생성한 Primary Thread에 대해서 ThreadFilterMessage 이벤트를 걸어두면 거의 모든 요구 사항 수준을 만족할 수 있습니다. 행여나, 별도의 스레드에서 UI를 생성한다면 그 스레드의 Dispatcher에 대해 ThreadFilterMessage를 수신하도록 하면 그만입니다.<br /> <br /> <a target='_tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=485&boardid=331301885'>첨부한 프로젝트는 위의 내용을 곧바로 확인할 수 있는 코드</a>를 담고 있습니다.<br /> <br /><br /><hr /><span style='color: Maroon'>[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
2092
(왼쪽의 숫자를 입력해야 합니다.)