본 강좌의 원본은 훈스닷넷에 있습니다.

연재 리스트 

  1. Windows 7 멀티터치 시작하기
  2. 미리 정의된 9가지 제스쳐 지원하기 (WM_GESTURE)
  3. 멀티터치 Raw 데이터를 사용 (WM_TOUCH)
  4. Manipulation and Inertia 활용
  5. WPF4 멀티터치 프로그래밍
  6. 실버라이트 4의 멀티터치 프로그래밍


WPF 4가 나오면서 Windows 7의 멀티터치를 적극적으로 지원을 하고 있습니다. 멀티터치를 구현하는 가장 좋은 방법이 바로 WPF 4를 사용하는 것이 아닐까 합니다.

WPF 컨트롤의 상속 구조에서 상위 클래스인 UIElement, UIElement3D, ContentElement 가 멀티터치를 지원 합니다. 즉 WPF에서 사용하는 모든 컨트롤이 멀티터치를 지원 하는 것이죠. 두가지 방식으로 지원을 하는데 첫번째는 멀티터치 원시 데이터(Raw Data)를 지원하고 두번 째는 Manipulation and Inertia를 지원 한다는 것입니다. 그래서 컨트롤의 이벤트를 살펴보면 이런 이벤트가 보입니다.

TouchDown, TouchUp, TouchMove, TouchEnter, TouchLeave


멀티터치 원시 데이터 이용
여러분이 예상하시는 그대로 터치를 하면 TouchDown, 움직이면 TouchMove, 터치를 제거하면 TouchUp 이벤트가 발생합니다. TouchEnter와 TouchLeave가 있는데 터치가 올라가고 내려가는데 반응하는게 아니라 터치를 한 상태에서 터치 영역의 안쪽에서 바깥쪽으로 터치 나가면 TouchLeave 바깥쪽에서 안쪽으로 들어오면 TouchEnter 이벤트가 발생합니다.

마우스와 조금 다른데 생각해보면 터치는 커서가 없기 때문에 공중에 떠서 버튼위에 올라가도 감지할 방법이 없기 때문이겠죠. (이런것들이 모두 터치 인터페이스의 특징입니다.)

그럼 Canvas 하나를 올리고 XAML 에서 위의 이벤트 핸들러를 등록하고 터치가 발생한 지점에 위치와 ID 정보를 표시해 봅시다. XAML 코드에 이렇게 사용되었습니다. 물론 코드 비하인드에서도 이벤트 핸들러를 등록할 수 있습니다.

<Canvas x:Name="_canvas" Canvas.Top="300" Canvas.Left="300"

                TouchDown="Canvas_TouchDown" TouchMove="Canvas_TouchMove" TouchUp="Canvas_TouchUp"

                TouchEnter="_canvas_TouchEnter" TouchLeave="_canvas_TouchLeave"

                Width="500" Height="500" Background="#FF0033FF">


이전 WM_TOUCH, WM_GESTURE 로 프로그래밍 할때는 터치 이벤트가 전체 프로그램에 하나 들어 오는데 WPF 4 에서는 컨트롤 마다 따로 멀티터치 이벤트를 처리 할 수 있습니다.

이벤트 핸들러를 살펴보면 핸들러마다 매개변수로 TouchEventArgs 를 사용합니다. 이 매개변수를 열어보면 TouchDevice, TouchPoint 등 멀티터치 관련된 원시 데이터를 얻을 수 있습니다. 이 데이터를 이용해서 하고 싶은 작업을 하면 되죠.

코드 비하인드에 추가적인 코드를 넣고 실행을 하면 아래 영상처럼 작동을 합니다. WM_TOUCH 샘플과 방식은 약간 다르지만 코드는 매우 비슷하네요.


영상이 보이지 않으면 : http://tvpot.daum.net/my/ClipView.do?ownerid=ADowB8WbINw0&clipid=25744494&q=

WPF 4 멀티터치 Raw data 소스코드 다운로드 : Wpf4MultitouchVisualization.zip (Visual Studio 2010, WPF 4)


WPF 4 멀티터치 Manipulation
WPF 4는 Manipulation 도 내장을 하고 있고 (이전 강좌의 Manipulation은 COM으로 구현된 라이브러리를 Interop 해서 쓰는 방식) 역시 컨트롤 마다 따로 프로그래밍을 할 수 있습니다. 매번 하는 샘플이지만 사진을 가지고 노는 샘플을 만들어 봅시다.

Image 컨트롤에 IsManipulationEnabled 라는 속성이 있고 Manipulation과 Inertia 관련 이벤트들이 존재하는 걸 볼 수 있습니다.

ManipulationStarting, ManipulationStarted, ManipulationDelta, ManipulationBoundaryFeedback, ManipulationCompleted, ManipulationInertiaStarting

이런 이벤트들이 놀랍게도 Image 컨트롤에 추가가 되었습니다. Manipulation의 기본 개념은 이전 강좌를 통해서 살펴봤으니 여기서는 코드만 보고 가겠습니다.

Image 컨트롤의 XAML 코드 입니다.

<Image Source="C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg" Width="100" Height="80"

               IsManipulationEnabled="True"

               ManipulationStarting="Image_ManipulationStarting" ManipulationDelta="Image_ManipulationDelta" ManipulationStarted=""

               ManipulationInertiaStarting="Image_ManipulationInertiaStarting"

               >

            <Image.RenderTransform>

                <MatrixTransform  />

            </Image.RenderTransform>

        </Image>


IsManipulationEnabled="True" 와 함께 이벤트 핸들러를 등록했고 변환을 편하게 적용하기 위해 MatrixTransform을 사용한 다는 걸 알 수 있습니다.

private void Image_ManipulationStarting(object sender, ManipulationStartingEventArgs e)

{

    e.ManipulationContainer = RootCanvas;

 

     e.Mode = ManipulationModes.All;

     //e.Mode = ManipulationModes.Rotate | ManipulationModes.Scale;

}


우선 Manipulation이 시작되는 시점(ManipulationStarting)에 적용될 범위를 정하고 사용할 조작의 종류들을 지정할 수 있습니다.

private void Image_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)

{

  FrameworkElement element = e.Source as FrameworkElement;

 

if (element != null)

{

Matrix matrix = ((MatrixTransform)element.RenderTransform).Matrix;

ManipulationDelta deltaManipulation = e.DeltaManipulation;

 

Point center = new Point(element.ActualWidth / 2, element.ActualHeight / 2);

center = matrix.Transform(center);

 

matrix.ScaleAt(deltaManipulation.Scale.X, deltaManipulation.Scale.Y, center.X, center.Y);

matrix.RotateAt(e.DeltaManipulation.Rotation, center.X, center.Y);

matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);

 

((MatrixTransform)element.RenderTransform).Matrix = matrix;

 

 

e.Handled = true;

 

}


이벤트를 발생시킨 소스를 찾아서 변화된 값이 모두 들어 있는 DeltaManipulation 속성에서 값을 찾아 MatrixTransform을 적용 했습니다.

WPF4 멀티터치 Inertia
관성은 ManipulationInertiaStarting 이벤트 핸들러에서 초기 값을 잘 정해주기 만 하면 알아서 잘 적용이 됩니다. 아래 코드를 보세요. 제가 물리/수학을 잘 못해서 가속도 값 계산 다른 샘플에서 가져다 썼습니다.

private void Image_ManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e)

{

     // (10 inches * 96 DIPS per inch / 1000ms^2)

     e.TranslationBehavior = new InertiaTranslationBehavior()

     {

         InitialVelocity = e.InitialVelocities.LinearVelocity,

         DesiredDeceleration = 1.0 * 96.0 / (1000.0 * 1000.0)

     };

 

     // Decrease the velocity of the Rectangle's resizing by

     // 0.1 inches per second every second.

     // (0.1 inches * 96 DIPS per inch / (1000ms^2)

     e.ExpansionBehavior = new InertiaExpansionBehavior()

     {

         InitialVelocity = e.InitialVelocities.ExpansionVelocity,

         DesiredDeceleration = 0.1 * 96 / 1000.0 * 1000.0

     };

 

     // Decrease the velocity of the Rectangle's rotation rate by

     // 2 rotations per second every second.

     // (2 * 360 degrees / (1000ms^2)

     e.RotationBehavior = new InertiaRotationBehavior()

     {

         InitialVelocity = e.InitialVelocities.AngularVelocity,

         DesiredDeceleration = 720 / (1000.0 * 1000.0)

     };

     e.Handled = true;    

 }


결국 TranslationBehavior , ExpansionBehavior , RotationBehavior 속성을 설정해 주는데 초기 속도와 원하는 가속도를 정해주고 있습니다.

WPF 4 멀티터치 Manipulation  샘플 : Wpf4ImageManipulation.zip (Visual Studio 2010, WPF 4)



실제 실행 결과는 아래 영상을 보세요.


영상이 보이지 않으면 : http://tvpot.daum.net/my/ClipView.do?ownerid=ADowB8WbINw0&clipid=25745220&q=


WPF 4 에서 멀티터치와 잘 통합되어 프로그래밍이 많이 편해진걸 느낄 수 있습니다. 하지만 아직도 멀티터치만이 할 수 있는 인터페이스는 연구해야  할 과제죠.


WRITTEN BY
ONESTONE

트랙백  0 , 댓글  1개가 달렸습니다.
  1. En attendant l'annonce d'un second épisode, http://www.moncleroutletespain.com/ moncler españa, Electronic Arts nous propose, http://www.moncleroutletespain.com/ moncler?? de redecouvrir la version iOS de Mirror's Edge en la proposant gratuitement pendant quelques heures. Cela concerne aussi bien la version iPhone/iPod (100 Mo) que la version iPad (123 Mo), http://www.moncleroutletespain.com/ moncler online. News Robert Downey Jr, http://www.moncleroutletespain.com/ moncler chaquetas. et Gwyneth Paltrow : amitié, http://www.moncleroutletespain.com/ http://www.moncleroutletespain.com/, drogue et alcool News De nouvelles images pour L, http://www.moncleroutletespain.com/ moncler outlet.A. NoireRelated articles:


    http://think1more.kr/222 http://think1more.kr/222

    http://hapina.tistory.com/category/?page=3 http://hapina.tistory.com/category/?page=3
secret


본 강좌의 원본은 훈스닷넷에 있습니다.

연재 리스트 

  1. Windows 7 멀티터치 시작하기
  2. 미리 정의된 9가지 제스쳐 지원하기 (WM_GESTURE)
  3. 멀티터치 Raw 데이터를 사용 (WM_TOUCH)
  4. Manipulation and Inertia 활용
  5. WPF4 멀티터치 프로그래밍
  6. 실버라이트 4의 멀티터치 프로그래밍


조작과 관성이라는 뜻의 Manipulation and Inertia API는 멀티터치 API 중에서 가장 강력한 기능을 가지고 있습니다. 원래는 마이크로소프트 서피스 SDK에 들어 있던 API인데 윈도우 7에 적용이 되었습니다. 사실 이동, 회전, 크기 조절은 모두 수학계산입니다. 관성도 물리 시간에 배우는 몇가지 공식이 적용되는 결국 수학으로 표현됩니다. 간단하지만은 않겠죠. 올바르게 구현하려면 조금  시간이 걸릴 것입니다. 하지만 Manipulation and Inertia API는 내부적으로 이 계산을 알아서 해주고 프로그래머에게는 결과 값만 이벤트로 알려주는 착한일을 합니다. 고맙죠.


Manipulation API
먼저 Manipulation API는 2D 환경에서의 변환 즉, 이동(Translation), 회전(Rotation), 크기조절(Rotation)를 담당합니다. WM_GESTURE 메시지와 다른 것은 모든 변환이 동시에 적용 될 수 있다는 것이다. 이동을 하면서 회전과 크기조절이 동시에 가능하죠. 또한 한 개 또는 두 개의 터치입력에 반응하는 WM_GESTURE와는 달리 여러 개의 멀티터치 입력에도 이동, 회전, 크기변환이 되어 조금 더 자연스러운 느낌을 줄 수 있습니다. .

아래 그림을 살펴보면 Manipulation API가 어떻게 작동되는지 잘 알 수 있습니다. COM으로 구현되어 있는 Manipulation API는 먼저 윈도우 7이 제공하는 WM_TOUCH 메시지의 원시(Raw) 데이터를 입력 받는 Manipulation Processor를 생성합니다. Manipulation Processor는 3가지 이벤트를 발생시키는데 ManipulationStarted 이벤트는 오브젝트를 조작하기 시작할 때 발생하고 ManipulationDelta 이벤트는 이동, 회전, 크기변환이 일어나는 중간에 발생하며 ManipulationCompleted 이벤트는 오브젝트에서 손가락을 떼어 조작을 마무리 하면 발생합니다.

결국 WM_TOUCH Raw data를  활용할 뿐 Application 단에서 모두 처리되는 구조 입니다.



조작이 일어나는 중간에 발생하는 ManipulationDelta 이벤트에서 전달되는 매개변수를 아래 표에서 살펴보세요. 여기서 변화량은 이전 이벤트와 현재 이벤트 사이의 변화량을 말하며 누적량은 ManipulationStarted 이벤트가 발생한 시점부터 현재 이벤트까지 누적된 변화량을 말한다.

종류

속성

설명

변화량

translationDeltaX

X축으로 이동한 변화량

translationDeltaY

Y축으로 이동한 변화량

scaleDelta

크기 변화량(1이 원래크기 1보다 작으면 작아짐)

rotationDelt

회전 변화량 (양수는 시계방향, 음수는 반시계방향)

누적량

cumulativeTranslationX

누적된 X축 이동량

cumulativeTranslationY

누적된 Y축 이동량

cumulativeScale

누적된 크기 변화량

cumulativeRotation

누적된 회전 변화량


즉, 이벤트 핸들러의 매개변수를 통해서 변화된 크기에 대한 정보를 프로그래머에게 알려줍니다. 프로그래머는 그 변화량 또는 누적량을 사용하면 됩니다.

Inertia API
Inertia API를 이용하면 간단한 물리 시뮬레이션을 구현할 수 있습니다. 물리 시뮬레이션은 우리가 실제 환경에서 사물을 이동할 때의 법칙을 멀티터치 응용프로그램에도 적용을 해준다는 것입니다. 예를 들어 책상 위의 물체를 잡고 이리저리 움직이다가 저쪽 끝으로 던지면 그 물체는 관성에 의해서 조금 더 미끄러지며 움직이다가 마찰력에 의해서 멈추게 됩니다. 회전이나 크기 변경도 마찬가지로 관성이 적용될 수 있습니다. 이런 물리적인 움직임을 우리의 멀티터치 응용프로그램에 적용을 하면 매우 자연스러운 느낌을 만들 수 있게 되는데 실제 손가락을 이용하는 터치 인터페이스와 연결되면 NUI(Nature User Interface)라는 말을 실감할 수 있게 만들수 있습니다.

Inertia API는 항상 Manipulation API와 함께 사용하게 된다. 그 이유는 Manipulation API가 끝나는 시점의 속도 등의 값들이 Inertia API의 초기값이 되어 물리적인 시뮬레이션을 시작하기 때문입니다. Inertia Processor가 시작 될 때 입력되는 초기값들의 종류를 아래 표에서 확인 할 수 있습니다. 이 값들을 조작 API의 BeforeInertia 이벤트 핸들어에서 설정을 하게 되면 추가적인 코드 없이도 관성이 적용되어 자연스러운 움직임을 구현할 수 있습니다.

속성

설명

InertiaTimerInterval

관성처리 이벤트가 발생하는 간격

MaxInertiaSteps

발생되는 이벤트의 최대 개수

InitialVelocity

초기 속도 값

DesiredDisplacement

원하는 이동거리

InitialAngularVelocity

초기 회전하는 속도 값

DesiredRotation

원하는 회전 각도 (라디안 값으로 표현)



구현 예
닷넷 환경에서 구현된 코드 조각을 살펴보겠습니다.

using Windows7.Multitouch.Manipulation;

private readonly ManipulationInertiaProcessor processor;

processor = new ManipulationInertiaProcessor

(ProcessorManipulations.ALL, Factory.CreateTimer());

 

processor.ManipulationStarted += processor_ManipulationStarted;

processor.ManipulationDelta += processor_ManipulationDelta;

processor.ManipulationCompleted += processor_ManipulationCompleted;

// WM_TOUCH 데이터(멀티터치 Raw data)를 사용합니다.
_image.StylusDown += new StylusDownEventHandler(Window1_StylusDown);

_image.StylusMove += new StylusEventHandler(Window1_StylusMove);

_image.StylusUp += new StylusEventHandler(Window1_StylusUp);

// WM_TOUCH 데이터를 연결시킵니다.
void Window1_StylusUp(object sender, StylusEventArgs e)

{

   processor.ProcessUp((uint)e.StylusDevice.Id,

e.GetPosition(_canvas).ToDrawingPointF());

}

 

void Window1_StylusMove(object sender, StylusEventArgs e)

{

  processor.ProcessMove((uint)e.StylusDevice.Id,

e.GetPosition(_canvas).ToDrawingPointF());

}

 

void Window1_StylusDown(object sender, StylusDownEventArgs e)

{

   processor.ProcessDown((uint)e.StylusDevice.Id,

e.GetPosition(_canvas).ToDrawingPointF());

}

 

processor.BeforeInertia += processor_BeforeInertia;

void processor_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)

{

_translate.X += e.TranslationDelta.Width;

_translate.Y += e.TranslationDelta.Height;

_rotate.Angle += e.RotationDelta * 180 / Math.PI;

_scale.ScaleX *= e.ScaleDelta;

_scale.ScaleY *= e.ScaleDelta;

}

void processor_BeforeInertia(object sender, BeforeInertiaEventArgs e)

{

processor.InertiaProcessor.InertiaTimerInterval = 15;

processor.InertiaProcessor.MaxInertiaSteps = 500;

//processor.InertiaProcessor.InitialVelocity = … //processor.InertiaProcessor.DesiredDisplacement = …

//processor.InertiaProcessor.InitialAngularVelocity = …

//processor.InertiaProcessor.DesiredRotation = …

//processor.InertiaProcessor.InitialExpansionVelocity = …

//processor.InertiaProcessor.DesiredExpansion = …

}


ManipulationInertiaProcessor라는 클래스를 초기화 하고 ManipulationStarted, ManipulationDelta, ManipulationCompleted 이벤트 핸들러를 등록했습니다. 조작이 끝날때 Inertia를 초기화하면 관성도 적용을 할 수 있습니다.

한가지 더 있습니다. 탄성을 적용할 수 있습니다. 오브젝트를 벽에 던지면 튕겨 나오듯이 모니터의 경계면에 우리가 던지 오브젝트가 튕겨져 나오는 걸 시뮬레이션 할 수 있습니다. 아래처럼 간단한 코드를 넣으면 말이죠.

processor.InertiaProcessor.Boundary = new System.Drawing.RectangleF(1.0f, 1.0f, (float)_canvas.ActualWidth, (float)_canvas.ActualHeight);

processor.InertiaProcessor.ElasticMargin = new System.Drawing.RectangleF(200, 50, 800, 700);


이 코드의 이미는 아래 그림과 같이 관성이 적용될 영역을 지정하고 (Boundary) 관성이 적용될 영역(ElasticMargin)을 지정해 주는 방법 입니다.



Manipulation and Inertia 사용 소스코드 다운로드 : WpfManuplationAndInertia.zip (Visual Studio 2008, .NET Framework 3.5)


실행 결과를 아래 영상으로 확인할 수 있습니다.


WRITTEN BY
ONESTONE

트랙백  0 , 댓글  0개가 달렸습니다.
secret

본 강좌의 원본은 훈스닷넷에 있습니다.

연재 리스트 

  1. Windows 7 멀티터치 시작하기
  2. 미리 정의된 9가지 제스쳐 지원하기 (WM_GESTURE)
  3. 멀티터치 Raw 데이터를 사용 (WM_TOUCH)
  4. Manipulation and Inertia 활용
  5. WPF4 멀티터치 프로그래밍
  6. 실버라이트 4의 멀티터치 프로그래밍

이전 강좌에서 소개된 9개의 미리 정의된 제스쳐는 쉽고 빠른 개발 방법이지만 9개 이외의 다른 제스쳐를 만들어 낼 수는 없습니다. 그래서 새로운 인터페이스를 만들고 싶다면 멀티터치 데이터의 원본(Raw Data)을 이용할 수 있어야 합니다.

마우스를 프로그래밍할 때 생각해보면 마우스의 위치 값, 왼쪽 버튼 클릭, 오른쪽 버튼 클릭 등의 데이터가 있고 MouseDown, MouseMove, MouseUp 이벤트가 있는 것을 기억할 것입니다. 멀티터치도 다르지 않습니다. WP_TOUCH라는 Windows 7 Native 메시지가 비슷한 정보를 우리의 응용프로그램에 전달해 줍니다.

Win32 API에서 WM_TOUCH를 받으려면 먼저 우리가 다루고 있는 윈도우를 WM_TOUCH 메시지 전달이 가능하도록 RegisterTouchWindow() 함수를 이용하여 등록을 하는 과정이 필요합니다. 그러면 터치 입력이 있을 때마다 TOUCHINFO라는 구조체가 매개변수로 전달 되는데 GetTouchInputInfo() 함수를 호출하여 전달된 멀티터치 메시지 데이터를 분석 할 수 있습니다. 하지만 우리는 닷넷 환경에서 작업을 할 것이기 때문에 이런 등록과정은 숨겨져 있습니다.

다만 WP_TOUCH가 전달하는 메세지의 내용을 살펴볼 필요가 있습니다. WM_TOUCH 메시지의 자세한 내용은 MSDN을 참조하세요.

입력 값

설명

ID

여러 개의 터치입력을 구분하는 ID

위치

화면 좌표 (x,y)

Contact의 크기

터치입력의 너비 (cxContact, cyContact)

Primary Contact 인지?

첫 번째 터치입력이면 true

Palm 인지?

손가락 입력이 아니면 true

Time

터치입력 발생 시각



마우스 보다 다양한 내용을 전달하는 걸 볼 수 있고 멀티터치를 구분하기 위해 ID 값이 존재하는 것을 알 수 있습니다. 제가 테스트 한 멀티터치 디바이스에서 ID 값은 처음 터치입력은 ID 10, 두 번째 터치는 11, 세 번째 터치는 12처럼 1씩 증가하면서 부여되고 모든 터치가 제거된 후에 다시 터치 입력을 하면 다시 ID 10부터 시작을 하는 식으로 부여됩니다. 이런식의 ID 변화는 손가락이 현재 몇개가 터치되어 있는지 확인 할 수 있겠죠.

당연히 화면에서의 위치 정보(이것은 마우스의 위치를 정하는 방법과 같습니다)가 있고 터치 입력의 넓이가 있습니다. 또한 첫번째 손가락인지, 손가락이 아니고 손바닥인지를 알 수 도 있습니다.

윈폼(WinForm) 환경에서 터치 데이터 활용
아래 코드처럼 TouchHandler 인스턴스를 생성하고 TouchDown, TouchMove, TouchUp 이벤트 핸들러를 등록합니다. 이벤트 핸들러에서 전달된 매개변수를 열어보면 위의 표에서 설명된 터치 입력에 대한 원시 데이터가 전달된 것을 확인 할 수 있죠. 이 코드는 마우스를 다루는 코드와 같군요. 다만 여러개가 입력될 수도 있다는 걸 제외하면요.

윈폼에서는 Windows7.Multitouch.WinForms.dll 을 사용합니다. 이 어셈블리를 구하는 방법은 이전 강좌에서 확인하세요.

using Windows7.Multitouch;

private TouchHandler _touchHandler;

_touchHandler = Factory.CreateHandler<TouchHandler>(this);

_touchHandler.TouchDown += OnTouchDownHandler;

_touchHandler.TouchMove += OnTouchMoveHandler;

_touchHandler.TouchUp += OnTouchUpHandler;

 

private void OnTouchDownHandler(object sender,TouchEventArgs e)

{

//e.Location

//e.Id

//e.AbsoluteTime

//e.ContactSize

//e.IsPrimaryContact

//e.IsTouchPalm

}

윈폼 샘플 소스코드 : TouchDataVisualization.zip (Visual Studio 2008, WinForm, .NET Framework 3.5)


소스코드는 손가락을 올렸을 때 손가락의 정보를 보여줍니다. 여기에서는 아이디가 10, 100 이런식으로 부여되네요. 아이디 부여 방식은 디바이스 드라이버 마다 다른지 확인을 해봐야겠습니다.


실행 결과를 영상으로 보세요.



동영상이 안보이면 http://tvpot.daum.net/my/ClipView.do?ownerid=ADowB8WbINw0&clipid=25737296&q=

한가지 기억할 것은 WP_TOUCH를 이용하면 WP_GESTURE를 이용할 수 없다는 것입니다. 즉, 터치의 포인트에 대한 정보를 받으면서 동시에 9가지 제스쳐를 다룰 수 없다는 것이죠.

WPF에서 멀티터치 원시 데이터를 이용하는  방법 (.NET Framework 3.5)
WPF에서도 같은 방법으로 프로그래밍을 합니다. WPF에서는 Windows7.Multitouch.WPF.dll을 참조해서 해야죠. 내부적인 방식이 약간 다른데 스타일러스 펜의 입력을 약간 우회하는 방법을 사용하나 봅니다. 소스를 따라 들어가다 보니 아래와 같은 코드가 있던데요. 이것은 아마도 WPF4가 나오기전에 멀티터치 프로그래밍을 위해서 스타일러스 입력을 활용할 수 있도록 열여주는 코드 같습니다.

HwndSource hs = (HwndSource)PresentationSource.FromVisual(this);
SetProp(new HandleRef(this, hs.Handle),     

"MicrosoftTabletPenServiceProperty", new HandleRef(null,    

new IntPtr(0x01000000)));


어째든 우리는 윈폼의 코드와 같은 방식으로 프로그래밍이 가능합니다.

Loaded += (s, e) => { Factory.EnableStylusEvents(this); };

 

StylusDown += OnTouchDownHandler;

StylusMove += OnTouchMoveHandler;

StylusUp += OnTouchUpHandler;


WPF 소스코드 다운로드 : TouchDataVisualization.zip (Visual Studio 2008, .NET 3.5)


실행한 결과는 아래 영상에서 확인 할 수 있습니다. 윈폼의 실행결과와 같습니다.



동영상이 보이지 않으면 : http://tvpot.daum.net/my/ClipView.do?ownerid=ADowB8WbINw0&clipid=25737794&q=

우리는 멀티터치의 원시 데이터(Raw Data)를 얻었습니다. 이 데이터를 가지고 프로그래밍을 하여 다양한 제스쳐를 만들거나 손가락을 그림을 그리는 등의 여러 아이디어 구현에 활용 할 수 있습니다.

이 강좌의 소스는 .NET Framework 3.5 를 사용했지만 WPF 4가 나오면서 조금더 세련되고 쉬운 방법으로 멀티터치를 프로그래밍을 할 수 있습니다. 다음 강좌에서 그 방법을 확인해 보세요.





WRITTEN BY
ONESTONE

트랙백  0 , 댓글  1개가 달렸습니다.
  1. keugbang 2015.09.22 18:59
    마이크로소프트의 링크가 이젠 사라지고 없군요. 하지만 첨부하신 예제 소스파일 덕분에 많은 도움이 되었습니다.
secret

본 강좌의 원본은 훈스닷넷에 있습니다.

연재 리스트 

  1. Windows 7 멀티터치 시작하기
  2. 미리 정의된 9가지 제스쳐 지원하기 (WM_GESTURE)
  3. 멀티터치 Raw 데이터를 사용 (WM_TOUCH)
  4. Manipulation and Inertia 활용
  5. WPF4 멀티터치 프로그래밍
  6. 실버라이트 4의 멀티터치 프로그래밍


관련 어셈블리(DLL) 다운로드 하기
시작하기전에 관련 DLL을 다운로드 해서 사용해야 합니다. 윈도우 7의 멀티터치 지원 API들은 모두 Win32 네이티브 API들입니다. Win32 환경에서는 직접 호출하여 사용을 할 수 있지만 .NET 프레임워크 환경에서는 직접 호출하여 사용할 수 없습니다.

따라서 .NET 프레임워크 환경에서 Win32 환경의 멀티터치 API를 호출할 수 있도록 해줘야 하는데 이 라이브러리가 공개되어 있습니다. Windows 7 Multitouch .NET Interop Sample Library 링크를 통해서 소스코드까지 다운로드 받을 수 있으며 비주얼 스튜디오를 이용하여 빌드하면 결과로 나오는 어셈블리 3가지 Windows7.Multitouch.dll, Windows7.Multitouch.WPF.dll, Windows7.Multitouch.WinForms.dll를 .NET 응용프로그램 소스코드에 참조로 등록하여 사용해야 합니다. 준비를 해 주세요.

MICROSOFT PUBLIC LICENSE 를 따르고 있으므로 꼭 다운로드 하셔야 합니다.

9가지 정해져 있는 멀티터치 제스쳐 (WM_GESTURE 메세지)

WM_GESTURE 메시지를 이용한 멀티터치 개발은 가장 쉽고 단순하게 윈도우 7에서 멀티터치를 구현하는 방법으로 정해진 9가지의 제스처를 이용하는 방법입니다. 먼저 9가지의 제스처를 아래 그림으로 살펴봅시다.


(출처 : MSDN, http://msdn.microsoft.com/ko-kr/library/dd940543(v=VS.85).aspx)

그림에서 보면 9가지 제스처와 그에 상응하는 마우스와 키보드 사용법을 매치 시켜놨습니다. 모든 제스처가 하나 또는 두 개의 터치입력으로 이루어진 제스처들인데 이는 두 개의 터치입력만 가능한 디바이스에서도 문제가 없도록 디자인을 했나봅니다.

어찌되었건 Windows 7은 멀티터치 디바이스에서 전달한 데이터를 가지고 저런 제스쳐를 만들어 프로그래머에게 던져 줍니다. 프로그래머는 그 이벤트를 받아서 마치 마우스나 키보드 컨트롤 하듯이 프로그래밍을 하면 쉽게 우리의 응용프로그램에 멀티터치 기능을 추가할 수 있습니다. 프로그래밍을 해봅시다.

다시 말하지만 Windows 7의 멀티터치 지원은 Windows의 Native API이므로 우리는 닷넷에서 사용가능하도록 랩핑된 어셈블리를 사용하겠습니다. 그리고 WPF 환경에서 샘플을 만들 예정이라서 주로 Windows7.Multitouch.WPF.dll 에 있는 내용을 사용하겠습니다.

소스코드 다운로드 하기 : Win7MultitouchCapabilities.zip (Visual Studion 2008, WPF)



멀티터치를 지원하는지 확인하기
먼저 해야 할 작업은 무엇보다 응용프로그램이 실행된 환경이 멀티터치가 가능한 환경인지 확인을 하는 하는 것입니다. 이 작업은 Win32 네이티브 API 중에서 GetSystemMetrics() 함수의 호출을 통해서 확인 할 수 합니다. 반환되는 값을 분석하면 추가적으로 몇 개의 멀티터치 포인트를 지원하는지, 터치 디바이스가 내장인지 외장인지에 대해서도 알 수 있다. .NET 환경에서는 아래 코드로 확인 할 수 있다. 우리는 이런 검사를 통해서 멀티터치가 가능한 상태에서의 반응과 가능하지 않은 상태에서의 반응을 다르게 프로그래밍 할 수도 있을 것입니다. 여기에서는 프로그램을 종료시켜 버렸는데 사실 좋은 프로그래밍이 아니죠.

using Windows7.Multitouch;

 

if (!GestureHandler.DigitizerCapabilities.IsMultiTouchReady)

{

MessageBox.Show("Multitouch is not availible");

Environment.Exit(1);

}

else

{

int numberoftouches =GestureHandler.DigitizerCapabilities.MaxumumTouches;

MessageBox.Show(numberoftouches + "개의 터치입력 가능");

}


저는 멀티터치 디바이스가 없는 PC에서 작업을 하고 있어서 Multitouch Vista라는 오픈소소의 도움을 받고 있는데요. 이 상태에서 실행시켜보니 아래처럼 255개의 포인트를 지원하네요. 멀티마우스를 손가락으로 시뮬레이션하기 때문에 최대값을 저렇게 지정을 했나봅니다. 실제로 마우스 255개를 붙이면 될까요? ^^



9개의 제스쳐 활용하기
Windows 7의 Native API가 전달해주는 구조체는 MSDN에서 확인 할 수 있는데 조금 복잡해 보일 수 도 있습니다. 하지만 닷넷, WPF에서는 우리가 기존에 마우스 이벤트를 다뤘던 경험만 있으면 어려워 보이는 9가지 제스쳐를 쉽게 구현할 수 있습니다. 먼저 코드를 살펴봅시다.

using Windows7.Multitouch;

GestureHandler _gestureHandler = Factory.CreateGestureHandler(this);

 

_gestureHandler.Pan += ProcessPan;

_gestureHandler.Rotate += ProcessRotate;

_gestureHandler.PressAndTap += ProcessPressAndTap;

_gestureHandler.TwoFingerTap += ProcessTwoFingerTap;

_gestureHandler.Zoom += ProcessZoom;

private void ProcessPan(object sender, GestureEventArgs args)

{

trans.X += args.PanTranslation.Width;

trans.Y += args.PanTranslation.Height;

}

private void ProcessRotate(object sender, GestureEventArgs args)

{

rotate.Angle -= args.RotateAngle * 180 / Math.PI;

}

private void ProcessPressAndTap(object sender, GestureEventArgs args)

{

rectangle.Fill = new SolidColorBrush(Colors.Blue);

}

 

private void ProcessTwoFingerTap(object sender, GestureEventArgs args)

{

rectangle.Fill = new SolidColorBrush(Colors.Red);

}

private void ProcessZoom(object sender, GestureEventArgs args)

{

scale.ScaleX *= args.ZoomFactor;

scale.ScaleY *= args.ZoomFactor;

}


원하는 제스쳐 선택하고 이벤트 핸들러를 등록한 다음 이벤트 핸들러에서 전달되는 매개변수 값을 이용하여 프로그래밍을 하면 됩니다. 참 쉽죠 잉~~. 아래 코드를 다운로드 하여 실행 시켜 봅시다. 

소스코드 다운로드 : WpfTouchGesture.zip (Visual Studion 2008, WPF)


실행한 영상을 아래 첨부 합니다. 마이크가 없어서 목소리 없이 그냥 ... 중간에 손가락을 빨간색 점으로 표시하고 박스도 빨간색이니 포인트가 안보여서 다시 소스를 보는 장면이 있는데 소스를 보니 Two Finger Tap이 박스의 색을 파란색으로 바꿔줍니다.



영상이 안보이면 http://tvpot.daum.net/my/ClipView.do?ownerid=ADowB8WbINw0&clipid=25736362

9개의 제스쳐를 활용한 프로그래밍은 단순해서 좋지만 한가지 단점이 있습니다. 한번에 하나의 제스쳐만 가능하기 때문에 사각형 박스를 돌리면서 동시에 이동을 할 수가 없습니다. 그래서 조금 부자연스럽다고 느끼게 됩니다.

하지만 응용프로그램의 설계에 따라서 필요한 제스쳐를 선택하고 적절히 사용한다면 문제가 없을 것입니다.


WRITTEN BY
ONESTONE

트랙백  0 , 댓글  0개가 달렸습니다.
secret

개발자를 위한 Windows 7 세미나 시리즈 그 마지막 "멀티터치를 활용한 응용 프로그램 개발 가이드" ...
계속되는 외근으로 인해 여유가 없어서 발표자료를 이제야 올려 드립니다.

발표자료
세션 1 윈도우 7 멀티터치 개발의 세계로
세션1 PPT 발표자료 다운로드

세션 1 개발환경 : Windows 7, Visual Studio 2008, Windows 7 SDK, .NET Framework 3.5 SP1

WM_GESTURE 메시지
Win7MultitouchCapabilities 샘플 : 터치가 가능한 API인지 확인하는 방법에 대한 샘플
WpfTouchGesture : WPF 환경에서 WM_GESTURE 메시지를 이용한 멀티터치 샘플

WM_TOUCH 메시지
TouchDataVisualization : WinForm 환경에서 WM_TOUCH 메시지를 이용한 멀티터치 샘플
WPFTouchDataVisualization : WPF 환경에서 WM_TOUCH 메시지를 이용한 멀티터치 샘플

Manuplation and Inertia
WpfManuplationAndInertia : WPF 환경에서 Manuplation and Inertia API를 활용한 멀티터치 샘플

세션2 멀티터치 WPF 4를 주목하라
세션2 PPT 발표자료 다운로드

세션2 개발환경 : Windows 7, Visual Studio 2010 beta 1, .NET Framework 3 beta 1

WPF4MultiTouchSample : .NET 4에서 Image 컨트롤의 멀티터치 활용 샘플
WPF4ScatterViewSample : .NET 4에서 제공하는 멀티터치 전용 컨트롤 ScatterView 샘플

많은 분들이 함께 해 주셔서 감사했습니다.
모두들 Windows 7의 세로운 가능성을 알아보고 미리 준비를 하시는 분들이겠죠. 마이크로소프트에서는 그저 Windows Native API에 멀티터치 지원을 추가했지만 새로운 경험, 새로운 인터페이스, 새로운 인터렉션을 만들어 내는 것은 결국 개발자, 기획자, 디자이너의 협업이라고 생각합니다. 화이팅 ~


WRITTEN BY
ONESTONE

트랙백  1 , 댓글  0개가 달렸습니다.
secret
멀티터치가 지원되는 하드웨어

현재까지 출시된 Windows 7에서 멀티터치가 가능한 하드웨어를 살펴보겠습니다.


HP Touch smart PC
터치 포인트 2개 인식. 감도가 매우 떨어진다는 평가


TouchSmart tx2 Multi-Touch Notebook
HP Touch Smart TX2 노트북 PC
터치 포인트 4개 인식. 감도가 그나마 좋음

dell-xt.png
Dell Latitude XT 노트북

그 외에는 3M에서 멀티터치 관련 개발자 킷을 판매한다는 기사가 있었는데 추가적인 소식은 없습니다. LG와 삼성에서도 멀티터치 제품을 열심히 만들고 있다는 소식이 들리기는 합니다.


멀티터치 지원 하드웨어가 없어요.

Windows 7의 멀티터치 개요에서 말씀드린 것처럼 현재는 몇가지 하드웨어가 출시되었습니다. 유투브 "Windows 7 Multi touch"라고 검색을 하면 그 하드웨어를 사용한 데모 영상들이 많이 있습니다.

하지만 우리는 당장 멀티터치가 지원되는 노트북이나 PC를 구할 수가 없네요. 멀티터치로 윈도우를 사용해 보고 싶기도하고 몇가지 샘플을 돌려서 개발을 해보고 싶기도 한데 말이죠.

이 글을 읽는 여러분이 개발자이고 멀티터치 개발에 관심이 있으며 Windows 7을 설치하셨다면 이 글을 통해서 여러개의 마우스를 붙여서 가상의 멀티터치 환경을 만들 수 있습니다. 즉, 비싼돈을 주고 멀티터치 하드웨어를 구입하지 않아도 왠만큼 테스트를 해볼 수 있습니다.

오픈소스 프로젝트 Multi-touch Vista

오픈소스 커뮤니티인 Codeplex에 가면 Multi-touch Vista라는 프로젝트가 있습니다. 원래는 윈도우 비스타 환경에서 멀티터치가 가능하도록 해주는 프로젝트인데 Windows 7이 나온 지금 멀티터치 디바이스 드라이버도 오픈소스로 제공을 하고 있습니다. 이 디바이스 드라이버를 이용해서 여러개의 마우스를 이용해서 멀티터치를 가상으로 시뮬레이션 할 수 있게 설정할 수 있습니다. 주인장인 nesher에게 감사드립니다. 친절하게도 설정방법까지 상세히 비디오로 정리를 해주었습니다.



위에서 설명된 방법으로 필요한 파일들을 다운 받고 설정을 해주고 마우스를 여러개 붙이면 멀터터치가 가능하게 됩니다.

저는 노트북을 사용하고 있어서 트랙패드와 무선 마우스 두개로 실행을 해봤는데 잘 작동을 하네요. 개발자 여러분 멀티터치 하드웨어가 없다면 이 환경에서 테스트 해보시기를 바랍니다. 시뮬레이터다 생각을 하면 되겠습니다. 하지만 터치 인터페이스는 직접 터치를 해봐야 느낌이 온다는 점을 잊지 말아야 할 것 같습니다.

Thanks for nesher's work!

WRITTEN BY
ONESTONE

트랙백  0 , 댓글  0개가 달렸습니다.
secret