Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Virtuelle Tastatur ohne Focus (https://www.delphipraxis.net/164513-virtuelle-tastatur-ohne-focus.html)

mcbain 16. Nov 2011 11:48

Virtuelle Tastatur ohne Focus
 
Hallo,

ich möchte auf Knopfdruck eine virtuelle Tastatur einblenden. Hierfür verwende ich die Tastatur-Komponente in Delphi2010.
Allerdings darf die Form auf der die Tastatur-Komponente liegt natürlich nie den Focus erhalten sobald ich eine Taste darauf mit der Maus anklicke. Ich verwende bisher folgenden Code:

Code:


procedure TForm3.CreateParams(var Params: TCreateParams);      //Kein Focus für die Tastatur-Form
begin
  inherited;
  Params.ExStyle := Params.ExStyle + WS_EX_NOACTIVATE;
end;



procedure TForm3.FormCreate(Sender: TObject);
var i: Integer;
begin
  SetWindowLong(Handle, GWL_STYLE, (GetWindowLong(Handle, GWL_STYLE) and not WS_Caption));
  ClientHeight := Height;
  Refresh;

  Top := Screen.Height - ClientHeight - 50;
  Left := (Screen.Width div 2) - (Width div 2);
  FormStyle := fsStayOnTop;

end;
Dieser Code funktioniert auch, aber nur, wenn ich es in einem externen Programm auslagere. Sprich der obige Code ist in der Tastatur.exe und ich rufe mit Createprocess aus einer anderen Anwendung die Tastatur.exe auf.
Ich möchte aber kein externes Programm aufrufen, sondern direkt aus meiner Anwendung eine Form mit der Tastatur-Komponente darauf anzeigen.
Leider funktioniert es dann nicht mehr. Die aufrufende Mainform verliert den Focus an die form mit der Tastatur-Komponente darauf, sobald ich auf die Tasten der Tastatur klicke. Und somit werden natürlich die Eingaben auf der Tastatur nicht in meine Edit-Felder auf der aufrufenden Mainform geschrieben.

Wäre nett, wenn mir jemand kurz weiterhelfen könnte.
Vielen Dank.
Gruß
mc

hathor 16. Nov 2011 13:05

AW: Virtuelle Tastatur ohne Focus
 
Ich habe gerade einen Artikel in CODEPROJECT vor mir - Titel:
Original Virtual PiliKeyboard with Prompt Feature. Samsung R-Series laptop keyboard
- da wird einfach nach dem Klicken der Window-Focus (CWinApi.SetForegroundWindow(hWndTarget);) geändert:

Code:
// setting active target window
            if (hWndTarget.ToInt32() != 0)
            {
                CWinApi.SetForegroundWindow(hWndTarget);

                // waiting up to the moment when target window will be on top
                System.Threading.Thread.Sleep(20);
            }

mcbain 17. Nov 2011 06:37

AW: Virtuelle Tastatur ohne Focus
 
Wenn ich das bspw. so mache:

Code:
procedure TForm3.FormKeyPress(Sender: TObject; var Key: Char);  //Form3 ist die Form auf dem das Keyboard liegt
begin
   Form2.edit1.SetFocus;
end;
Dann blinkt Form2 und Form3 bloß kurz auf, aber er schreibt nicht in edit1.
Dafür muss es doch eine elegante Lösung geben oder? Das aufblinken ist nämlich auch nicht so schön. Es funktioniert ja auch, wenn es in einer eigenen Anwendung aufgerufen wird...

Hat noch jemand einen Tip evtl.?

Bummi 17. Nov 2011 07:10

AW: Virtuelle Tastatur ohne Focus
 
Ich habe gerade keinen Zugriff auf meine Sourcen, als QuickHack könnte ich mir folgendes vorstellen.
Annahme das Fenster mit der virtuellen Tastatur bildet die Tasten über ein/mehrer Images oder Speedbutton o.ä. ab.
Delphi-Quellcode:
procedure TForm1.Edit1Enter(Sender: TObject);
begin
   With Form2 do
    begin
      width := 300;
      height := 200;
      Left := TWincontrol(Sender).Left + TWincontrol(Sender).Width;
      Top := TWincontrol(Sender).Top;
      Parent := Self;
      Show;
    end;
end;
der Tastaturcode nur testweise
Delphi-Quellcode:
procedure SendKeys(sText: String);

var
 i            : Integer;
 shift        : Boolean;
 vk, scancode  : Word;
 ch           : Char;
 c, s         : Byte;
const
 vk_keys      : Array[0..9] of Byte=(VK_HOME, VK_END, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_PRIOR, VK_NEXT, VK_INSERT, VK_DELETE);
 vk_shft      : Array[0..2] of Byte=(VK_SHIFT, VK_CONTROL, VK_MENU);
 flags        : Array[FALSE..TRUE] of Integer = (KEYEVENTF_KEYUP, 0);
 C_ALTGRS = ['\','@','~','²','³','€','{','}','[',']'];

begin
 shift:=FALSE;
 for i:=1 to Length(sText) do begin
   ch:=sText[i];
     if (ch>=#250) then begin
     s:=Ord(ch)-250;
     shift:=NOT Odd(s);
     c:=vk_shft[s shr 1];
     scancode:=MapVirtualKey(c, 0);
     Keybd_Event(c, scancode, flags[shift], 0);
   end else begin
     vk:=0;
     if (ch>=#240) then
       c:=vk_keys[Ord(ch)-240]
     else if (ch>=#228) then
       c:=Ord(ch)-116
     else if (ch<#32) then
       c:=Ord(ch)
     else begin
       vk:=VkKeyScan(ch);
       c:=LoByte(vk);
     end;

     scancode:=MapVirtualKey(c, 0);

     if (sText[i] in C_AltGRS) then Keybd_Event(VK_RMENU, MapVirtualKey(VK_RMENU,0), 0, 0)
     else if (NOT shift AND (Hi(vk)>0)) then Keybd_Event(VK_SHIFT, $2A, 0, 0 );
     Keybd_Event( c, scancode, 0, 0 );
     Keybd_Event( c, scancode, KEYEVENTF_KEYUP, 0 );
     if (sText[i] in C_AltGRS) then Keybd_Event(VK_RMENU,MapVirtualKey(VK_RMENU,0), KEYEVENTF_KEYUP, 0)
     else if (NOT shift AND (Hi(vk)>0)) then Keybd_Event(VK_SHIFT, $2A, KEYEVENTF_KEYUP, 0);

   end;
   Application.ProcessMessages;
 end;
end;


procedure TForm2.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
   SendKeys('Test');
end;
Oder alternativ eine Prozedur in die virtuelle Tastatur einbauen, der das Wincontrol übergeben wird.
Dort alles Merken (Parent/Fontsize/Left/Top/aling/Ancors etc...)
Dann dem Control ein Panel auf der Tastatur als Parent zuweisen, ausrichten etc. und anzeigen , im Close alles wieder herstellen.

divBy0 17. Nov 2011 08:02

AW: Virtuelle Tastatur ohne Focus
 
Probiers mal so:

Delphi-Quellcode:
SetWindowLong(handle, GWL_EXSTYLE,GetWindowLong(handle, GWL_EXSTYLE) or WS_EX_NOACTIVATE);
  SetWindowPos(self.Handle, HWND_NOTOPMOST + WORD(true), 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);

mcbain 17. Nov 2011 09:38

AW: Virtuelle Tastatur ohne Focus
 
@Bummi
Das ist sehr ausführlich, vielen Dank. Aber ich denke das ganze muss wesentlich einfacher zu realisieren sein, da es ja in einer externen Anwendung genau so funktioniert wie ich möchte. Ich will halt nur nicht immer ne externe Anwendung aufrufen müssen.

@divBy0
Ich hab es so eingebaut:

Code:
procedure TForm2.btn1Click(Sender: TObject);
begin
  form3 := TForm3.Create(Application);
  SetWindowLong(form3.handle, GWL_EXSTYLE,GetWindowLong(form3.handle, GWL_EXSTYLE) or WS_EX_NOACTIVATE);
  SetWindowPos(form3.Handle, HWND_NOTOPMOST + WORD(true), 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
  form3.Visible := true;

end;
Aber am Verhalten hat sich nix geändert...

Uwe Raabe 17. Nov 2011 10:11

AW: Virtuelle Tastatur ohne Focus
 
Zitat:

Zitat von mcbain (Beitrag 1136616)
Aber ich denke das ganze muss wesentlich einfacher zu realisieren sein, da es ja in einer externen Anwendung genau so funktioniert wie ich möchte. Ich will halt nur nicht immer ne externe Anwendung aufrufen müssen.

Es ist aber halt doch ein Unterschied, ob eine externe Anwendung aktiviert wird (oder eben auch nicht), oder ob ein anderes Form der aktiven Anwendung den Fokus erhält. Manchmal ist das, was einfach erscheint, doch eben nicht so einfach zu realisieren - wenn es denn überhaupt geht. Es ist sehr wohl möglich, daß die mitgelieferte Bildschirmtastatur in diesem Fall für deine Zwecke nicht geeignet ist.

ConnorMcLeod 17. Nov 2011 10:30

AW: Virtuelle Tastatur ohne Focus
 
Immer, wenn eine Eingabemaske den Fokus bekommt, kann man sich im VirtuellenKeyboard in einem Property merken, welche es ist.
Immer, wenn ein Eingabefeld den Fokus bekommt, kann man sich im VirtuellenKeyboard einem Property merken, welches es ist.
Beim Klick eines Buttons im VK kann man nun dem richtigen Edit eine Message senden, welche Taste gedrückt wurde, und danach die richtige Maske retour-aktivieren.
...oder?

Uwe Raabe 17. Nov 2011 11:02

AW: Virtuelle Tastatur ohne Focus
 
Zitat:

Zitat von ConnorMcLeod (Beitrag 1136626)
Immer, wenn eine Eingabemaske den Fokus bekommt, kann man sich im VirtuellenKeyboard in einem Property merken, welche es ist.
Immer, wenn ein Eingabefeld den Fokus bekommt, kann man sich im VirtuellenKeyboard einem Property merken, welches es ist.
Beim Klick eines Buttons im VK kann man nun dem richtigen Edit eine Message senden, welche Taste gedrückt wurde, und danach die richtige Maske retour-aktivieren.
...oder?

Da die Keyboard-Komponente keine Events bereitstellt, in die man sich einklinken kann, bleibt eigentlich nur eine Ableitung als Lösung. Dummerweise sind die relevanten Methoden aber nicht virtuell. Damit kann man auch gleich eine eigene Komponente schreiben. Einfach ist das alles aber wirklich nicht.

Ein möglicher Ansatz wäre allerdings auch, die FormKey-Events des Keyboard-Forms zu verwenden. Das Weiterleiten der Messages and das passende Control ist allerdings immer noch unschön - vor allem, da das Keyboard ja eigentlich dieses (zumindest im eigenen Formular) schon korrekt ausführen würde.

ConnorMcLeod 17. Nov 2011 11:17

AW: Virtuelle Tastatur ohne Focus
 
Yo, ich kenne diese Keyboard-Komponente leider nicht. Meine Lösung war anno damals ein eigenes Form mit einem Haufen Buttons und diesen beiden Properties. In einer globalen Funktion reagiere ich auf die Fokusgeschichten. Funktioniert bis heute, obwohl es bestimmt eleganter ginge.

Der Vorteil für mich (und ich meine damit diesen Anwendungsfall) liegt darin, alles total unter Kontrolle zu haben inkl Sondertasten und Farben und Dimensionen und Buttontextur und Multilanguage-Sonderzeichen etc. d.h. wenn einmal etwas nicht funktioniert, dann kann ich sicher davon ausgehen, dass der Fehler bei mir liegt und nicht an irgendwelchen kryptischen Länder/Windows/Tastatur/Hardware-Einstellungen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:43 Uhr.
Seite 1 von 2  1 2      

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