2016-03-23 7 views
32

Quando eseguo un'applicazione WinForms (o Delphi, vedere alla fine) su Windows 10 in un tablet mode, una tastiera touch non viene visualizzata automaticamente quando una casella di input è focalizzata .Apre automaticamente la tastiera touch del tablet sullo stato di input di WinForms

Credo che ciò dovrebbe avvenire automaticamente, senza alcun codice aggiuntivo/configurazione.


Per un test, ho la più semplice applicazione WinForms desktop di VS 2015, con un unico TextBox control.

enter image description here

E 'semplicemente il default Applicazione Windows Form C# progetto creato da Visual Studio. Nessun codice aggiunto, nessuna proprietà modificata. Proprio il TextBox è stato aggiunto, facendo cadere dal Toolbox (di nuovo immobili cambiato):

this.textBox1 = new System.Windows.Forms.TextBox(); 
this.textBox1.Location = new System.Drawing.Point(64, 27); 
this.textBox1.Name = "textBox1"; 
this.textBox1.Size = new System.Drawing.Size(100, 20); 
this.textBox1.TabIndex = 0; 

per verificare la mia ipotesi che il pop-up dovrebbe essere automatico:

  • Ho provato a eseguire la versione di Windows XP di notepad.exe su Windows 10. Viene automaticamente visualizzata la tastiera touch. Dubito che Windows XP abbia un supporto esplicito per le tastiere touch.

  • Ho anche provato alcune antiche applicazioni MFC (ad esempio FileZilla 2.2.15 dal 2005). Si apre anche la tastiera touch su tutte le sue caselle di input. Ancora una volta, sono abbastanza sicuro, l'MFC non ha alcun supporto esplicito per le tastiere touch.

  • Lo stesso per le applicazioni basate su wxWidgets (ad esempio FileZilla 3.x).


sembra che ci sia qualcosa di rotto in WinForms che impedisce il popup automatico. È interessante notare che i pop-up automatici opere:

  • per (modificabile) caselle combinate (ComboBox con DropDownStyle = DropDown)
  • per le caselle di testo in una modalità password (TextBox.PasswordChar)
  • per le caselle di testo RTF (RichTextBox)
  • quando la casella di input è attiva nel momento in cui la tastiera hardware viene "rimossa" (lo faccio sfogliando lo schermo sul notebook Lenovo Yoga), ma mai dopo.

Ho visto tutti i suggerimenti circa un popup esplicito eseguendo il TabTip.exe. Per esempio.:

La maggior parte delle "soluzioni" offrono un codice come questo:

var progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink"; 
var keyboardPath = Path.Combine(progFiles, "TabTip.exe"); 
this.keyboardProc = Process.Start(keyboardPath); 

B Non posso credere che questo potrebbe essere il modo "ufficiale". Se non altro, allora perché non esiste un modo pulito per nascondere la tastiera aperta eseguendo il TabTip.exe (le soluzioni includono hack come uccidere il processo o inviare chiave Esc).

E in realtà quanto sopra mod non sembra funzionare più in Windows Update 10 ° Anniversario:


interessante, vedo lo stesso comportamento con Delphi/C++ Builder/Applicazioni VCL. La tastiera non si apre per le caselle di modifica (TEdit). Viene visualizzato per le caselle combinate (TComboBox) e per le caselle di modifica in modalità password (PasswordChar). È interessante notare che non è per TRichEdit, che cosa è notevole differenza per .NET RichTextBox, che forse vale la pena indagare.

Questa domanda (senza risposta) descrive un comportamento identico:
Application written Delphi XE8 touch in edit boxes keyboard not appear in Windows 10.

+0

Hai provato con 2 caselle di testo e modificando la messa a fuoco? Ho avuto qualcosa di simile una volta quando c'era una casella di input che si è concentrata all'avvio. In qualche modo questo evento è mancato a "OS (?)". Risolto il problema impostando lo stato iniziale su un altro controllo. – Stefan

+0

@Stefan Sicuro. In realtà ho bisogno di questo per una grande applicazione. Ho appena ridotto il problema alla semplice applicazione di test solo a scopo di questa domanda. –

+0

Quale dispositivo stai utilizzando? Windows 10 ha alcune euristiche interne per decidere se la tastiera deve effettivamente mostrare o meno, in base a una serie di cose. La modalità Tablet non è sufficiente per "forzare" la tastiera a mostrare. Sul mio Surface Book, devo staccare fisicamente la tastiera affinché l'OSK si mostri automaticamente (o essere forzato usando trucchi e soluzioni alternative) – o0rebelious0o

risposta

0

Come suggerito da Ofek Shilon's answer, sembra che la tastiera tattile possa sfruttare lo UI automation.


Uno può utilizzare l'implementazione di automazione UI da UIAutomationClient.dll.

Per l'automazione UI da iniettare magicamente in un'applicazione, è necessario attivare l'inizializzatore di classe della classe interna dell'assieme UiaCoreApi.

On può realizzare che, per esempio chiamando apparente no-op:

AutomationElement.FromHandle(IntPtr)(-1) 

Un altro modo è quello di implementare l'automazione dell'interfaccia utente in modo esplicito. Per questo implementare le interfacce ITextProvider/IValueProvider per il rispettivo controllo di input.

Per collegare l'implementazione delle interfacce al controllo, gestire WM_GETOBJECT window message con lParam = RootObjectId.

Per un esempio di implementazione, si veda risposta


Anche se è interessante notare che, i controlli, per i quali tocco tastiera funziona out-of-the-box (come casella combinata o casella di modifica della password, vedere la risposta), non implementare il WM_GETOBJECT/RootObjectId. Ci deve essere un meccanismo diverso dietro di loro.

5

Per quanto ne so, l'avvio di osk.exe o tabtip.exe è praticamente il modo "standard" per farlo funzionare. Non ho trovato nessuna soluzione "ufficiale" finora.

Tuttavia, se dovessi farlo, non ucciderei il processo o l'invio di chiavi per provare a chiudere la tastiera. Invece, è possibile ottenere l'handle della finestra quando si avvia il processo e utilizzarlo per ridurre a icona la finestra e nasconderlo dalla barra delle applicazioni.

Qualcuno qui ha ottenuto la maniglia della finestra solo per chiuderla, ma ti dà l'idea: Show & hiding the Windows 8 on screen keyboard from WPF

Se avete bisogno di me, fatemelo sapere e vedrò se riesco a trovare il tempo per fare un esempio completo.

+1

Grazie per la risposta, quindi perché funziona con MFC/wxWidgets o combo box? –

8

Sono stato in questa strada alcune volte e sono sempre stato in grado di implementare l'opzione taptip.exe. E a sua volta chiudi la finestra uccidendo il processo. Ho anche scoperto che con alcuni hack del Registro di sistema è possibile ottenere la tastiera predefinita sul pannello della scrittura a mano, se lo si desidera. Ma poi funziona solo con Win8 e fallisce in Win10. Ecco quello che ho fatto nel caso in cui nessun altro trova questo utile:

RegistryKey registryKey = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\TabletTip\\1.7"); 

registryKey?.SetValue("KeyboardLayoutPreference", 0, RegistryValueKind.DWord); 
registryKey?.SetValue("LastUsedModalityWasHandwriting", 1, RegistryValueKind.DWord); 

Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe"); 

ho bisogno di dare credito a questo post per l'idea di registro: Windows 8 Desktop App: Open tabtip.exe to secondary keyboard (for numeric textbox)

+0

Grazie per la risposta, ma come ho già commentato all'altra risposta: quindi perché funziona per MFC/wxWidgets o per la casella combinata? –

+0

@MartinPrikryl - Non posso commentare perché non ho mai usato questi widget. Mi piacerebbe pensare che ci sia un modo più semplice per far apparire la tastiera integrata sullo schermo, ma come hai cercato, non sembra possibile. – jaredbaszler

6

La causa principale sembra essere che textBox WinForms' non è un AutomationElement, mentre il resto dei controlli citati (ComboBoxes ecc.) lo sono.

quotatura Markus von und zu di accepted answer here Heber:

abbiamo trovato nell'articolo "Automatic Touch Keyboard for TextBoxes in WPF Applications on Windows 8+", ma funziona anche molto buono (e anche più facile!) Per WinForms. Grazie, Dmitry Lyalin!

  1. Inserire un riferimento alla UIAutomationClient.dll al progetto

  2. Nella forma-load-gestore della finestra principale dell'applicazione, inserire il seguente codice:

    var asForm = System.Windows.Automation.AutomationElement.FromHandle(this.Handle); 
    
+2

Chiamare "AutomationElement.FromHandle (handle)" ha effettivamente l'effetto che stavo cercando. Ma è solo un effetto collaterale. In realtà è possibile passare qualsiasi cosa al metodo, incluso un handle non valido come '(IntPtr) (- 1)'. Tutto ciò che importa è che l'implementazione del metodo utilizza una classe interna 'UiaCoreApi'. L'inizializzatore di classe fa un po 'di magia, che rende la tastiera touch pop-up per le caselle di modifica. Ma fa anche miliardi di altre cose e carica molti assembly non correlati, tutti con effetti collaterali sconosciuti che non sono disposto a usare ciecamente. –

+0

Grazie comunque. Forse qualcuno può basarsi su queste informazioni. Ho passato molte ore a cercare di scoprire quale sia la vera causa, ma non ci sono riuscito. –

+0

In realtà potrebbe essere che la tastiera touch può effettivamente sfruttare l'automazione dell'interfaccia utente, se implementata dall'applicazione. Ed è quello che fa l'inizializzatore 'UiaCoreApi'. Forse qualcuno può confermarlo. –

1

Utilizzare un controllo RichTextBox anziché un controllo TextBox. RichTextBox supporta la tastiera touch e si aprirà automaticamente la tastiera quando viene acquisita la messa a fuoco. (simile ad altri controlli di input come la casella combinata)

Il RichTextBox supporta anche le stesse proprietà del TextBox, quindi dovrebbe essere un calo nella maggior parte dei casi.(Entrambi i controlli derivano da TextBoxBase)

Ho notato che se la tastiera tattile è stata chiusa dopo l'apertura, potrebbe essere necessario toccare due volte il controllo per farlo tornare indietro.

+0

Grazie. Questa è un'osservazione interessante, sebbene non sia una soluzione accettabile. Ho comunque aggiunto queste informazioni alla mia domanda. –

Problemi correlati