Jnmarczi Posted March 24, 2008 Share Posted March 24, 2008 (edited) Hallo zusammen, ich versuche gerade herauszufinden, wie man über die SendMessage API den aktuellen Kanal wechseln kann... Die Nutzung des COM Interfaces scheidet leider in meinem konkreten Fall aus... Hat jemand zufällig ein kleines Code-Beispiel für diesen Anwendungsfall (Delphi Code bevorzugt) ? gruß, jnmarczi Edited March 24, 2008 by Jnmarczi Quote Link to comment
Griga Posted March 25, 2008 Share Posted March 25, 2008 Was ist an Daten verfügbar, um den Kanal zu identifizieren? Sind z.B. Tunertyp (DVB-S/T/C), Sendername, ServiceID und Audio-PID bekannt? Soll die Umschaltung durch ein anderes Programm (einen anderen Prozess) oder durch ein Plugin erfolgen? Quote Link to comment
Jnmarczi Posted March 25, 2008 Author Share Posted March 25, 2008 (edited) Was ist an Daten verfügbar, um den Kanal zu identifizieren? Sind z.B. Tunertyp (DVB-S/T/C), Sendername, ServiceID und Audio-PID bekannt? Soll die Umschaltung durch ein anderes Programm (einen anderen Prozess) oder durch ein Plugin erfolgen? Die Daten sind bekannt (Auslesen der channels.dat oder mittels extra Config-Datei)... Die Architektur ist derzeit noch ein kleines Problem, da habe ich noch nicht den Dreh raus. Das eigentliche "Programm" läuft als Com-Server, der in einem Windows-Service gehostet wird. Dieser Service ist nur unter LocalSystem-Account lauffähig (Umstellen auf einen User-Account hat mir der Service mit einem schönen Absturz quittiert ) Deswegen scheidet auch die Nutzung des COM-Interfaces aus, da mein COM-Server den COM-Server vom DVBViewer gar nicht "sieht", bzw. GetActiveObjekt nicht funktioniert. Wenn die Umschaltung aus einem "anderen Prozess" klappt, würde mich das weiterbringen. Wenn es nicht funktioniert, würde ich ein DVBV Plugin schreiben und mal schauen wie ich das aus meinem Com-Server anspreche (COM, Pipes, Sockets o.ä.)... Gruß, jnmarczi Edited March 25, 2008 by Jnmarczi Quote Link to comment
Griga Posted March 25, 2008 Share Posted March 25, 2008 Ok, am besten versuchst du es so: 1) Du stellst aus den Kanalparametern einen String zusammen, der das gleiche Format hat wie ein Kommandoparameter, mit dem man den DVBViewer dazu bewegt, einen Sender einzuschalten. Er enthält die ChannelID, die sich aus Name, Tunertyp, AudioPID und ServiceID zusammensetzt. Der DVBViewer identifiziert den dazugehörigen Sender in seiner Kanalliste fehlertolerant, d.h. selbst wenn eine der Angaben nicht stimmt oder fehlt, findet er meistens noch den richtigen Sender: function BuildID(const Channel: TChannel): String; begin with Channel, Tuner do result := '-c' + Name + ':' + IntToStr(Int64((DWord(TunerType)+1) shl 29 + AudioPID shl 16 + SID)); end; 2) Du benutzt PostMessage, um dem DVBViewer den String zu senden. Da sowas prozessübergreifend mit Messages normalerweise nicht geht, hinterlegst du den String über die API-Funktion GlobalAddAtom für den DVBViewer und sendest ihm das "Atom" (also die String-ID), das die Funktion zurückgibt. Der DVBViewer holt den String dann mit GlobalGetAtomName ab, führt den Kommandoparameter aus und entfernt ihn mit GlobalDeleteAtom aus der entsprechenden Windows-Tabelle. Deshalb musst du sicherstellen, dass der DVBViewer dabei läuft, weil du sonst das OS zumüllst. Wenn das Handle des DVBViewer-Hauptfensters bereits ermittelt wurde (z.B. mit FindWindow), sieht der Code so aus: const MSG_DVBCOMMANDPARAMS = WM_USER + 100; var DVBViewerHandle: HWND; PostMessage(DVBViewerHandle,MSG_DVBCOMMANDPARAMS,GlobalAddAtom(PChar(BuildID(Channel))),0); Der EPGManager verwendet diese Methode, und auch der DVBViewer selbst, wenn man ihn (d.h. die gleiche Installation) ein zweites Mal mit einem Kommandoparemeter startet, um diesen an die schon laufende Instanz zu übergeben und sich danach sofort wieder zu beenden. Quote Link to comment
Lars_MQ Posted March 25, 2008 Share Posted March 25, 2008 1. müsste man sehen, ob das geht, ein starten aus einem service heraus kann durchaus fatale folgen haben, besonders wenn der usermode =1 ist. 2. Wenn ich mich recht erinnere versagt Findwindow im service context, da der service keinen zugriff auf den userdesktop hat. Das ganze ist nicht so einfach zu lösen, ich habe mich bei recordingservice mit einem plugin beholfen, das via shared memory mit dem service kommuniziert. Quote Link to comment
Jnmarczi Posted March 25, 2008 Author Share Posted March 25, 2008 1. müsste man sehen, ob das geht, ein starten aus einem service heraus kann durchaus fatale folgen haben, besonders wenn der usermode =1 ist. 2. Wenn ich mich recht erinnere versagt Findwindow im service context, da der service keinen zugriff auf den userdesktop hat. Danke Griga, danke Lars für die Tipps... Ich werde das heute abend mal reinhacken... @Lars: 2. funktioniert, wenn man dem Service und LocalSystem den Datenaustausch mit dem Destop erlaubt. SendMessage funktioniert auch schon generell, d.h. ich habe schon Actions im DVBViewer durch den Service ausgelöst. Nur noch eine kurze Frage... Funktioniert das Auslesen des aktuellen Kanals auf ähnliche Weise??? Danke und Gruß, jnmarczi Quote Link to comment
Lars_MQ Posted March 25, 2008 Share Posted March 25, 2008 @Lars: 2. funktioniert, wenn man dem Service und LocalSystem den Datenaustausch mit dem Destop erlaubt. Auch unter vista? ich bin der meinung dort ist das nicht mehr erlaubt. Quote Link to comment
Fiedel Posted March 25, 2008 Share Posted March 25, 2008 Auch unter vista? ich bin der meinung dort ist das nicht mehr erlaubt. Vorschlag eines Anfängers: activedvbviewer = (DVBViewerServer.IDVBViewer)Marshal.GetActiveObject("DVBViewerServer.DVBViewer"); Quote Link to comment
Lars_MQ Posted March 25, 2008 Share Posted March 25, 2008 Der service hat doch gar keinen zugriff auf den ROT des userdesktops. Quote Link to comment
Jnmarczi Posted March 25, 2008 Author Share Posted March 25, 2008 Auch unter vista? ich bin der meinung dort ist das nicht mehr erlaubt. Stimmt, an Vista habe ich gar nicht gedacht Da muss ich mir evtl. noch was anderes ausdenken... Quote Link to comment
Jnmarczi Posted March 26, 2008 Author Share Posted March 26, 2008 Auch unter vista? ich bin der meinung dort ist das nicht mehr erlaubt. Hallo Lars, danke nochmal für den Hinweis... Ich werde das Problem nun mit einem Plugin lösen, das mit dem Service über Named Pipes kommuniziert. Einen ersten Wurf hab' schon runtergetippt... Ist allerdings noch sehr träge... Gruß, jnmarczi Quote Link to comment
Jnmarczi Posted March 26, 2008 Author Share Posted March 26, 2008 Hallo nochmal, der von Griga vorgeschlagene Weg funktioniert ganz gut... Allerdings dauert es vom PostMessage z.T. 7-8 sek. bis der DVBViewer wirklich den Kanal wechselt (wäre für eine interaktive Fernbedienung ein bisschen zu träge ) Da ich jetzt - aufgrund des Hinweises von Lars - doch auf ein Plugin (und IPC mit dem Service) umgestiegen bin, wollte ich nachfragen ob es noch eine andere Möglichkeit gibt? Da ich nun auch wg. einem evtl. Usermode Problem auf eine eigene Konfiguration umgestiegen bin - um z.B. die Senderliste für die Philips FB zu speichern - kann ich mir jede dafür benötigte Information vorhalten. Oder empfiehlt Ihr an dieser Stelle die Verwendung des COM Interfaces in einem Plugin? gruß, jnmarczi Quote Link to comment
erwin Posted March 27, 2008 Share Posted March 27, 2008 Oder empfiehlt Ihr an dieser Stelle die Verwendung des COM Interfaces in einem Plugin? Wenn die gewünschte DVBV-Funktionalität aus dem Plugin heraus realisierbar ist macht COM keinen Sinn - weil 1. noch mehr Performanceverlust und 2. der DVBV GE nicht mehr verwendet werden kann. der von Griga vorgeschlagene Weg funktioniert ganz gut... Allerdings dauert es vom PostMessage z.T. 7-8 sek. bis der DVBViewer wirklichden Kanal wechselt (wäre für eine interaktive Fernbedienung ein bisschen zu träge ) Hmm, 7-8 sek erscheint mir trotz Pipes-IPC nun doch ein wenig lang. Du solltest mal feststellen wo dieser Performanceverlust wirklich herkommt. Wenns wirklich die Pipes sind (werden die etwa gepollt?) gibst ja noch andere Oprionen für die IPC - Shared Medmory etwa. mfg erwin Quote Link to comment
Jnmarczi Posted March 27, 2008 Author Share Posted March 27, 2008 (edited) Wenns wirklich die Pipes sind (werden die etwa gepollt?) gibst ja noch andere Oprionen für die IPC - Shared Medmory etwa. Hallo Erwin, ja, die Pipes werden per Timer gepollt... Ich werde zur Sicherheit mal das Plugin deaktivieren und PostMessage aus einer anderen Applikation absetzen. Mal schauen, ob es dann schneller geht. Wenn das bottleneck doch PostMessage ist, was dann? Gruß, jnmarczi Edited March 27, 2008 by Jnmarczi Quote Link to comment
erwin Posted March 27, 2008 Share Posted March 27, 2008 Ich werde zur Sicherheit mal das Plugin deaktivieren und PostMessageaus einer anderen Applikation absetzen. Mal schauen, ob es dann schneller geht. Wenn Du mit SendMessage/Postmessage aus einem anderen Prozess auf den DVBV zugreifen willst könnte dies hier hilfreich sein: http://www.DVBViewer.info/forum/index.php?showtopic=19515 mfg erwin Quote Link to comment
erwin Posted March 27, 2008 Share Posted March 27, 2008 der von Griga vorgeschlagene Weg funktioniert ganz gut... Allerdings dauert es vom PostMessage z.T. 7-8 sek. bis der DVBViewer wirklichden Kanal wechselt (wäre für eine interaktive Fernbedienung ein bisschen zu träge ) Noch ein par Anregungen. const MSG_DVBCOMMANDPARAMS = WM_USER + 100; var DVBViewerHandle: HWND; PostMessage(DVBViewerHandle,MSG_DVBCOMMANDPARAMS,GlobalAddAtom(PChar(BuildID(Channel))),0); Wenn Du aus einem DVBV-Plugin heraus operierst, brauchst Du den Umweg über GlobalAddAtom() nicht. const MSG_CHANNELSWITCH = ???; var DVBViewerHandle: HWND; CHANNELSWITCH_DATA: channel. PostMessage(DVBViewerHandle,MSG_CHANNELSWITCH,channel,0); Auch entfällt das Parsen des übergebenen Kommandozeilenparameters. Du brauchst hierfür den Wert für MSG_CHANNELSWITCH (oder wie ihn die DVBV-Entwickler nennen) und die Beschreibung der zugehörigen Datenstruktur/Datenstrings aus dem SDK. Habs zwar dort nicht gefunden aber vielleicht schauen hier die Entwickler noch mal vorbei. mfg erwin Quote Link to comment
Griga Posted March 27, 2008 Share Posted March 27, 2008 Wenn Du aus einem DVBV-Plugin heraus operierst, brauchst Du den Umweg über GlobalAddAtom() nicht.Auch entfällt das Parsen des übergebenen Kommandozeilenparameters. Das sind alles nur Millisekunden. Wenn ich hier eine DVBViewer-Verknüpfung mit einem Kommandoparameter erzeuge, der auf einen bestimmten Sender umschaltet, geht das nach einem Doppelklick darauf bei laufendem DVBViewer Pro in zwei bis drei Sekunden über die Bühne. Und dabei muss sogar eine zweite DVBViewer-Instanz von der Festplatte geladen und gestartet werden, die dann der ersten wie beschrieben den Kommandoparameter übermittelt. Die Verzögerung dürfte deshalb eine andere Ursache haben. Quote Link to comment
erwin Posted March 27, 2008 Share Posted March 27, 2008 Das sind alles nur Millisekunden. Wenn ich hier eine DVBViewer-Verknüpfung mit einem Kommandoparameter erzeuge, der auf einen bestimmten Sender umschaltet, geht das nach einem Doppelklick darauf bei laufendem DVBViewer Pro in zwei bis drei Sekunden über die Bühne. Und dabei muss sogar eine zweite DVBViewer-Instanz von der Festplatte geladen und gestartet werden, die dann der ersten wie beschrieben den Kommandoparameter übermittelt. Die Verzögerung dürfte deshalb eine andere Ursache haben. Sehe ich auch so mfg erwin Quote Link to comment
Jnmarczi Posted March 31, 2008 Author Share Posted March 31, 2008 Die Verzögerung dürfte deshalb eine andere Ursache haben. Hatte Sie, ich hatte noch eine Plugin-Leiche von meinen kläglichen Entwicklungsversuchen im Plugins-Verzeichnis... ...DVBViewer-Verknüpfung mit einem Kommandoparameter erzeuge... @Griga: Du bist meine Inspiration... Um es erst einmal zum Laufen zu bringen und mich nicht in Pipes, MMF o.ä. zu verzetteln, habe ich eine "ähnliche" Lösung gewählt. Aus dem Service heraus wird nun mittels CreateProcessAsUser eine Applikation im User-Kontext gestartet, die dann die Kommandos an den DVBViewer per PostMessage/SendMessage sendet. Auf diese Weise kann ich nun auch den DVBViewer selbst im User-Kontext starten, falls er noch nicht läuft. Danke und Gruß, jnmarczi Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.