Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Handschriften-Erkennung (https://www.delphipraxis.net/184445-handschriften-erkennung.html)

MatthiasD 27. Mär 2015 11:00

Handschriften-Erkennung
 
Hallo,

ich möchte in einer Tablet-Anwendung (Win 8.1) Anmerkungen auf Plänen anbringen lassen. Dies wäre am Einfachsten per Stifteingabe zu realisieren. Eine Delphi-Komponente zur Handschriftenerkennung habe ich nicht gefunden. Hat jemand eine Idee, wie man stattdessen das Windows Writing Pad nutzen könnte? Es wäre gut, das Pad programmgesteuert aufrufen, positionieren und in der Breite anpassen zu können.

Danke für jeden Tip!
M.

Mavarik 27. Mär 2015 11:13

AW: Handschriften-Erkennung
 
Vielleicht hilft das?

Der schöne Günther 27. Mär 2015 11:26

AW: Handschriften-Erkennung
 
Ich verstehe das Problem nicht-

Windows 8.1 hat doch in der Bildschirmtastatur eine wirklich richtig gut funktionierende Handschrifterkennung eingebaut. Ist dein Problem dass du nicht weißt wie man die Bildschirmtastatur aus einer Desktop-Anwendung heraus auf und zumacht?

MatthiasD 27. Mär 2015 11:49

AW: Handschriften-Erkennung
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1295045)
Ich verstehe das Problem nicht. Windows 8.1 hat doch in der Bildschirmtastatur eine wirklich richtig gut funktionierende Handschrifterkennung eingebaut. Ist dein Problem dass du nicht weißt wie man die Bildschirmtastatur aus einer Desktop-Anwendung heraus auf und zumacht?

Genau. Ideal wäre ein Bereich zum Schreiben, der von der Anwendung an einer bestimmten Position in festgelegter Größe geöffnet wird - also lediglich der "Schreibblock" ohne alle nicht unmittelbar benötigten Schaltflächen.

Danke!
M.

hathor 27. Mär 2015 13:28

AW: Handschriften-Erkennung
 
http://windows.microsoft.com/de-de/w...#1TC=windows-7
http://windows.microsoft.com/en-us/w...pc-input-panel
http://windows.microsoft.com/en-us/w...other-language

Keyboard:
%windir%\system32\osk.exe

Der schöne Günther 27. Mär 2015 13:42

AW: Handschriften-Erkennung
 
Ich hatte damit einmal angefangen aber es nie ganz fertig gestellt. Schau mal ob du damit etwas anfangen kannst:

Delphi-Quellcode:
unit TabTip_ 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
         windowHandle:   HWND;
         exePath:      String;

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

      private
         procedure setHandWriting(const isEnabled: Boolean);
//      public const
//         DOCK_BOTTOM   =   10021;
//         DOCK_TOP   =   10023;
//         FLOATING   =   10020;

      public var
         handWriting: Boolean;

      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();

         //procedure setPosition(const position: Word);
   end;

var
   TabTip: TTabTip;


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

{ 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();
const
   messageName:   PChar = 'IPTipDockButtonPressed';
var
   dockButtonPressed:   DWORD;
   windowHandle:      HWND;
begin
    dockButtonPressed := RegisterWindowMessage(messageName);
    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;
   fileName:      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);
   try
      registry.RootKey := HKEY_LOCAL_MACHINE;
      registry.OpenKeyReadOnly(path);
      registryValue := registry.ReadString(EmptyStr);
      exePath := TEnvironment.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;


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

procedure TTabTip.SetHandWriting(const isEnabled: Boolean);
const
   path = 'SOFTWARE\Microsoft\TabletTip\1.7';
   keyName = 'LastUsedModalityWasHandwriting';
var
   registry: TRegistry;
begin
   registry := TRegistry.Create(KEY_READ or KEY_WRITE or KEY_WOW64_64KEY);
   try
      registry.RootKey := HKEY_CURRENT_USER;
      if not registry.OpenKey(path, False) then RaiseLastOSError();

      registry.WriteInteger( keyName, isEnabled.ToInteger() );
   finally
      registry.Destroy();
    end;
end;

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

//procedure TTabTip.setPosition(const position: Word);
//const
//   errorMsg = 'position (%d) was not within the allowed range';
//var
//   windowHandle:   HWND;
//begin
//   if (position <> DOCK_BOTTOM) and (position <> DOCK_TOP) and (position <> FLOATING) then raise
//      EArgumentOutOfRangeException.Create(errorMsg);
//
//   windowHandle := determineHWND();
//   PostMessage(windowHandle, WM_COMMAND, MakeWParam(position, 0), LPARAM(0));
//end;

end.
Da das "Handwriting an/aus" über die Registry geht und mir nichts besseres eingefallen ist muss man das Tabtip vor dem Ändern mit Gewalt abschießen:

Delphi-Quellcode:
   TabTip.launch();
   ReadLn;
   TabTip.termiante();
   TabTip.handWriting := True;
   TabTip.launch();

BUG 27. Mär 2015 14:07

AW: Handschriften-Erkennung
 
termiante mehrfach ... the copy&paste is strong with this one :wink:

//EDIT: Du hast vermutlich terminate nicht jedes mal neu falschgeschrieben, sondern den Bezeichner einfach kopiert. Außerdem: Star-Wars-Referenz.

Der schöne Günther 27. Mär 2015 14:10

AW: Handschriften-Erkennung
 
wat

MatthiasD 27. Mär 2015 14:26

AW: Handschriften-Erkennung
 
[QUOTE=Der schöne Günther;1295063]Ich hatte damit einmal angefangen aber es nie ganz fertig gestellt. Schau mal ob du damit etwas anfangen kannst./QUOTE]

Danke, ich probiere es.

Der schöne Günther 27. Mär 2015 17:20

AW: Handschriften-Erkennung
 
Aaaaah ok, den Schreibfehler habe ich nicht gesehen :-D

Das mit Star Wars verstehe ich auch noch nicht, aber das kommt vielleicht noch...


PS: Naja, nicht Copy&Paste- Einmal im interface-Teil halt so getippt, dann mit STRG+Shift+C automatisch das Implementationsgerüst bilden lassen und wenn man es aufruft tippe ich sowieso nur immer den ersten (vielleicht zweiten) Buchstaben und vervollständoge mit Strg+Leer. Tippen ist überbewertet ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:14 Uhr.
Seite 1 von 2  1 2   

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