Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Lazarus (IDE) (https://www.delphipraxis.net/81-lazarus-ide/)
-   -   Win 8 bzw. 10 Touch-Tastatur aufrufen? (https://www.delphipraxis.net/186239-win-8-bzw-10-touch-tastatur-aufrufen.html)

AlexII 17. Aug 2015 09:40

Win 8 bzw. 10 Touch-Tastatur aufrufen?
 
Hallo,

ich möchte mit nem Button die Touch-Tastatur von Windows 8 bzw. 10 aufrufen. Kann mir vllt jemand sagen wie es geht?
Ist eigentlich die Bildschirmtastatur von Win 7 das selbe wie unter 8 und 10? Kann man mit einem Befehl die Tastatur unter 7, 8 und 10 aufrufen?

Danke!

borncrush 17. Aug 2015 10:32

AW: Win 8 bzw. 10 Touch-Tastatur aufrufen?
 
Guten Morgen,

ich suche auch eine Möglichkeit. Speziell für meine BluetoothMaus möchte ich, dass per Mausklick (Schnelltaste) die Tastatur (OSK/On Screen Keyboard) aufgeht. (hab ja schließlich keine Tastatur parat).

Probiere bitte mal den Programmaufruf aus und gib dann mal bitte Feedback:

Code:
%ProgramFiles%\Common Files\microsoft shared\ink\TabTip.exe

Diese Variante fand ich weniger elegant bzw. ist es auch eine andere Tastatur.
Code:
%windir%\system32\osk.exe

Danke und Gruß

AlexII 17. Aug 2015 10:54

AW: Win 8 bzw. 10 Touch-Tastatur aufrufen?
 
Danke Dir, es klappt!

Wieso findest Du
Zitat:

%windir%\system32\osk.exe
weniger elegant?

Der schöne Günther 17. Aug 2015 11:09

AW: Win 8 bzw. 10 Touch-Tastatur aufrufen?
 
Das alte OSK hat viele Dinge nicht, beispielsweise Handschrifterkennung.

Ich habe im Endeffekt nichts neues beizutragen, nur wie ich das bei mir gewrapped habe. Wie man die Bildschirmtastatur ohne viel Gewalt beendet fand ich auch nicht ganz trivial :|

Delphi-Quellcode:
unit Common.Classes.OSK platform;

interface

uses Winapi.Windows;

type
   /// <summary>
   ///     Wrapper für die <i>TabTip</i>-Bildschirmtastatur von Windows
   /// </summary>
   /// <remarks>
   ///     Die Singleton-Instanz ist die globale Variable <see cref="TabTip" />
   /// </remarks>
   TTabTip = record
      private var
         exePath:      String;

         procedure determineExePath();
         /// <returns>
         ///     Gibt <c>0</c> zurück wenn das Fenster nicht gefunden wurde
         /// </returns>
         function determineHWND(): HWND;

      public
         procedure launch(const parentHWND: HWND = 0);
         /// <summary>
         ///      Blendet das Fenster freundlich aus. Der <c>TabTip.exe</c>-Prozess
         ///    wird nicht geschlossen
         /// </summary>
         procedure close();
         /// <summary>
         ///     Schießt den <c>TabTip.exe</c>-Prozess mit Gewalt ab. Das nächste
         ///    <see cref="launch">Starten</see> hat zur Folge dass die
         ///    Einstellungen aus der Registry neu gelesen werden
         /// </summary>
         procedure termiante();

         function isVisible(): Boolean;
   end;

var
   TabTip: TTabTip;

implementation uses
   System.IOUtils, System.SysUtils, System.Win.Registry,
   Winapi.ShellApi, Winapi.Messages, Winapi.TlHelp32
;

function ExpandEnvironmentVariables(const variable: string): string;
var
   len: DWORD;
begin
   len := MAX_PATH;
   SetLength(Result, len);
   len := WinApi.Windows.ExpandEnvironmentStrings(PChar(variable), PChar(Result), len);
   Win32Check(len > 0);
   SetLength(Result, len - 1);
end;

{ TTabTip }

function determineProcessHandleForExeName(
   const exeName: String;
   out processHandle: THandle
): Boolean;
var
   snapShot:   THandle;
   process:   TProcessEntry32;
   pid:      DWORD;
begin
   Result := False;
   snapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   try
      process.dwSize := SizeOf(TProcessEntry32);
      if Process32First(snapShot, process) then
         while Process32Next(snapShot, process) do
            if String(process.szExeFile).ToLowerInvariant() = exeName then begin
               pid := process.th32ProcessID;
               processHandle := OpenProcess(PROCESS_TERMINATE, False, pid);
               Exit(True);
            end;
   finally
      CloseHandle(snapShot);
   end;
end;

procedure TTabTip.close();
var
   windowHandle:      HWND;
begin
    windowHandle := determineHWND();
    PostMessage(windowHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
end;

procedure TTabTip.determineExePath();
const
   path = 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\TabTip.exe';
   hardcodedPath = 'C:\Program Files\Common Files\microsoft shared\ink\TabTip.exe';
   errorMsg   =   'The executable for "TabTip" cannot be found';
var
   registry:      TRegistry;
   registryValue:   String;
begin
   {TODO -oJM -cGeneral : Eine 32-Bit-Anwendung muss auf einem 64-Bit OS
   trotzdem das 64-Bit OSK aufrufen. Deshalb sollten wir mittels dem
   KEY_WOW64_64KEY-Flag in die 64-Bit-Registry schauen und die
   dort vorhandene Umgebungsvariable nach 64-Bit-Art expandieren. Aber wie
   das gehen soll ist mir schleierhaft.
   Außerdem muss das noch auf einem 32-Bit OS getestet werden}

   registry := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);
   try
      registry.RootKey := HKEY_LOCAL_MACHINE;
      registry.OpenKeyReadOnly(path);
      registryValue := registry.ReadString(EmptyStr);

      exePath := ExpandEnvironmentVariables(registryValue);
   finally
      registry.Destroy();
   end;

   if not TFile.Exists(exePath) then exePath := hardcodedPath;
   if not TFile.Exists(exePath) then raise EFileNotFoundException.Create(errorMsg);
end;

function TTabTip.determineHWND(): HWND;
const
   windowName:      PChar = 'IPTip_Main_Window';
begin
   Result := FindWindow(windowName, nil);
end;

function TTabTip.isVisible(): Boolean;
begin
   Result := determineHWND() <> 0
end;

procedure TTabTip.launch(const parentHWND: HWND = 0);
begin
   if exePath.IsEmpty() then determineExePath();
    if ShellExecute(parentHWND, 'open', PChar(exePath), nil, nil, SW_SHOWNA) < 32 then RaiseLastOSError();
end;

procedure TTabTip.termiante();
var
   processHandle:   THandle;
begin
   if determineProcessHandleForExeName('tabtip.exe', processHandle) then
      Win32Check( TerminateProcess(processHandle, ERROR_SUCCESS) );
end;

end.

AlexII 17. Aug 2015 11:55

AW: Win 8 bzw. 10 Touch-Tastatur aufrufen?
 
Wow... so kompliziert, geht das auch so? Bei mir läufts, auf win64, auf win32 weiß ich nicht.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  SysUtils.ExecuteProcess('C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe', '', []);
end;

Der schöne Günther 17. Aug 2015 13:47

AW: Win 8 bzw. 10 Touch-Tastatur aufrufen?
 
Das einzige was bei mir ja noch drin ist ist das Schließen der Bildschirmtastatur und ... ja. Etwas übertrieben vielleicht.

Ich wollte mich nur nicht drauf verlassen dass es auf alle Zeit genau dort unter C:\Programme liegt. Zu irgendwas wird der "App Paths"-Schlüssel in der Registry ja gedacht sein ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:00 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz