![]() |
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:
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.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; 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 |
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); } |
AW: Virtuelle Tastatur ohne Focus
Wenn ich das bspw. so mache:
Code:
Dann blinkt Form2 und Form3 bloß kurz auf, aber er schreibt nicht in edit1.
procedure TForm3.FormKeyPress(Sender: TObject; var Key: Char); //Form3 ist die Form auf dem das Keyboard liegt
begin Form2.edit1.SetFocus; end; 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.? |
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:
der Tastaturcode nur testweise
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;
Delphi-Quellcode:
Oder alternativ eine Prozedur in die virtuelle Tastatur einbauen, der das Wincontrol übergeben wird.
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; 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. |
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); |
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:
Aber am Verhalten hat sich nix geändert...
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; |
AW: Virtuelle Tastatur ohne Focus
Zitat:
|
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? |
AW: Virtuelle Tastatur ohne Focus
Zitat:
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. |
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. |
AW: Virtuelle Tastatur ohne Focus
Vielen Dank für eure zahlreichen Antworten, hätte nicht gedacht, dass es sich so schwierig gestaltet.
Dann muss ich evtl. doch die einzelnen Keys per OnKeyPress des Forms an die jeweilige Komponente schicken.... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz