9

.NET Framework4を対象とする既存のWindowsフォームデスクトップアプリケーションがあり、それにWindows8タッチサポートを追加したいと思います。

現在、このプログラムはWindows 8で正常に動作します。一部の要素のサイズを変更するだけで、タッチデバイスでより使いやすくなる可能性があります。ただし、データグリッドにピンチしてズームするなどのジェスチャを追加したり、他の要素のスワイプサポートを追加したりすると、タッチオンリー環境でアプリケーションをより最新のものにするのに大いに役立ちます。

Visual Studio 2012に投資しています。これにより、.NET4.5と新しいWindows8機能をターゲットにできますが、アプリケーションの更新に役立つリソースを知っている人はいますか?私は特に次のことを心配しています:

  • 非タッチ開発マシンでアプリケーションのタッチ機能を直接テストできない。MicrosoftのシミュレーターはMetroアプリのみをサポートしているようです。Splashtopなどのタブレットアプリが役立つと聞きましたが(私はAndroidタブレットを持っています)、この特定のシナリオに具体的なものは何も見ていません。
  • WinFormsアプリケーションでジェスチャがサポートされているかどうか。これを機能させるには、UI全体をWPFにアップグレードする必要がありますか?(このルートを使用した場合、マルチタッチはWPF 4でサポートされているため、Windows 7もターゲットにできると思います)
  • MicrosoftのWindowsRTOfficeアプリのタッチモード設定と同様に、実行時にデバイスのタッチサポートを検出し、UIを適切にスケーリング/変更します。新しい機能を追加するためだけにプロジェクトをフォークしたくありません
  • タッチインタラクションの自動テスト

これは決して網羅的なリストではありませんが、過去に同様のアップグレードに取り組んだ可能性のある人からのアドバイスをいただければ幸いです。

4

5 に答える 5

6

コンポーネント1からWinForms用のTouchToolkitを使用できます。ただし、これらのコンポーネントを使用するには、アプリケーションを書き直す必要があると思います。

ここに画像の説明を入力してください

于 2014-07-28T00:48:30.740 に答える
6

ユーザーはいつでもタッチデバイスに接続できるため、実行時にデバイスのタッチサポートを検出することには問題があります。タッチデバイスの接続を検出した後でフォームのサイズを変更し、デバイスの接続が安定していない場合、フォーム自体のサイズが変更され続ける可能性があります。すべての入力に対して1つの安定したインターフェイスを使用することをお勧めします(たとえば、小さなメニューバーの代わりにリボンを使用します)。タッチデバイスを本当に検出したい場合は、SM_DIGITIZERを使用してGetSystemMetricsを呼び出すことができます。

ジェスチャはWindowsフォームではサポートされていません(2005年に機能が凍結されました)。ただし、デフォルトのタッチハンドラーはタッチをマウスクリックに変換するため、フォームコントロールは引き続きタッチ入力を使用できます。独自のタッチハンドラーが必要な場合は、タッチ入力がWindowsメッセージの形式で送信されるため、フォームまたはコントロールのWndProc関数をオーバーライドしてジェスチャメッセージを処理できます。サンプルコードについては、Windows7SDKのWindowsTouchサンプルを確認してください。

タッチ機能のテストコードを作成するには、InjectTouchInputを呼び出してタッチ入力をシミュレートできます。完全なサンプルは、入力:タッチインジェクションサンプルにあります。

于 2014-07-31T22:47:50.780 に答える
5

「非タッチ開発マシンでアプリケーションのタッチ機能を直接テストできない。MicrosoftのシミュレーターはMetroアプリのみをサポートしているようです」 -シミュレーターを実行し、シミュレーターのデスクトップに移動して実行することができます。タッチ入力をシミュレートしている間の任意のアプリ-WinFormsアプリを含みます。

WinFormsはWinAPIのネイティブUIAPIの単なるラッパーであるため、p / Invokeを使用して、Vista /Windows7の期間に追加されたと思われるタッチAPIを使用できます。主にWM_TOUCHおよびWM_GESTUREメッセージ。protected override void WndProc(ref Message m)タッチを処理するために必要な主なものであるp/Invokingとusingの例はたくさんあります。それ以外の場合-タッチ入力は、タッチとして処理されない場合、デフォルトで自動的にマウスイベントにプロモートされるため、多くのことが機能します。

于 2014-08-01T16:41:20.080 に答える
2

タッチは多かれ少なかれ「正しく機能する」はずですが、もちろん、ボタンは大きくする必要があります。タッチするよりも複雑なジェスチャについては、こちらも参照してください。

于 2012-11-10T02:02:57.153 に答える
1

WinFormsへのジェスチャーサポートの追加-ここで解決:

http://portal.fke.utm.my/libraryfke/files/1387_LIEWHONCHIN2011.pdf

'Imports System.Security.Permissions
'Imports System.Runtime.InteropServices


  Private first_point As New Point()
  Private second_point As New Point()
  Private iArguments As Integer = 0
  Private Const ULL_ARGUMENTS_BIT_MASK As Int64 = &HFFFFFFFFL
  Private Const WM_GESTURENOTIFY As Integer = &H11A
  Private Const WM_GESTURE As Integer = &H119
  Private Const GC_ALLGESTURES As Integer = &H1
  Private Const GID_BEGIN As Integer = 1
  Private Const GID_END As Integer = 2
  Private Const GID_ZOOM As Integer = 3
  Private Const GID_PAN As Integer = 4
  Private Const GID_ROTATE As Integer = 5
  Private Const GID_TWOFINGERTAP As Integer = 6
  Private Const GID_PRESSANDTAP As Integer = 7
  Private Const GF_BEGIN As Integer = &H1
  Private Const GF_INERTIA As Integer = &H2
  Private Const GF_END As Integer = &H4
  Private Structure GESTURECONFIG
    Public dwID As Integer
    Public dwWant As Integer
    Public dwBlock As Integer
  End Structure
  Private Structure POINTS
    Public x As Short
    Public y As Short
  End Structure
  Private Structure GESTUREINFO
    Public cbSize As Integer
    Public dwFlags As Integer
    Public dwID As Integer
    Public hwndTarget As IntPtr
    <MarshalAs(UnmanagedType.Struct)>
    Friend ptsLocation As POINTS
    Public dwInstanceID As Integer
    Public dwSequenceID As Integer
    Public ullArguments As Int64
    Public cbExtraArgs As Integer
  End Structure
  <DllImport("user32")> _
  Private Shared Function SetGestureConfig(ByVal hWnd As IntPtr, ByVal dwReserved As Integer, ByVal cIDs As Integer, ByRef pGestureConfig As GESTURECONFIG, ByVal cbSize As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
  End Function
  <DllImport("user32")>
  Private Shared Function GetGestureInfo(ByVal hGestureInfo As IntPtr, ByRef pGestureInfo As GESTUREINFO) As <MarshalAs(UnmanagedType.Bool)> Boolean
  End Function
  Private _gestureConfigSize As Integer
  Private _gestureInfoSize As Integer
  <SecurityPermission(SecurityAction.Demand)>
  Private Sub SetupStructSizes()
    _gestureConfigSize = Marshal.SizeOf(New GESTURECONFIG())
    _gestureInfoSize = Marshal.SizeOf(New GESTUREINFO())
  End Sub
  <PermissionSet(SecurityAction.Demand, Name:="FullTrust")>
  Protected Overrides Sub WndProc(ByRef m As Message)
    Dim handled As Boolean
    Select Case m.Msg
      Case WM_GESTURENOTIFY
        Dim gc As New GESTURECONFIG()
        gc.dwID = 0
        gc.dwWant = GC_ALLGESTURES
        gc.dwBlock = 0
        Dim bResult As Boolean = SetGestureConfig(Handle, 0, 1, gc, _gestureConfigSize)
        If Not bResult Then
          Throw New Exception("Error in execution of SetGestureConfig")
        End If
        handled = True
      Case WM_GESTURE
        handled = DecodeGesture(m)
      Case Else
        handled = False
    End Select
    MyBase.WndProc(m)
    If handled Then
      Try
        m.Result = New IntPtr(1)
      Catch excep As Exception
        Debug.Print("Could not allocate result ptr")
        Debug.Print(excep.ToString())
      End Try
    End If
  End Sub
  Private Function DecodeGesture(ByRef m As Message) As Boolean
    Dim gi As GESTUREINFO
    Try
      gi = New GESTUREINFO()
    Catch excep As Exception
      Debug.Print("Could not allocate resources to decode gesture")
      Debug.Print(excep.ToString())
      Return False
    End Try
    gi.cbSize = _gestureInfoSize
    If Not GetGestureInfo(m.LParam, gi) Then
      Return False
    End If
    Select Case gi.dwID
      Case GID_BEGIN, GID_END
      Case GID_TWOFINGERTAP
        'Receipt.Show()
        'Invalidate()
      Case GID_ZOOM
        Select Case gi.dwFlags
          Case GF_BEGIN
            iArguments = CInt(Fix(gi.ullArguments And
            ULL_ARGUMENTS_BIT_MASK))
            first_point.X = gi.ptsLocation.x
            first_point.Y = gi.ptsLocation.y
            first_point = PointToClient(first_point)
          Case Else
            second_point.X = gi.ptsLocation.x
            second_point.Y = gi.ptsLocation.y
            second_point = PointToClient(second_point)
            RaiseEvent GestureHappened(Me, New GestureEventArgs With {.Operation = Gestures.Pan, .FirstPoint = first_point, .SecondPoint = second_point})
            'Invalidate()
            'MsgBox("zoom")
        End Select
      Case GID_PAN
        Select Case gi.dwFlags
          Case GF_BEGIN
            first_point.X = gi.ptsLocation.x
            first_point.Y = gi.ptsLocation.y
            first_point = PointToClient(first_point)
          Case Else
            second_point.X = gi.ptsLocation.x
            second_point.Y = gi.ptsLocation.y
            second_point = PointToClient(second_point)
            RaiseEvent GestureHappened(Me, New GestureEventArgs With {.Operation = Gestures.Pan, .FirstPoint = first_point, .SecondPoint = second_point})
            'Invalidate()
            'MsgBox("pan")
        End Select
      Case GID_PRESSANDTAP
        'If gi.dwFlags = GF_BEGIN Then
        '  Invalidate()
        'End If
      Case GID_ROTATE
        'Select Case gi.dwFlags
        '  Case GF_BEGIN
        '    iArguments = 0
        '  Case Else
        '    first_point.X = gi.ptsLocation.x
        '    first_point.Y = gi.ptsLocation.y
        '    first_point = PointToClient(first_point)
        '    Invalidate()
        'End Select
    End Select
    Return True
  End Function


  Public Enum Gestures
    Pan
    Zoom
  End Enum

  Public Class GestureEventArgs
    Inherits EventArgs
    Public Property Operation As Gestures
    Public Property FirstPoint As Point
    Public Property SecondPoint As Point
  End Class

  Public Event GestureHappened(sender As Object, e As GestureEventArgs)
于 2016-01-27T22:54:10.910 に答える