AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Multimedia-Tasten hooken

Ein Thema von Gausi · begonnen am 16. Feb 2006 · letzter Beitrag vom 30. Jun 2007
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
847 Beiträge
 
Delphi 11 Alexandria
 
#1

Multimedia-Tasten hooken

  Alt 16. Feb 2006, 15:11
Zuallererst: 'Tschuldigung für so ein langes Erst-Posting...

Ich möchte in meinem Programm die Benutzung der Multimediatasten einer Tastatur ermöglichen. Das mache ich so:
Delphi-Quellcode:
TForm1 = class(TForm)
protected
  procedure MediaKey (Var aMSG: tMessage); message WM_APPCOMMAND;
end;
//...
procedure TForm1.MediaKey (Var aMSG: tMessage);
begin
  case aMSG.LParam of
    APPCOMMAND_MEDIA_NEXTTRACK:
    begin
      Memo1.lines.add('Next');
      aMsg.Result := 1;
    end;
    APPCOMMAND_MEDIA_PREVIOUSTRACK:
    begin
      Memo1.lines.add('Prev');
      aMsg.Result := 1;
    end;
    //usw.
  end;
end;
Das funktioniert so weit ganz gut. Da die Steuerung auch dann funktionieren soll, wenn mein Fenster nicht den Fokus hat, hab mich mal mit Hooks beschäftigt. (Das Problem habe ich übrigens im DF auch schon erläutert: *klick*)
Mein Hook-Code sieht so aus:
Delphi-Quellcode:
function InstallHook(Hwnd: Cardinal): Boolean; stdcall;
begin
  Result := False;
  if HookHandle = 0 then begin
    //Erstmal Hook installieren
    HookHandle := SetWindowsHookEx(WH_SHELL, @KeyboardHookProc, HInstance, 0);
    //Uebergebenes Fensterhandle sichern
    MyWindowHandle := Hwnd;
    oDemoObj := TWDB_IPCDemoObj.Create('NempNochEinMP3Player');
    oDemoObj.MainWindow := Hwnd;
    oDemoObj.HookHandle := HookHandle;
    Result := True;
    showmessage('Installiert ' + inttostr(HookHandle) + ' ' + inttostr(MyWindowHandle));
  end;
end;

function UninstallHook: Boolean; stdcall;    
begin
  Result := UnhookWindowsHookEx(oDemoObj.HookHandle);
end;

function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  oDemoObj := TWDB_IPCDemoObj.Create('NempNochEinMP3Player');
  case nCode < 0 of
    FALSE:
      begin
        if (lparam = APPCOMMAND_MEDIA_NEXTTRACK)
            or (lparam = APPCOMMAND_MEDIA_PREVIOUSTRACK)
            or (lparam = APPCOMMAND_MEDIA_STOP)
            or (lparam = APPCOMMAND_MEDIA_PLAY_PAUSE)
        then
        begin
          SendMessage(oDemoObj.MainWindow,WM_APPCOMMAND,wparam,lParam);
          //showmessage('Abgefangen ' + inttostr(oDemoObj.HookHandle) + ' ' + inttostr(oDemoObj.MainWindow));
          Result := 1;
        end
        else
          Result := CallNextHookEx(oDemoObj.HookHandle, nCode, wParam, lParam);
      end;
    else
      Result := CallNextHookEx(oDemoObj.HookHandle, nCode, wParam, lParam);
  end;
end;
Dabei benutze ich diese Unit, um sehr einfach ein MMF zu erstellen (oDemoObj ist von dieser Kalsse abgeleitet und hat die Eigenschaften MainWindow und HookHandle).

Das funktioniert soweit auch - das heißt, wenn meine Anwendung den Hook installiert, dann erscheinen in der Memo der Hauptanwendung auch brav die Tastendrücke. Auch dann, wenn das Fenster nicht den Fokus hat.

Aber: Ich habe bei mir auch "iTouch" laufen. Dies ist ein Tool von Logitech. Was es genau macht, weiß ich nicht. Ich vermute sehr stark, dass es ebenfalls die APPCOMMAND_MEDIA_xxx Messsages (und andere) hookt und an sämtliche andere Fenster weiterleitet, damit diese die Multimediatasten ohne eigene Hooks benutzen können. (D.h. Meine Anwendung bekommt auch ohne meinen Hook die Nachrichten, aber ich möchte nicht voraussetzen, dass überall iTouch installiert ist).

Und da gibts jetzt Probleme. Wenn dieses iTouch vor meinem Hook gestartet wird (was die Regel sein dürfte), dann fängt iTouch die Message zuerst ab und sendet sie weiter, was dann von meinem Hook abgefangen wird und an meine Anwendung weitergeleitet wid. Und das passiert leider nicht nur einmal, sondern öfter (die genaue Zahl hängt von der Zahl der offenen Fenster ab). D.h. ein Druck auf die Taste Next bewirkt, dass meine Anwendung ca. 20 mal die Nachricht erhält. Das (hier auskommentierte) ShowMessage erscheint übrigens mit den entsprechenden Anwendungstiteln, die gerade laufen. Also ein paar mal "explorer", ein paar mal "delphi" usw.

Die Frage ist nun, was ich da falsch mache. Und für den unwahrscheinlichen Fall, dass ich nichts falsch mache, sondern das Problem bei iTouch liegt, wie kann ich das umgehen? D.h. wie kann ich feststellen, ob die Nachrichten, die ich hooken möchte, bereits gehookt werden? Damit mein Hook nicht zusätzlich installiert wird (in der Hoffnung, dass es dann schon klappt).
  Mit Zitat antworten Zitat
Benutzerbild von Boombuler
Boombuler

Registriert seit: 14. Mär 2003
Ort: Osnabrück
244 Beiträge
 
Delphi 2009 Professional
 
#2

Re: Multimedia-Tasten hooken

  Alt 17. Feb 2006, 07:03
Hi

ich hab auch mal versucht die Mediatasten zu Hooken. Dabei is mir aufgefallen, dass zwar mein Hook "abgespielt" wird aber trozdem die alte Nachricht gesendet wird! Problem scheint also zu sein das Windows oder das Logitech Programm das direkt auf Treiber-Ebene lösen! Wenn das wirklich so seien sollte kann man das mit dem Hooken gepflegt knicken

evtl äusert sich ja auch noch mal einer von unseren "Was-Macht-Windows-Genau"-Meistern

Greetz
Boombuler
"Look at you, Hacker. A pathetic creature of meat and bone, panting and sweating as you run through my corridors. How can you challenge a perfect, immortal machine?"
SwapIt Highscore:
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Multimedia-Tasten hooken

  Alt 17. Feb 2006, 07:17
Ich glaube Gausi aus dem DF hat da mal was gemacht mit seinem MP3 Player: http://www.delphi-forum.de/viewtopic...er=asc&start=0
Ächtz, es ist noch früh am morgen. Das bist du ja selber.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Duke_2004
Duke_2004

Registriert seit: 26. Jan 2005
61 Beiträge
 
#4

Re: Multimedia-Tasten hooken

  Alt 17. Feb 2006, 07:22
Hab sowas auch schonmal versucht mit meiner Tastatur... Hatte dann aber net mehr die Zeit dazu das weiterzutreiben... Den Tastatur-Hook konnt ich getrost vergessen... Den hats einfach ignoriert. ^^

Hatte dann gelesen, dass es wohl mit einem Low-Level-Hook funktionieren könnte, aber um das auszuprobieren fehlte die Zeit... Vielleicht schaffst du es ja damit...
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#5

Re: Multimedia-Tasten hooken

  Alt 17. Feb 2006, 07:24
Es laeuft ein Service der die Multimediatasten liest. Die Multimediatasten sind naemlich zumindest bei USB-Tastaturen ein eigenstaendiges Geraet.
Dieser Service sendet das WM_APPCOMMAND und wenn es von der Applikation nicht verboten wird, dann werden die Standardbelegungen vom Service initiiert.

Ungluecklicherweise koennen auch andere Programme solche Tricks ausfuehren.
Wie bemerkt sind das Maustreiber oder Tastaturtreiber. Genaugenommen macht es die Tray-Applikation, die ueber einen Seitenausgang des proprietaeren Treibers mit der Maus oder Tastatur kommuniziert und all die komischen Belegungen direkt implementiert.
Die Tasten gelangen nie ans Betriebssystem sondern nur an die Tray-Applikation.
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
847 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Multimedia-Tasten hooken

  Alt 17. Feb 2006, 08:32
OK, hier scheint es ja einige zu geben, die sich damit etwas auskennen

Wenn ich iTouch abschalte (ob es nun die Messages hooked oder auf Treiberebene arbeitet, ist mir jetzt erstmal egal, ich klicke halt auf das Symbol im Tray und wähle "beenden"), dann funktioniert mein Hook.
Wenn iTouch läuft, dann wird auch bei mehreren offenen Multimedia-Anwendungen nur eine bedient, wenn ich eine der Tasten drücke (dabei scheint es Prioritäten zu geben, der Windows-Player wird z.B bevorzugt bedient, dann kommt Winamp, dann der Thunderbird (fragt nicht, was der damit macht, ich weiß es nicht), und dann kommt meine Anwendung (ohne Hook)). Das bedeutet doch, dass iTouch mit dem Senden der Nachricht an alle Fenster aufhört, wenn eine Anwendung/ein Fenster was mit der Nachricht anfangen konnte.

Wenn ich jetzt meinen Hook dazwischenschalte (d.h. alle von iTouch gesendeten Messages gehen an dieselbe Anwendung), dann wird fröhlich weitergesendet. Das legt für mich die Vermutung nahe, dass irgendwas an meiner Hook-Technik nicht richtig ist - dass nämlich die Nachricht nicht als "empfangen und erledigt" markiert wird, wenn mein Hook sie an meine Anwendung weitergeleitet hat. Am Code in der Anwendung liegt es nicht: Wenn ich zwei Instanzen meines (noch ungehookten) Players starte, erhält nur eine von iTouch die entsprechende Nachricht.

@Luckie: Ja ich bins selbst . In dem mp3Player verwende ich bisher nur das erste Stück Code, was nur mit iTouch (bzw. mit Fokus) funktioniert. Ich kann es jetzt so erweitern, dass es ohne funktioniert, aber nicht so, das es auch ohne funktioniert
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
847 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: Multimedia-Tasten hooken

  Alt 21. Feb 2006, 13:39
Ich bin ja eigentlich kein Freund von Schiebepostings, aber ich komme hierbei einfach nicht weiter.

Vielleicht nochmal: Die Mediatasten können ruhig erst bei iTouch oder bei sonst einem Service o.Ä. ankommen. Nur wenn dieser Service dann die Nachrichten weiterverteilt, möchte ich mit meinem Hook die Nachricht auf meine Anwendung umleiten. Das funktioniert ja auch in sofern, dass meine Anwendung die Nachricht empfängt.
Nur leider empfange ich die Nachricht nicht nur einmal, sondern mehrfach, was meiner Meinung daran liegt, dass mein Hook die Nachricht nicht ganz korrekt behandelt/weiterleitet/als erledigt markiert, so dass iTouch erneut versucht, die WM_APPCOMMAND an den Mann zu bringen, was dann wiederrum von mir abgefangen und umgeleitet wird.
Das geht solange, bis der Service im Hintergrund alle Fenster durchhat.

Sieht denn keiner mit mehr Erfahrung als ich auf dem Gebiet den Fehler, den ich mache?
  Mit Zitat antworten Zitat
Der_Ventilator

Registriert seit: 11. Apr 2004
Ort: Kanada
136 Beiträge
 
Delphi 2010 Professional
 
#8

Re: Multimedia-Tasten hooken

  Alt 4. Sep 2006, 20:47
Hast du es bis jetzt gelöst?
Ich versuche nämlich gerade dasselbe bei meinem Mp3-Player Emat (http://www.g-software.de.gg) zu verwirklichen.

Nutze auch iTouch, allerdings mit eine PS2 Tastatur (ob das irgendwelche Unterschiede macht?)

Wie wäre es mit einer Option in deinem Player, bei der der Anwender iTouch-Kombatibilität auswählen kann?
Codito, ergo sum. - I code therefore I am
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
847 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: Multimedia-Tasten hooken

  Alt 4. Sep 2006, 21:31
Ich habe es halbwegs lösen können, ja. Problem war, dass ohne iTouch ein Hook nötig ist (in etwa der, den ich oben gepostet habe), aber dieser Hook bei installiertem iTouch dafür sorgt, dass die Message vervielfältigt wird.

Mein Lösungsprinzip:

Das Programm besitzt ein Flag "MMKey-Taste bereits benutzt", der beim Start aus einer ini gelesen wird. Initial ist dieser "False". Der Hook wird zunächst nicht installiert.

Wenn das erste Mal ein MMKey-Tastendruck erkannt wird (weil z.B das Programm beim Drücken den Fokus hatte, oder iTouch läuft), dann wird ein MMKey-Test initiiert. Dieser sieht so aus, dass der Hook installiert wird, und modal ein neues Fenster geöffnet wird, was keine MMKeys empfangen kann. Der User wird dann aufgefordert, EINMAL die Play-Taste zu drücken.
Im Hauptfenster wird nun (bei laufendem MMKey-Test) jede ankommende MMKey-Message "Play/Pause" registriert und dabei eine Variable hochgezählt (eine kommt mindestens an, wir haben ja den Hook installiert; zur Not gibt es ein "Abbrechen"-Button). Außerdem wird nach einem empfangenen "Play/Pause" die modale Form so geändert, dass sich beim User nett bedankt wird, und er aufgefordert wird, den OK-Button zu klicken, der dann erscheint.
Dann wird die Anzahl der angekommenen Messages ausgewertet. Ist sie = 1, dann hat der Hook vernünftig funktioniert, und wird beim nächsten Mal geladen.
Ist sie >1, dann ist wahrscheinlich iTouch o.Ä. installiert - auf jeden Fall läuft was schief (oder der User hat zweimal gedrückt - für diesen Fall kann der Test auch manuell gestartet werden). Der Hook wird dann deinstalliert und beim nächsten Start nicht geladen.

Der Wert "MMKey-Taste bereits benutzt" wird dann auf True gesetzt, so dass die MMKey-Einrichtung beim nächsten Mal nicht mehr durchgeführt werden muss.
  Mit Zitat antworten Zitat
Der_Ventilator

Registriert seit: 11. Apr 2004
Ort: Kanada
136 Beiträge
 
Delphi 2010 Professional
 
#10

Re: Multimedia-Tasten hooken

  Alt 13. Sep 2006, 12:08
Die von dir genutzten Konstanten habe ich im Netz gefunden:

Delphi-Quellcode:
const
   APPCOMMAND_MEDIA_NEXTTRACK = $B0000; // 720896;
   APPCOMMAND_MEDIA_PREVIOUSTRACK = $C0000; // 786432;
   APPCOMMAND_MEDIA_STOP = $D0000; // 851968;
   APPCOMMAND_MEDIA_PLAY_PAUSE = $E0000; // 917504;

Aber wie finde ich diese heraus?

APPCOMMAND_VOLUME_DOWN
APPCOMMAND_VOLUME_MUTE
APPCOMMAND_VOLUME_UP

Eine KeyDownAbfrage reagiert nicht auf die Media Tasten meiner Logitech Tastatur; die procedure MediaKey (Var aMSG: tMessage) schlägt auch nicht auf die Volume +/- Knöpfe an. Wie kann man diese in sein Programm einbinden?
Codito, ergo sum. - I code therefore I am
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 12:23 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