2012-11-09 15 views
9

Ho un'applicazione desktop Windows Form esistente che utilizza .NET Framework 4 e desidero aggiungere il supporto per Windows 8 al tocco.Aggiunta del supporto tocco di Windows 8 all'applicazione WinForms esistente

Attualmente il programma funziona correttamente in Windows 8 e posso potenzialmente ridimensionare alcuni elementi per renderlo più user-friendly sui dispositivi touch. Tuttavia, l'aggiunta di gesti come pizzicare-zoom su datagrids e il supporto di scorrimento per altri elementi farebbe molto per rendere l'applicazione più moderna in un ambiente solo tocco.

Sto investendo in Visual Studio 2012, che mi consentirà di utilizzare .NET 4.5 e le nuove funzionalità di Windows 8, ma qualcuno è a conoscenza di risorse che potrebbero aiutarmi nell'aggiornare la mia applicazione? Sono particolarmente preoccupato per quanto segue:

  • Incapacità di testare direttamente le funzionalità di tocco dell'applicazione sul mio computer di sviluppo non touch. Il simulatore di Microsoft sembra supportare solo le app Metro. Ho sentito che le app per tablet come Splashtop possono aiutare (ho un tablet Android), ma non ho visto nulla di concreto per questo particolare scenario
  • Se i gesti sono persino supportati su applicazioni WinForms. Dovrò aggiornare l'intera interfaccia utente a WPF per farlo funzionare? (Se ho seguito questa strada, credo che potrei scegliere come target anche Windows 7, poiché il multi-touch è supportato su WPF 4)
  • Rilevare il supporto touch del dispositivo in fase di runtime e ridimensionare/modificare l'interfaccia utente in modo appropriato, simile alla modalità Touch impostazione su app Microsoft Windows RT Office. Non voglio sborsare il progetto solo per aggiungere le nuove funzioni
  • test automatici delle interazioni tattili

Questo non è un elenco esaustivo con qualsiasi mezzo, ma mi piacerebbe davvero apprezzare alcun consiglio da quelli chi potrebbe aver contattato un aggiornamento simile in passato.

+0

Se ci si rivolge WinRT si sta andando ad avere a che fare una completa riscrittura dal WinRT non ha WinForms equivalente. – mydogisbox

+1

@mydogisbox - Non sto prendendo di mira WinRT, mi interessa solo l'aggiornamento di un'applicazione desktop WinForms esistente per supportare il tocco. Avrei dovuto renderlo più chiaro nella mia domanda. Grazie per l'input. –

+0

[Per chi ha bisogno di aggiornare una vecchia app WinForms per sfruttare appieno il touchscreen di Windows 10], vedere il mio commento sotto [risposta di Sheng Jiang] (https://stackoverflow.com/a/25070182/199364) per il collegamento corrente a Windows 7 SDK per ottenere il campione di gesti ('pizzica-zoom' e' ruota'). Verificato che la soluzione C# funziona con Microsoft Surface Pro (2017) che esegue Windows 10 Pro. – ToolmakerSteve

risposta

6

Rilevamento supporto touch del dispositivo in fase di esecuzione è problematico in quanto l'utente può collegare un qualsiasi momento dispositivo touch. Se si ridimensiona il modulo dopo aver rilevato la connessione del dispositivo touch e la connessione del dispositivo non è stabile, si può finire con un modulo che continua a ridimensionarsi. Meglio avere un'interfaccia stabile per tutti gli ingressi (ad esempio usando un nastro al posto di una piccola barra dei menu). Se si desidera veramente rilevare dispositivi touch, è possibile chiamare GetSystemMetrics con SM_DIGITIZER.

I gesti non sono supportati in Windows Form (funzione congelata nel 2005). Tuttavia, i controlli dei moduli possono ancora utilizzare l'input tattile poiché il gestore di tocco predefinito traduce i tocchi nei clic del mouse. Se si desidera avere il proprio gestore di tocco, poiché gli input tattili vengono inviati sotto forma di messaggi di Windows, è possibile ignorare il modulo o la funzione di controllo WndProc per gestire i messaggi di gesture. Per il controllo del codice di esempio Windows Touch Samples nell'SDK di Windows 7.

Per scrivere il codice di prova per la funzionalità touch, è possibile chiamare InjectTouchInput per simulare l'input tattile. Un campione completo può essere trovato a Input: Touch injection sample.

+0

Come aggiungere touch a winforms __sono stati risolti__ comprare LIEW HON CHIN nella sua tesi: http://portal.fke.utm.my/libraryfke/files/1387_LIEWHONCHIN2011.pdf, vedere la mia risposta qui sotto. – FastAl

+0

@FastAl - Grazie, ma l'autore della tesi utilizza le stesse API di Windows di cui sopra. Penso che la pagina MSDN collegata sopra fornisca migliori esempi ed esempi. –

+1

@Daver, grazie, ma qualcuno può fornire un collegamento agli esempi? Nota 5+ commenti degli utenti nella parte inferiore delle pagine che colleghi per lamentarti della mancanza di esempi completi! Ho davvero voluto che quella pagina fornisse un file .sln completo scaricabile per l'esempio C# - _soooo_ molto manca e so che probabilmente Microsoft ne ha avuto uno- ci sono persino degli screenshot! Spero solo di averlo perso. (nota-download? id = 6450 menzionato da un commento utente è morto). In mancanza di ciò, il codice completo.Net di Liew era bello (gli utenti C# possono convertirsi su telerik.com). – FastAl

2

Il tocco dovrebbe più o meno "funzionare", ma ovviamente i pulsanti dovranno essere più grandi ecc. Vedere anche here per gesti più complessi del semplice tocco.

6

È possibile utilizzare TouchToolkit for WinForms dal componente uno. Comunque penso che dovrai riscrivere la tua applicazione per usare questi componenti.

enter image description here

+0

Premiato come questa è stata la migliore risposta. Grazie! – SSS

+0

Il collegamento TouchToolkit ora restituisce "404 non trovato". – ToolmakerSteve

5

Per quanto riguarda il commento "Incapacità di provare direttamente le funzionalità touch dell'applicazione sulla mia macchina di sviluppo non-touch simulatore di Microsoft sembra solo per supportare le applicazioni Metro" - Sono in grado di eseguire il simulatore, andare al desktop nel simulatore ed esegui qualsiasi app mentre simuli il touch input, incluse le app di WinForms.

Poiché WinForms è solo un wrapper sulle API native dell'interfaccia utente di WinAPI, è possibile utilizzare p/Invoke per utilizzare le API tattili che penso siano state aggiunte attorno al tempo di Vista/Windows 7. Principalmente i messaggi WM_TOUCH e WM_GESTURE. Ci sono molti esempi per p/Invocare e usare protected override void WndProc(ref Message m) che sono le cose principali che dovresti gestire. Oltre a questo - gli input touch vengono automaticamente promossi automaticamente agli eventi del mouse quando non vengono gestiti come touch, quindi molte cose funzionano.

1

Aggiungere il supporto gesto per WinForms - risolto qui:

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) 
+0

Sfortunatamente, il link pdf è morto. Come usi il codice sopra? La mia prima ipotesi è mettere tutte quelle righe all'interno di una definizione di classe. Allora cosa? [Sto cercando di aggiungere pizzico-zoom a una vecchia app WinForms.] – ToolmakerSteve

+0

Non importa. Vedi il mio commento sotto [risposta di Sheng Jiang] (https: // StackOverflow.it/a/25070182/199364) - Windows 7 SDK Touch Samples include una soluzione C# completa, che implementa i gesti di zoom e rotazione. Quel campione funziona così com'è su Microsoft Surface Pro (2017) con Windows 10, quindi ho quello che mi serve per aggiornare una vecchia app WinForms :) – ToolmakerSteve

Problemi correlati