Windows Touch Scratchpad-Beispiel (C#)

Das Windows Touch Scratchpad-Beispiel in C# zeigt, wie Sie Windows Touch-Nachrichten verwenden, um Ablaufverfolgungen der Touchpunkte in einem Fenster zu zeichnen. Die Spur des primären Fingers, der zuerst auf den Digitizer gelegt wurde, ist schwarz gezeichnet. Sekundäre Finger werden in sechs weiteren Farben gezeichnet: Rot, Grün, Blau, Cyan, Magenta und Gelb. Die folgende Abbildung zeigt, wie die Anwendung aussehen könnte, wenn sie ausgeführt wird.

Screenshot, der das Windows-Touch-Scratchpad-Beispiel in c scharf zeigt, mit schwarzen, grünen, blauen und roten Wellen auf dem Bildschirm

Für dieses Beispiel wird ein touchierbares Formular erstellt, um WM_TOUCH Nachrichten zu verarbeiten. Dieses Formular wird geerbt, um Windows Touch auf der Scratchpad-Anwendung zu aktivieren. Wenn die WM_TOUCH Nachrichten in das Formular gelangen, werden sie in Punkte interpretiert und der Auflistung der Striche hinzugefügt. Die Strichauflistung wird in das Graphics-Objekt gerendert. Der folgende Code zeigt, wie sich das touchbare Formular für die Verarbeitung WM_TOUCH Nachrichten registriert und wie es WM_TOUCH-Nachrichten verarbeitet.

        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);
            }
        }

Der folgende Code zeigt, wie die Windows Touch-Nachricht interpretiert und die Daten zu Strichsammlungen hinzugefügt werden.

        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;
        }
    }

Der folgende Code zeigt, wie eine Strichauflistung angezeigt wird.

        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)));
        }

Der folgende Code zeigt, wie sich die einzelnen Strichobjekte mit einem Graphics-Objekt darstellen.

        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 Touch Scratchpad-Beispiel (C++),Multitouch Scratchpad-Anwendung (WM_TOUCH/C#),Multitouch Scratchpad-Anwendung (WM_TOUCH/C++),Windows-Touch-Touch-Beispiele