AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Notebook Presenter Mouse - Abfangen der Präsentationstasten
Thema durchsuchen
Ansicht
Themen-Optionen

Notebook Presenter Mouse - Abfangen der Präsentationstasten

Ein Thema von Martin K · begonnen am 5. Jul 2008 · letzter Beitrag vom 13. Jul 2008
Antwort Antwort
Benutzerbild von Martin K
Martin K

Registriert seit: 20. Okt 2005
919 Beiträge
 
Turbo Delphi für Win32
 
#1

Notebook Presenter Mouse - Abfangen der Präsentationstasten

  Alt 5. Jul 2008, 00:23
Hallo,
habe mir die "Wireless Notebook Presenter Mouse 8000" von Microsoft gekauft.
Mit den Präsentationstasten lässt sich leider nur PowerPoint steuern, wir erstellen unsere Präsentationen allerdings mit LaTeX und verwenden zum präsentieren den Acrobat Reader. Nach etwas googeln habe ich folgende Links gefunden:
Fertige Lösung
Lösung für Ubuntu
OpenOffice

Nun wollte ich mir so etwas wie im ersten Link selber basteln, vor allem da die Mouse 3 Tasten zur Präsentationssteuerung hat, die fertige Lösung aber nur den Vor- und Zurückbutton abfängt.

Das hier klingt dabei besonders hilfreich:
Zitat:
The mouse generates the WM_APPCOMMAND message with the "cmd" set to
APPCOMMAND_MEDIA_NEXTTRACK for the next page
APPCOMMAND_MEDIA_PREVIOUSTRACK for the previous page

and (not necessary for presentations, but could be used to start and stop
embedded animations and sounds)
APPCOMMAND_MEDIA_PLAY_PAUSE for the media control button
Also habe ich mir folgendes gebastelt, funktioniert auch:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    procedure Hallo(var Msg: tagMsg); message WM_APPCOMMAND;
  end;

{...}

procedure TForm1.Hallo(var Msg: tagMSG);
begin
  case Msg.wParam of
    720896: ShowMessage('Nächste Folie');
    786432: ShowMessage('Vorherige Folie');
    917504: ShowMessage('Leere Folie');
  end;
end;
Nur:
Die Meldung wird immer 2mal angezeigt wenn das Fenster den Fokus hat, sonst nur einmal.
Mir ist es nicht gelungen, das Ganze über RegisterHotKey zu machen, das ist aber mein Ziel und dabei brauch ich eure Hilfe
Die Präsentationstasten sollen schließlich richtig abgefangen werden, im Moment startet sich nämlich bei "Leere Folie" (APPCOMMAND_MEDIA_PLAY_PAUSE) zusätzlich noch der Windows Media Player...
Ach ja, diese APPCOMMAND_MEDIA_...-Befehle habe ich in Delphi nicht gefunden, es erscheint immer "Undefinierter Bezeichner"...

Danke schonmal für eure Antworten
Mit den Menschen ist es wie mit Computern -
es gibt Nullen und Einsen.
  Mit Zitat antworten Zitat
Benutzerbild von Martin K
Martin K

Registriert seit: 20. Okt 2005
919 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Notebook Presenter Mouse - Abfangen der Präsentationstas

  Alt 8. Jul 2008, 18:37
So, bin jetzt etwas weiter gekommen, habe den Code wie folgt geändert:

Delphi-Quellcode:
type
  TForm1 = class(TForm)
    procedure MediaKey(var Msg: TMessage); message WM_APPCOMMAND;
  end;

{...}

procedure TForm1.MediaKey(var Msg: TMessage);
begin
  case Msg.lParam of

    $B0000: // APPCOMMAND_MEDIA_NEXTTRACK
      begin
        ShowMessage('Nächste Folie');
        Msg.Result := 1;
      end;

    $C0000: // APPCOMMAND_MEDIA_PREVIOUSTRACK
      begin
        ShowMessage('Vorherige Folie');
        Msg.Result := 1;
      end;

    $E0000: // APPCOMMAND_MEDIA_PLAY_PAUSE
      begin
        ShowMessage('Leere Folie');
        Msg.Result := 1;
      end;
  end;
end;
Jetzt wird die Meldung nur noch einmal angezeigt, da durch Result := 1 Windows mitgeteilt wurde, dass das Programm die Eingabe verarbeitet hat.
Dass die Meldung auch angezeigt wird, wenn das Programm nicht den Fokus hat, klappt allerdings nur wenn das Fenster offen ist (z.B. hinter einem anderen Fenster liegt, dass diese Eingabe nicht verarbeitet hat), wenn mein Fenster minimiert ist, klappt es nicht mehr (die Eingabe kommt nicht an).
Da jedoch z.B. der Windows Media Player diese Eingabe auch bekommt wenn er minimiert ist (z.B. "Nächster Titel" wenn der Player grad minimiert ist), habe ich mal meine Vermutung aufgestellt:

1. Das Fenster, welches gerade im Vordergrund ist, bekommt die Eingabe. Wird die Eingabe nich verarbeitet (nicht Result := 1), dann

2. Die Eingabe wird nacheinander an alle geöffneten Fenster geschickt (jedoch keine minimierten). Wenn die Eingabe immer noch nicht verarbeitet wurde, dann

3. Wird eine Liste von Programmen durchgegangen, die diese Eingabe erhalten (so z.B. der Windows Media Player). Übrigens wird der sogar mit der Play/Pause Taste gestartet, wenn er überhaupt nicht läuft! Wurde die Eingabe immer noch nicht verarbeitet, dann

4. Gibt es laut MSDN einen Shell Hook mit dem Code HSHELL_APPCOMMAND.


Da 1 und 2 nur bei geöffnetem Fenster geht und ich natürlich gerne mein Programm minimieren würde, um die Eingaben umzuwandeln, wäre die beste Lösung wenn ich irgendwie herausfinden könnten, wie das mit der Liste der Programme funktioniert. Gibt es eine solche Liste? Wo ist die? Kann ich da einfach mein Programm in diese Liste hinzufügen? Oder gibts vielleich ein Attribut eines Programms, das aussagt, dass es sich um ein Muldimedia-Programm handelt, wie z.B. beim WMP, und dass dann die Eingabe an alle "Multimedia-Programme" gesendet wird?

Ansonsten wäre es interessant zu wissen, wie das mit dem Shell Hook funktioniert. Davon habe ich keine Ahnung...
Wobei sich mir die Frage stellt, da z.B. die Play/Pause schon in Schritt 3 immer an den WMP gesendet wird (?), ob es dann überhaupt zu dem Shell Hook kommt ?!?

Wäre wirklich super, bin im Moment absolut ratlos, wie ich diese Media-Tasten global abfangen kann...

Dieser Thread hat mir leider auch nicht wirklich geholfen, da hier keine Lösung angeboten wird... (hab ihn erst entdeckt, nachdem ich das Thema eröffnet hatte)
Mit den Menschen ist es wie mit Computern -
es gibt Nullen und Einsen.
  Mit Zitat antworten Zitat
Benutzerbild von Martin K
Martin K

Registriert seit: 20. Okt 2005
919 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Notebook Presenter Mouse - Abfangen der Präsentationstas

  Alt 8. Jul 2008, 22:38
Sorry, ich weiß dass pushen vor 24 Stunden nicht gern gesehen ist, aber ich habe jetzt mal das Tutorial über Hooks durchgearbeitet und es damit versucht:
Delphi-Quellcode:
function InstallHook(Hwnd: THandle): Boolean; stdcall; external 'PresenterHook.dll';
function UninstallHook: Boolean; stdcall; external 'PresenterHook.dll';

{...}

procedure TForm1.FormCreate(Sender: TObject);
begin
  InstallHook(Handle);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  UninstallHook;
end;
Mit folgender DLL:
Delphi-Quellcode:
library PresenterHook;

uses
  Windows, Messages, Dialogs, SysUtils;

var
  HookHandle: Cardinal = 0;
  WindowHandle: Cardinal = 0;

function PresenterHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
  case nCode < 0 of
    TRUE: exit;
    FALSE:
      begin
        if nCode = HSHELL_APPCOMMAND then
          ShowMessage('Hook:' +#13#10+ IntToStr(wParam) +#13#10+ IntToStr(lParam));
      end;
  end;
end;

function InstallHook(Hwnd: Cardinal): Boolean; stdcall;
begin
  Result := False;
  if HookHandle = 0 then
  begin
    HookHandle := SetWindowsHookEx(WH_SHELL, @PresenterHookProc, HInstance, 0);
    WindowHandle := Hwnd;
    Result := TRUE;
  end;
end;

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

exports
  InstallHook,
  UninstallHook;
end.
Leider passiert gar nichts
Bei Play/Pause wird immer noch der WMP gestartet.

Was mache ich falsch?

Warum klappt das mit dem WMP wenn er minimiert ist, aber nicht mit meinem Programm?
Übrigens mit PowerDVD klappts auch, wenn PowerDVD minimiert ist und ich z.B. Play/Pause drücke, so wird die Wiedergabe in PowerDVD pausiert und NICHT der WMP gestartet!
Warum kriege ich sowas in meinem Programm nicht hin?
Ich bin echt am verzweifeln
Mit den Menschen ist es wie mit Computern -
es gibt Nullen und Einsen.
  Mit Zitat antworten Zitat
Benutzerbild von freak4fun
freak4fun

Registriert seit: 22. Sep 2004
Ort: Hannover
1.807 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#4

Re: Notebook Presenter Mouse - Abfangen der Präsentationstas

  Alt 8. Jul 2008, 22:51
Mal blöd gefragt: Funktioniert der Hook bei anderen Tasten?
Christian
IT: Schließen Sie bitte das Fenster. User: Die Tür auch?
i++; // zaehler i um 1 erhoehen
  Mit Zitat antworten Zitat
Benutzerbild von Martin K
Martin K

Registriert seit: 20. Okt 2005
919 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Notebook Presenter Mouse - Abfangen der Präsentationstas

  Alt 8. Jul 2008, 22:56
Meinst du mit "anderen Tasten" statt Play/Pause auch nächster Track und vorheriger Track?
-> Nein, funktioniert nicht, hab ich getestet. Wenn ein Media Player gestartet ist (WMP/PowerDVD) kommt dann entsprächend der nächste/vorherige Titel. Ansonsten keine Funktion

Wenn du mit "andere Tasten" normale Tasten meinst?
-> Nein, es ist ja ein Shell-Hook, kein normaler Tastatur-Hook (WH_SHELL mit Code=HSHELL_APPCOMMAND). Ansonsten hab ich den Quellcode 1:1 vom Tutorial übernommen.
Mit den Menschen ist es wie mit Computern -
es gibt Nullen und Einsen.
  Mit Zitat antworten Zitat
Benutzerbild von Martin K
Martin K

Registriert seit: 20. Okt 2005
919 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Notebook Presenter Mouse - Abfangen der Präsentationstas

  Alt 11. Jul 2008, 16:37
Mit einem Hook funktioniert es definitiv nicht!
Hab es mal mit der Klasse JvAppCommand aus den JVCL probiert, auch hier klappt der Hook nicht.
Es scheint so, dass die "Microsoft IntelliPoint"-Software hier ihr eigenes Süppchen kocht...

Läuft weder WMP noch PowerDVD, so wird über die Play/Pause-Taste selbst bei installiertem Hook der WMP gestartet!
Wenn WMP oder PowerDVD läuft, so erhalten diese stets die Nachrichten der Tasten, sogar wenn diese minimiert sind!
Irgendwie müsste ich doch sowas dann auch hinkriegen? Ich vermute ja immernoch, dass die IntelliPoint-Software eine Art Liste von Multimediaprogrammen hat, an die diese Tasten gesendet werden, wenn sonst kein Programm vorher die Tasten verarbeitet hat. Und da hilft wohl kein Hook...

Oder es ist vielleicht so, dass diese Programme (WMP/PowerDVD) sich beim Start bei der IntelliPoint-Software "registrieren", damit die Software nun weiß, dass ein solches Programm läuft, dem es die Tasten sendet...
Ein Idiz dafür habe ich in der Dokumentation über FindWindow() gefunden:
Zitat:
To check if the Microsoft IntelliType version 1.x software is running, call FindWindow as follows:
Code:
FindWindow("MSITPro::EventQueue",NULL);
To check if the IntelliType version 2.0 software is running, call FindWindow as follows:
Code:
FindWindow("Type32_Main_Window", NULL);
If the IntelliType software is running, it sends WM_APPCOMMAND messages to the application. Otherwise the application must install a hook to receive WM_APPCOMMAND messages.
Wie versteht ihr diese Aussage?
Man ruft FindWindow mit den entsprechenden Parametern auf, dann hat man sich bei der Software "registriert" und erhält die Tasten von WM_APPCOMMAND auch ohne Hook (der ja nicht funktioniert)?
...klingt unlogisch, aber so habe ich diese Aussage verstanden?!?
Was meint ihr?

[Edit]
Ist wohl eher so zu verstehen: Wenn die IntelliPoint-Software läuft, dann verschickt sie WM_APPCOMMAND Nachrichten. Wenn sie nicht läuft, muss man einen Hook installieren, um die Nachrichten zu empfangen.
Mit anderen Worten: Wenn sie läuft, funktioniert kein Hook, sondern nur das normale Empfangen der Nachrichten.
So kann ich es ja auch bestätigen: Ein Hook funktiniert nicht bei laufender IntelliPoint-Software!
[/Edit]

Allerdings ist der Artikel wohl schon etwas älter und inzwischen heißt die Software "Microsoft IntelliPoint" Version 6.2.
Mit den oben genannten FindWindow-Aufrufen habe ich auch immer 0 zurückbekommen...
Kennt jemand den FindWindow-Aufruf für die aktuelle Version dieser Software?
Mit den Menschen ist es wie mit Computern -
es gibt Nullen und Einsen.
  Mit Zitat antworten Zitat
Benutzerbild von Martin K
Martin K

Registriert seit: 20. Okt 2005
919 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: Notebook Presenter Mouse - Abfangen der Präsentationstas

  Alt 13. Jul 2008, 16:20
Die Frage ist immer noch, warum andere Programme wie PowerDVD oder WMP die WM_APPCOMMAND-Nachrichten auch erhalten, wenn das Fenster minimiert ist.
Mein Programm bekommt die Nachrichten nur, wenn es NICHT minimiert ist, muss aber auch nicht im Vordergrund sein. Zum Abfangen der Tasten müsste ich eben nur dafür sorgen, dass mein Programm nicht minimiert werden kann...
Mich würde halt nur mal interessieren, ob sich jemand mit der IntelliPoint-Software auskennt, warum manche Programme hier immer die Tasten-Eingaben (WM_APPCOMMAND-Nachrichten) erhalten, auch wenn diese minimiert sind?!? Hat denn keiner diese Software drauf und weiß wie die das regelt?
Mit den Menschen ist es wie mit Computern -
es gibt Nullen und Einsen.
  Mit Zitat antworten Zitat
Antwort Antwort


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 08:16 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