다음을 통해 공유


Windows Touch 스크래치 패드 샘플(C#)

C#의 Windows Touch Scratchpad 샘플에서는 Windows Touch 메시지를 사용하여 터치 지점의 추적을 창에 그리는 방법을 보여 줍니다. 디지타이저에 먼저 놓인 기본 손가락의 추적은 검은색으로 그려집니다. 보조 손가락은 빨간색, 녹색, 파란색, 시안색, 마젠타 및 노란색의 여섯 가지 다른 색으로 그려집니다. 다음 이미지는 애플리케이션이 실행되면 어떻게 보이는지 보여줍니다.

화면에 검은색, 녹색, 파란색 및 빨간색 물결선이 있는 c sharp의 Windows 터치 스크래치 패드 샘플을 보여 주는 스크린샷

이 샘플의 경우 WM_TOUCH 메시지를 처리하기 위해 터치 가능한 양식 만들어집니다. 이 양식은 스크래치 패드 애플리케이션에서 Windows Touch를 사용하도록 설정하기 위해 상속됩니다. WM_TOUCH 메시지가 양식에 오면 포인트로 해석되고 스트로크 컬렉션에 추가됩니다. strokes 컬렉션은 Graphics 개체에 렌더링됩니다. 다음 코드에서는 터치 가능한 양식이 WM_TOUCH 메시지를 처리하기 위해 자신을 등록하는 방법과 WM_TOUCH 메시지를 처리하는 방법을 보여 줍니다.

        private void OnLoadHandler(Object sender, EventArgs e)
        {
            try
            {
                // Registering the window for multi-touch, using the default settings.
                // p/invoking into user32.dll
                if (!RegisterTouchWindow(this.Handle, 0))
                {
                    Debug.Print("ERROR: Could not register window for multi-touch");
                }
            }
            catch (Exception exception)
            {
                Debug.Print("ERROR: RegisterTouchWindow API not available");
                Debug.Print(exception.ToString());
                MessageBox.Show("RegisterTouchWindow API not available", "MTScratchpadWMTouch ERROR",
                    MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
            }
        }
(...)
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        protected override void WndProc(ref Message m)
        {
            // Decode and handle WM_TOUCH message.
            bool handled;
            switch (m.Msg)
            {
                case WM_TOUCH:
                    handled = DecodeTouch(ref m);
                    break;
                default:
                    handled = false;
                    break;
            }

            // Call parent WndProc for default message processing.
            base.WndProc(ref m);

            if (handled)
            {
                // Acknowledge event if handled.
                m.Result = new System.IntPtr(1);
            }
        }

다음 코드에서는 Windows Touch 메시지가 해석되고 데이터가 스트로크 컬렉션에 추가되는 방법을 보여 줍니다.

        private bool DecodeTouch(ref Message m)
        {
            // More than one touchinput may be associated with a touch message,
            // so an array is needed to get all event information.
            int inputCount = LoWord(m.WParam.ToInt32()); // Number of touch inputs, actual per-contact messages

            TOUCHINPUT[] inputs; // Array of TOUCHINPUT structures
            inputs = new TOUCHINPUT[inputCount]; // Allocate the storage for the parameters of the per-contact messages

            // Unpack message parameters into the array of TOUCHINPUT structures, each
            // representing a message for one single contact.
            if (!GetTouchInputInfo(m.LParam, inputCount, inputs, touchInputSize))
            {
                // Get touch info failed.
                return false;
            }

            // For each contact, dispatch the message to the appropriate message
            // handler.
            bool handled = false; // Boolean, is message handled
            for (int i = 0; i < inputCount; i++)
            {
                TOUCHINPUT ti = inputs[i];

                // Assign a handler to this message.
                EventHandler<WMTouchEventArgs> handler = null;     // Touch event handler
                if ((ti.dwFlags & TOUCHEVENTF_DOWN) != 0)
                {
                    handler = Touchdown;
                }
                else if ((ti.dwFlags & TOUCHEVENTF_UP) != 0)
                {
                    handler = Touchup;
                }
                else if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0)
                {
                    handler = TouchMove;
                }

                // Convert message parameters into touch event arguments and handle the event.
                if (handler != null)
                {
                    // Convert the raw touchinput message into a touchevent.
                    WMTouchEventArgs te = new WMTouchEventArgs(); // Touch event arguments

                    // TOUCHINFO point coordinates and contact size is in 1/100 of a pixel; convert it to pixels.
                    // Also convert screen to client coordinates.
                    te.ContactY = ti.cyContact/100;
                    te.ContactX = ti.cxContact/100;
                    te.Id = ti.dwID;
                    {
                        Point pt = PointToClient(new Point(ti.x/100, ti.y/100));
                        te.LocationX = pt.X;
                        te.LocationY = pt.Y;
                    }
                    te.Time = ti.dwTime;
                    te.Mask = ti.dwMask;
                    te.Flags = ti.dwFlags;

                    // Invoke the event handler.
                    handler(this, te);

                    // Mark this event as handled.
                    handled = true;
                }
            }

            CloseTouchInputHandle(m.LParam);

            return handled;
        }
    }

다음 코드는 스트로크 컬렉션이 표시되는 방법을 보여줍니다.

        public void Draw(Graphics graphics)
        {
            if ((points.Count < 2) || (graphics == null))
            {
                return;
            }

            Pen pen = new Pen(color, penWidth);
            graphics.DrawLines(pen, (Point[]) points.ToArray(typeof(Point)));
        }

다음 코드에서는 개별 스트로크 개체가 Graphics 개체를 사용하여 자신을 표시하는 방법을 보여 줍니다.

        public void Draw(Graphics graphics)
        {
            if(points.Count < 2 || graphics == null)
            {
                return;
            }

            Pen pen = new Pen(color, penWidth);
            graphics.DrawLines(pen, (Point[]) points.ToArray(typeof(Point)));
        }

Windows 터치 스크래치 패드 샘플(C++),멀티 터치 스크래치패드 애플리케이션(WM_TOUCH/C#),멀티 터치 스크래치패드 애플리케이션(WM_TOUCH/C++), Windows Touch 샘플