다음을 통해 공유


관리되는 Window 프로시저를 사용하여 컨트롤 서브클래싱

업데이트: 2007년 11월

.NET Compact Framework에서는 네이티브 코드에서 콜백 대리자를 사용하여 관리 코드를 호출할 수 있는 기능을 제공합니다. 해당하는 네이티브 컨트롤에서 콜백을 받도록 관리되는 컨트롤을 서브클래싱하면 .NET Compact Framework에서 직접 사용할 수 없는 기능이 포함된 컨트롤을 만들 수 있습니다.

이 항목은 Windows 프로그래밍 및 컨트롤 서브클래싱에 대한 지식을 개발자에게 제공하는 고급 항목입니다. 컨트롤을 서브클래싱하려면 네이티브 컨트롤의 내부를 자세히 알고 있어야 하며 이 컨트롤이 관리 컨트롤에 대한 확장에서 제공할 기능에 매핑되는 방식에 대해서도 알아야 합니다. 또한 모니터링할 Windows 메시지와 원하는 기능을 제공하기 위해 호출할 네이티브 Windows Embedded CE 함수를 알고 있어야 합니다.

이 항목에서는 TreeViewButton 컨트롤을 서브클래싱하는 방법을 설명하며 다음 항목에서는 응용 프로그램 작성에 관련된 코드 예제와 지침을 제공합니다.

방법 항목

세부 항목

방법: 네이티브 콜백을 사용하여 TreeView 서브클래싱

TreeView 컨트롤을 서브클래싱하면 NodeMouseClick 이벤트의 구현이 만들어집니다. 이 방법은 제약이 있는 리소스에 대해 크기를 제한해야 하므로 .NET Compact Framework에서 직접 지원되지 않습니다.

방법: 네이티브 콜백을 사용하여 Button 서브클래싱

Button 컨트롤을 서브클래싱하면 컬러 그라데이션 채우기가 표시됩니다.

이 단추는 주로 서브클래싱과 콜백을 사용하는 방법을 보여 주는 데 사용됩니다. 그라데이션 채우기 단추를 보다 쉽게 만들려면 방법: 그라데이션 채우기 표시를 참조하십시오.

두 개의 서브클래싱 프로그램에는 모두 WndProcHooker 클래스와 네이티브 Win32 구조, 플랫폼 호출 선언 및 WndProc 대리자의 도우미 클래스가 포함되어 있습니다. 코드 목록은 방법: Windows 프로시저를 후크하기 위한 클래스 사용방법: 플랫폼 호출에 도우미 클래스 사용을 참조하십시오.

WndProcHooker 클래스

WndProcHooker 클래스는 네이티브 컨트롤 또는 창에서 해당 컨트롤에 대한 특정 Windows 메시지를 받았을 때 관리 코드에 대한 콜백을 호출할 수 있는 기능을 제공합니다. 이 작업은 네이티브 컨트롤의 창 프로시저(WndProc) 대신 제네릭 창 프로시저인 WindowProc를 사용하여 수행되며, 호출할 콜백 메서드에 연결된 컨트롤 목록에 해당 컨트롤이 있는지 여부를 조회합니다. 이 경우, 해당 컨트롤은 후크 대상으로 고려됩니다.

컨트롤이 후크되면 WindowProc는 해당 컨트롤이 특정 Windows 메시지에 응답하도록 매핑되었는지 확인합니다. 이것은 원하는 기능이 포함된 관리 메서드를 호출하는 WndProcCallback 대리자와 Windows 메시지를 매핑하는 메시지 맵입니다. 메시지 맵에 메시지가 포함된 경우 WndProcCallback 대리자는 WindowProc에 제공된 메시지 매개 변수를 사용하여 코드를 호출합니다.

컨트롤 후크

HookWndProc 메서드는 컨트롤의 핸들을 제네릭 창 프로시저인 WindowProc에서 사용할 메시지 맵과 연결합니다. 이러한 작업을 컨트롤 후크라고 합니다.

HookWndProc 메서드는 컨트롤이 이미 후크되었는지 확인합니다. 후크되지 않았으면 해당 컨트롤에 대한 HookedProcInformation 개체가 만들어집니다. 이 개체에는 컨트롤에 대한 참조와 메시지 맵이 들어 있습니다. 컨트롤에 대한 핸들이 이미 만들어진 경우 이 메서드는 이후 복원을 위해 창의 원래 창 프로시저에 대한 포인터를 만들어서 창을 후크합니다. 만들어진 핸들이 없는 경우 이 메서드는 HandleCreated 이벤트를 처리하는 ctrl_HandleCreated 메서드에 의해 후크됩니다.

그런 다음 HookWndProc 메서드는 HookedProcInformation 개체를 다음과 같은 두 개의 제네릭 사전 컬렉션 중 하나에 추가합니다.

  • hwindDict 사전에는 모든 후크된 창 핸들의 전역 목록이 들어 있습니다. 키는 hwnd입니다. 핸들이 만들어진 컨트롤은 이 사전에 포함됩니다. 이 사전에 있는 컨트롤은 매핑된 메시지에 대해 WindowProc에 의해 평가됩니다.

  • ctlDict 사전에는 핸들이 만들어지지 않은 컨트롤이 포함됩니다. ctrl_HandleCreated 메서드가 호출되면 컨트롤이 hwndDict 사전으로 이동합니다.

컨트롤 언후크

UnhookWndProc 메서드는 컨트롤을 언후크하는 다음과 같은 두 가지 방법을 제공합니다.

  • 컨트롤에 대한 메시지 맵에서 메시지만 제거하고 후크된 창의 hwndDict 사전에 있는 컨트롤은 유지합니다. 또한 이 메서드는 HookedProcInformation 개체에 유지된 포인터를 사용하여 컨트롤에 대한 원래 창 프로시저를 복원합니다.

  • 후크된 컨트롤의 hwndDict 사전에서 컨트롤을 제거한 다음, 컨트롤의 핸들을 제거하고 해당 컨트롤을 ctrlDict 사전에 배치하거나 컨트롤 전체를 제거합니다. 이 메서드도 HookedProcInformation 개체에 유지된 핸들을 사용하여 컨트롤에 대한 원래 창 프로시저를 복원합니다.

TreeView 컨트롤 서브클래싱

방법: 네이티브 콜백을 사용하여 TreeView 서브클래싱에 제공된 샘플 프로그램 TreeViewBonus 클래스는 TreeView 컨트롤을 확장하여 .NET Compact Framework에서 직접 사용할 수 없는 NodeMouseClick 이벤트를 포함합니다.

NodeMouseClick 이벤트는 WndProcHooker 클래스에서 수행했던 것처럼 WM_NOTIFY 메시지를 컨트롤에 대한 메시지 맵에 추가하여 가져올 수 있습니다. 관리 콜백 메서드인 WM_Notify_Handler는 네이티브 GetMessagePos 함수를 호출하여 Windows 메시지가 전송된 시점의 마우스 커서 좌표를 가져옵니다.

이러한 좌표는 TreeView 컨트롤을 기준으로 하지 않고 화면에 표시되는 클라이언트 영역을 기준으로 하는 상대 좌표입니다. TreeViewBonus 클래스는 컨트롤에 대한 PointToClient 메서드를 사용하여 화면 좌표를 클라이언트 좌표로 변환합니다. 이러한 클라이언트 좌표는 TreeViewBonus 개체가 클릭되었는지 여부와 클릭된 위치를 확인하는 TVM_HITTEST 메시지와 함께 보내집니다.

TreeViewBonus 클래스에는 네이티브 컨트롤의 TVM_HITTEST 메시지를 사용하여 컨트롤의 상대 좌표를 가져오는 코드가 들어 있습니다.

트리 뷰 노드 중 하나에서 클릭이 발생하면 네이티브 TVHITTESTINFO 구조체에는 해당 노드에 대한 핸들이 포함됩니다. 마지막 단계에서는 FindTreeNodeFromHandle 메서드가 관리 TreeView 노드를 재귀적으로 탐색하면서 일치하는 핸들을 찾고 NodeMouseClick 이벤트를 발생시킵니다. TreeNodeMouseClickEventArgs 클래스는 다음과 같은 데이터를 제공합니다.

  • 클릭한 노드

  • 클릭한 단추

  • 클릭 횟수(1로 설정됨)

  • 클릭이 발생한 X 좌표

  • 클릭이 발생한 Y 좌표

TreeViewBonus 클래스는 WndProcHooker 클래스에서 수행한 것과 마찬가지로 관리 창 프로시저에 대한 네이티브 트리 뷰 컨트롤의 부모를 후크합니다. 이 클래스는 부모 컨트롤을 후크하여 OnParentChanged 이벤트에 응답하기 때문에 Form에서 Panel로 이동하는 것과 같이 TreeView가 새 부모로 이동할 수 있습니다 .

Button 컨트롤 서브클래싱

방법: 네이티브 콜백을 사용하여 Button 서브클래싱에 나열된 GradientFilledButton 및 GradientFill 클래스는 Button 컨트롤을 확장하여 두 색 사이의 그라데이션 채우기를 표시합니다. 이 프로그램은 주로 서브클래싱을 보여 주는 데 사용됩니다. 그러나 단추에 그라데이션 채우기를 표시하는 보다 쉬운 방법은 방법: 그라데이션 채우기 표시에서 설명한 대로 Control에서 파생된 사용자 지정 컨트롤을 만드는 것입니다.

GradientFilledButton 클래스의 생성자는 Windows 메시지를 관리 콜백에 매핑하는 WndProcHooker 클래스의 인스턴스를 만듭니다. 이러한 콜백 메서드는 Windows 메시지와 컨트롤의 Capture 속성 상태에 따라 적절한 상태로 단추를 그립니다. 다음 표에서는 매핑된 Windows 메시지와 해당 콜백을 나열합니다.

Windows 메시지

관리 콜백 메서드 및 설명

WM_KEYDOWN

WM_KeyDown_Handler - 스페이스바 또는 Enter(또는 Action) 키가 눌러진 경우 단추를 눌러진 상태로 다시 그립니다.

WM_KEYUP

WM_KeyUp_Handler - 단추를 눌러지지 않은 상태로 다시 그리고 스페이스바 또는 Enter(또는 Action) 키가 눌러진 경우 Click 이벤트를 발생시킵니다.

WM_LBUTTONDOWN

WM_LeftButtonDown_Hander - 단추를 눌러진 상태로 다시 그리고 컨트롤에 대한 마우스 Capture 속성을 true로 설정합니다.

WM_LBUTTONUP

WM_LButtonUp_Handler - 눌러지지 않은 상태로 단추를 다시 그리고 컨트롤의 클라이언트 영역 내에서 커서를 놓은 경우 MouseUp 이벤트를 발생시킨 다음 컨트롤에 대한 마우스 Capture 속성을 false로 설정합니다.

WM_MOUSEMOVE

WM_MouseMove_Handler - 단추가 이전에 클릭되었고 Capture가 true이면 단추를 다시 그립니다.

WM_PAINT

WM_Paint_Handler - 단추를 적절한 상태로 다시 그립니다.

이러한 관리 콜백 메서드는 DrawButton 메서드를 사용하여 단추를 적절한 상태로 그립니다. 이 메서드에는 이 예제에 사용된 창 또는 Graphics 개체에서 단추를 그리기 위한 두 개의 오버로드가 있습니다. 두 오버로드는 모두 단추가 눌러진 경우 true라는 부울 값을 받습니다.

GradientFilledButton 클래스는 GradientFill 클래스를 사용하여 네이티브 코드에 대한 P/Invoke 호출을 수행하여 채우기 작업을 실행합니다. GradientFill 클래스는 시작 및 끝 색을 설정하는 속성과 왼쪽에서 오른쪽 또는 위쪽에서 아래쪽으로의 채우기 방향을 지정하는 속성을 제공합니다.

참고 항목

작업

방법: Windows 프로시저를 후크하기 위한 클래스 사용

방법: 플랫폼 호출에 도우미 클래스 사용

방법: 네이티브 콜백을 사용하여 TreeView 서브클래싱

방법: 그라데이션 채우기 표시

개념

.NET Compact Framework 방법 항목

기타 리소스

.NET Compact Framework의 상호 운용성