首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows 7 多點觸控開發實戰:從滑鼠操作升級至多指觸控應用

     編輯:關於.NET

概述

Windows 7 引入了原生多點觸控支援,讓使用者能直接以手指操作應用程式,無需滑鼠或觸控筆等中介裝置。這項技術擴展了平板電腦原有的觸控筆功能,並支援多個觸控點同時輸入,實現十指同步操作甚至多使用者協作等複雜場景。然而,要充分發揮多點觸控優勢,開發者必須調整應用程式的使用者介面與行為,以適應全新的輸入模式。

本實驗將引導您將一個基於滑鼠的簡單圖片操作應用程式,逐步升級為支援多點觸控的現代化應用,體驗類似 Microsoft Surface 的互動效果。

啟用多點觸控的應用程式示例

圖 1:啟用了多點觸控的應用程式

學習目標

  • 理解同時操作多個物件的意義與實作方式
  • 檢測多點觸控硬體是否存在及就緒狀態
  • 在 WPF 3.5 SP1 中實作多點觸控事件處理
  • 透過內建 WPF 觸控筆事件使用多點觸控
  • 運用操作與慣性處理器提升觸控體驗

環境準備

為方便實驗,我們以 Visual Studio 程式碼片段形式提供所需程式碼。請先執行實驗 Setup 資料夾下的 MultiTouchLab.vsi 安裝程式碼片段。

系統需求

  • Microsoft Visual Studio 2008 SP1
  • Windows 7 作業系統
  • Windows 7 Integration Library 範例(Windows Touch:開發人員資源)
  • 一台支援多點觸控的硬體設備

練習 1:開發多點觸控圖片處理應用程式

要掌握多點觸控輸入處理,首先需理解單點滑鼠輸入的處理方式。我們準備了一個基於滑鼠的圖片處理應用程式作為起點。

任務 1:認識初始解決方案

  1. 開啟位於 %TrainingKitInstallDir%\MultiTouch\Ex1-PictureHandling\Begin 的初始解決方案,選擇 C# 或 VB.NET 版本。
  2. 編譯並執行。您可以:單擊選取圖片、按住滑鼠左鍵拖曳移動、使用滑鼠滾輪縮放。每次選取圖片時,該圖片會移至最上層。

應用程式架構解析

應用程式以 Picture 使用者控制項代表每張圖片,基於 WPF 建立。其 XAML 定義如下:

<UserControl x:Class="MultitouchHOL.Picture"
 xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
 <Image Source="{Binding Path=ImagePath}" Stretch="Fill" Width="Auto"
 Height="Auto" RenderTransformOrigin="0.5, 0.5">
 <Image.RenderTransform>
 <TransformGroup>
 <RotateTransform Angle="{Binding Path=Angle}"></RotateTransform>
 <ScaleTransform ScaleX="{Binding Path=ScaleX}" ScaleY="{Binding Path=ScaleY}">
 </ScaleTransform>
 <TranslateTransform X="{Binding Path=X}" Y="{Binding Path=Y}"/>
 </TransformGroup>
 </Image.RenderTransform>
 </Image>
 </UserControl>

該控制項的程式碼僅包含 ImagePath、Angle、ScaleX、ScaleY、X、Y 等相依屬性宣告,分別對應圖片路徑、旋轉角度、縮放比例與中心座標。

MainWindow 結構

主視窗 XAML 僅包含一個 Canvas 面板(名為 _canvas),作為承載 Picture 控制項的容器:

<Window x:Class="MultitouchHOL.MainWindow"
 xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
 Title="MultitouchHOL" Height="300" Width="300" WindowState="Maximized"
 xmlns:mt="clr-namespace:MultitouchHOL">
 <Canvas Name="_canvas"></Canvas>
 </Window>

滑鼠事件處理邏輯

MainWindow 類別透過 _picture 成員追蹤目前被拖曳的圖片,_prevLocation 記錄上一次滑鼠位置以計算位移。建構函式註冊滑鼠事件:

public MainWindow()
{
 InitializeComponent();
 this.Loaded += (s, e) => { LoadPictures(); };
 MouseLeftButtonDown += ProcessDown;
 MouseMove += ProcessMove;
 MouseLeftButtonUp += ProcessUp;
 MouseWheel += ProcessMouseWheel;
}

LoadPictures() 從使用者圖片資料夾載入圖片並建立對應的 Picture 控制項。

核心事件處理函式
  • ProcessDown:取得相對於 Canvas 的指標位置,呼叫 FindPicture() 進行視覺樹點擊測試找到最上層圖片,並透過 BringPictureToFront() 將其置於最上層。
  • ProcessMove:若滑鼠左鍵未按下或未選取圖片則返回;否則計算位移量並更新圖片的 X、Y 屬性,更新 _prevLocation。
  • ProcessMouseWheel:取得滑鼠位置下的圖片,置於最上層,根據滑鼠滾輪增量計算縮放因子並更新 ScaleX、ScaleY。

任務 2:檢測多點觸控硬體就緒狀態

雖然 WPF 3.5 不原生支援多點觸控(WPF 4.0 才內建),但可透過 Windows 7 Integration Library 範例在當前版本中實現。該程式庫示範如何在 .NET 程式碼中呼叫 Win32 原生 API。

  1. 加入 Windows7.Multitouch.dll 與 Windows7.Multitouch.WPF.dll 參考。
  2. 在 MainWindow 建構函式中加入檢測程式碼:
if (!Windows7.Multitouch.TouchHandler.DigitizerCapabilities.IsMultiTouchReady)
{
 MessageBox.Show("Multitouch is not available");
 Environment.Exit(1);
}

您還可檢視 TouchHandler.DigitizerCapabilities 的其他屬性以獲取更多硬體資訊。

TouchHandler.DigitizerCapabilities 屬性檢視

圖 2:查看 TouchHandler.DigitizerCapabilities 屬性

任務 3:以觸控筆事件取代滑鼠事件

為啟用手指觸控操作,需移除滑鼠事件註冊,改用觸控筆事件。

  1. 加入命名空間:using Windows7.Multitouch; using Windows7.Multitouch.WPF;
  2. 在 Loaded 事件中呼叫 Factory.EnableStylusEvents(this),指示系統以觸控筆事件形式發送觸控事件。
  3. 移除 ProcessMouseWheel 及其註冊(縮放功能稍後實作)。
  4. (C#)移除滑鼠事件註冊程式碼,建構函式簡化為僅含硬體檢測與啟用觸控筆事件。
  5. 修改事件處理函式簽名,改用 StylusEventArgs:
public void ProcessDown(object sender, StylusEventArgs args)
{
 _prevLocation = args.GetPosition(_canvas);
 _picture = FindPicture(_prevLocation);
 BringPictureToFront(_picture);
}

public void ProcessMove(object sender, StylusEventArgs args)
{
 if (_picture == null) return;
 Point newLocation = args.GetPosition(_canvas);
 _picture.X += newLocation.X - _prevLocation.X;
 _picture.Y += newLocation.Y - _prevLocation.Y;
 _prevLocation = newLocation;
}

public void ProcessUp(object sender, StylusEventArgs args)
{
 _picture = null;
}
  1. 註冊觸控筆事件:StylusDown += ProcessDown; StylusUp += ProcessUp; StylusMove += ProcessMove;
  2. 編譯執行,嘗試用手指操作圖片!

思考:若嘗試使用多根手指會發生什麼情況?為什麼?

任務 4:同時處理多張圖片(真正的多點觸控)

每根觸控螢幕的手指都會獲得唯一的觸控 ID,只要手指持續接觸,系統就會保持該 ID 關聯。我們需將觸控 ID 與對應圖片建立連結,實現多指同時操作不同圖片。

透過 args.StylusDevice.Id 可從觸控筆事件參數中取得觸控 ID。WPF 會為每根手指持續觸發帶有相同 ID 的事件。

設計 PictureTracker 與 PictureTrackerManager

為同時追蹤多張圖片,我們引入兩個類別:

  • PictureTracker:封裝單一圖片的觸控處理邏輯,包含 ProcessDown、ProcessMove、ProcessUp 方法。
  • PictureTrackerManager:管理觸控 ID 到 PictureTracker 的對應字典,負責分派觸控事件給正確的追蹤器。

核心邏輯:GetPictureTracker 方法

此方法處理三種觸控按下情境:

  1. 手指觸碰空白處 → 不建立追蹤器。
  2. 手指觸碰新圖片 → 建立新 PictureTracker 並加入字典。
  3. 第二根(或更多)手指觸碰已被追蹤的圖片 → 將新觸控 ID 關聯至同一 PictureTracker。

移動與抬起事件則根據觸控 ID 在字典中查找對應追蹤器並轉發處理,最後一個關聯觸控 ID 釋放時移除追蹤器。

完整 PictureTrackerManager 實作

class PictureTrackerManager
{
 private readonly Dictionary<int, PictureTracker> _pictureTrackerMap = new Dictionary<int, PictureTracker>();
 private readonly Canvas _canvas;

 public PictureTrackerManager(Canvas canvas) { _canvas = canvas; }

 public void ProcessDown(object sender, StylusEventArgs args) { ... }
 public void ProcessUp(object sender, StylusEventArgs args) { ... }
 public void ProcessMove(object sender, StylusEventArgs args) { ... }

 private PictureTracker GetPictureTracker(int touchId) { ... }
 private PictureTracker GetPictureTracker(int touchId, Point location) { ... }
 private Picture FindPicture(Point location) { ... }
 private void BringPictureToFront(Picture picture) { ... }
}

此架構確保每根手指獨立控制對應圖片,實現真正的多點觸控體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved