AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi DLL-Fenster erhält nicht alle Keyboard-Events?!
Thema durchsuchen
Ansicht
Themen-Optionen

DLL-Fenster erhält nicht alle Keyboard-Events?!

Ein Thema von chrschn · begonnen am 16. Nov 2004 · letzter Beitrag vom 18. Nov 2004
 
chrschn
(Gast)

n/a Beiträge
 
#2

DLL-Fenster erhält nicht alle Keyboard-Events?! GEHT JETZT!

  Alt 18. Nov 2004, 17:20
Ich habe es jetzt nach einigen Experimenten hinbekommen. Die Lösung baut auf dem schon geposteten Versuch auf, die Keyboard-Messages über ein TApplicationEvents-Objekt abzufangen und an das Control mit dem Focus weiterzuleiten, also sowohl an die eigenen als auch an die DLL.

Allerdings müssen dazu nicht nur die WM_KEYDOWN und WM_KEYUP-Messages weitergeleitet werden. Darüber hinaus müssen die WM_KEYDOWN-Messages noch mit TranslateMessage in eine WM_CHAR oder WM_DEADCHAR-Message umgewandelt werden, welche dann auch noch weitergeleitet werden müssen. Außerdem dürfen die Tabulator oder Enter-Taste nicht weitergeleitet werden, sonst verlieren sie ihre spezielle Funktion. Keine Idee, woran das liegen könnte.

Was jetzt funktioniert:
  • Sämtliche Zeichen können erzeugt werden, auch Akzente (Dead-Chars), [ALT GR]-Zeichen usw.
  • Pfeiltasten, Home, End, PgUp, PgDn usw. können erzeugt werden
  • Die Hostanwendung funktioniert nach meiner Beobachtung genauso wie vorher ([Tab]: Focuswechsel, Return: Default-Button, [ALT]+MenuAccel: Tastenkürzel, ...)
Was allerdings (noch) nicht funktioniert:
  • [TAB] innerhalb des DLL-Fensters wechselt nicht den Focus innerhalb desselben, sondern springt zum nächsten Control der Hostanwendung
  • Der Focuswechsel durch [TAB] in der Hostanwendung überspringt das DLL-Fenster
  • MenuAccels im DLL-Fenster funktionieren nicht, also z. B. Button-Captions wie '&OK' können nicht mit [ALT]+[O] aktiviert werden
Mit diesen Einschränkunten kann ich allerdings erstmal leben .

Um die Tabulator-Geschichte hinzubiegen, kam mir schon folgende Idee: Man könnte das Panel in den Focuswechsel mit einbeziehen (TPanel.TabStop := True) und sich das Handle des aktuell angezeigten DLL-Fensters von selbiger erfragen. Dann kann man im TPanel.OnEnter-Event-Handler das Fenster per Windows-API aktivieren, mit SetFocus(HandleOfCurrentDLL). Aber für weitere Experimente habe ich immo leider keine Zeit. Falls es jemand ausprobiert, bitte (Miss-)Erfolgsbereichte hier posten 8)

Hier nun der Code für das TApplicationEvents.OnMessage in der Hostanwendung:
Delphi-Quellcode:
procedure TConfigForm.ApplicationKeyboardEventsMessage(var Msg: tagMSG;
  var Handled: Boolean);
const
  DONT_FORWARD_KEYS: set of Byte = [VK_RETURN, VK_TAB];

var
  Handle: THandle;
  VKey: Byte;
begin
  // This event handler forwards the keyboard events to the DLL window.
  // Without it some keys would not be sent to the DLL window. This seems
  // to be an issue of either Delphi or the Windows message handling.
  case Msg.message of
    WM_KEYDOWN:
      begin
        // Translate the virutal key into a character key (0..255)
        VKey := Lo(MapVirtualKey(Msg.wParam, 2));
        // If no translation has to be made, MapVirtualKey returns 0.
        if (VKey = 0) then VKey := Lo(Msg.wParam);
        // Don't handle the DONT_FORWARD_KEYS keys as they have special
        // functions and must be handled by the application itself.
        if not (VKey in DONT_FORWARD_KEYS) then
          begin
            // Get current focused control
            Handle := GetFocus;
            // Forward the message to it
            SendMessage(Handle, Msg.message, Msg.wParam, Msg.lParam);
            // Process message by translating the WM_KEYUP message into a
            // WM_CHAR message.
            Handled := TranslateMessage(Msg);
          end;
      end;

    WM_KEYUP:
      begin
        // Translate the virutal key into a character key (0..255)
        VKey := Lo(MapVirtualKey(Msg.wParam, 2));
        // If no translation has to be made, MapVirtualKey returns 0.
        if (VKey = 0) then VKey := Lo(Msg.wParam);
        // Don't handle the DONT_FORWARD_KEYS keys as they have special
        // functions and must be handled by the application itself.
        if not (VKey in DONT_FORWARD_KEYS) then
          begin
            // Get current focused control
            Handle := GetFocus;
            // Forward the message to it
            SendMessage(Handle, Msg.message, Msg.wParam, Msg.lParam);
            Handled := True;
          end;
      end;

    WM_DEADCHAR,
    WM_CHAR:
      begin
        VKey := Msg.wParam;
        // Don't handle the DONT_FORWARD_KEYS keys as they have special
        // functions and must be handled by the application itself.
        if not (VKey in DONT_FORWARD_KEYS) then
          begin
            // Get current focused control
            Handle := GetFocus;
            // Forward the message to it
            SendMessage(Handle, Msg.message, Msg.wParam, Msg.lParam);
            Handled := True;
          end;
      end;
  end;
end;
Gruß,
Christian
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:05 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