![]() |
AW: TAudioVolume Komponente incl. System Mixer
Zitat:
Wenn du mehr verwendest wie ich in TAudioVolume kommst du um eine extra Event Thread nicht herum. Wie oft habe ich das jetzt schon geschrieben? Hmmm.... gruss |
AW: TAudioVolume Komponente incl. System Mixer
Liste der Anhänge anzeigen (Anzahl: 1)
Eine VCL-Anwendung wie die oben gezeigte besteht aber in der Regel aus mindestens drei Threads.
Zumindest laut Anzeige der IDE. Das Verhalten scheint es so nur in Windows 7 zu geben. Unter Windows 10 kann man so viele Threads (die andere Aufgaben machen) erstellen wie man möchte, es wird OnSessionCreate ausgelöst. Sogar im Mainthread und im extra dafür erstellten Thread. Siehe Screenshot. Vielleicht doch mal ein Grund zu wechseln und upzudaten? Hihi, war nur Spaß! :-D 8-) |
AW: TAudioVolume Komponente incl. System Mixer
Zitat:
Eine wirklich fertige und vor allem gute Komponente in der Hinsicht habe ich über die Jahre nicht wirklich ausmachen können für Delphi. Ich habe jetzt folgendes gemacht. (Bin dafür wieder auf Sendmessage umgestiegen da ich nicht weis wie man den Thread in die Class TAudioVolume integriert.) *.pas angehängt. Wenn die Message ausgelöst wird.
Delphi-Quellcode:
procedure TSessionThread.WndProc(var Msg: TMessage);
begin if FThreadHandle <> 0 then begin case Msg.Msg of WM_SessionCreate: Msg.Result := SendMessage(FThreadHandle, WM_SessionCreate, Msg.WParam, Msg.LParam); WM_SessionDestroy: Msg.Result := SendMessage(FThreadHandle, WM_SessionDestroy, Msg.WParam, Msg.LParam); else Msg.Result := DefWindowProc(FWnd, Msg.Msg, Msg.WParam, Msg.LParam); end; end else Msg.Result := DefWindowProc(FWnd, Msg.Msg, Msg.WParam, Msg.LParam); end;
Delphi-Quellcode:
dann kommt sie hier an.
procedure TAudioVolume.ProcessMsg(var Msg: TMessage);
begin case Msg.Msg of WM_SessionCreate: if Assigned(FOnSessionCreated) then OnSessionCreated(IAudioSessionControl(Msg.WParam)); WM_SessionDestroy: if Assigned(FOnSessionDisconnected) then OnSessionDisconnected(Msg.WParam); end; end; in OnSessionCreated.. sorge ich dann dafür das nur eine Message der gleichen PID zur Anwendung durchgelassen wird.
Delphi-Quellcode:
function TAudioVolume.OnSessionCreated(const NewSession: IAudioSessionControl): HResult;
var SessionControl2: IAudioSessionControl2; PID: uint; IntI: Integer; begin Result := S_OK; if Supports(NewSession, IAudioSessionControl2, SessionControl2) then begin SetLength(PidList, PIDIndex + 1); SessionControl2.GetProcessID(PID); for IntI := 0 to (Length(PidList) - 1) do if PidList[IntI] = PID then begin SessionControl2 := nil; exit; end; PidList[PIDIndex] := PID; end; if (MainThreadID <> GetCurrentThreadId) then begin TThread.Synchronize(nil, procedure begin if Assigned(FOnSessionCreated) then begin SessionPIDCreated := PID; FOnSessionCreated(NewSession); inc(PIDIndex); end; end); end; end; das funktioniert soweit. (Bei Message Boxen) aber auch da mosert Delphi schon rum wegen Deadlock. Aber! Ich kann keine neue Grafikkomponente erstellen der Thread blockt irgendwie sobald ich einen zugriff auf einer der Funktionen von TAudioVolume starte. Dann hängt der Thread. Ein einfacher Aufruf von SimpleVolume := nil; reicht da schon. Keine Ahnung was da wieder abgeht. Ich weis nicht wie ich dann die Komponente erstellen soll wenn nicht hier. PS: OnSessionDisconnected funktioniert nie egal ob mit Event Thread oder nicht. Ist das bei dir auch so? Wenn ja muss ich das später über die PID steuern. gruss |
AW: TAudioVolume Komponente incl. System Mixer
1. Bitte beachte was ich einige Seiten zuvor über das Casten und Versenden von Interface-Pointern schrieb.
2. OnSessionDisconnected könnte möglicherweise mit der 3 Minuten-Regel zusammenhängen, die HolgerX einige Seiten zuvor herausgefunden hat. Hast du das mal länger laufen lassen? |
AW: TAudioVolume Komponente incl. System Mixer
Zitat:
Nur wie mache ich es besser? Dazu müsste ich den Event Thread in TAudioVolume integrieren nur weis nicht wie. Sorry gruss |
AW: TAudioVolume Komponente incl. System Mixer
Du weißt doch, wie man eine Callback schreibt, was hält dich auf?
Welche Klasse integriert denn jetzt eigentlich das Interface IAudioSessionNotification? Der TSessionThread ist es nicht. |
AW: TAudioVolume Komponente incl. System Mixer
Zitat:
Zitat:
OK.. Habe die Winproc rausgeworfen brauche ich nicht. Benötige den Thread nur zur Initialisierung von CoInitializeEx. Werde mal testen ob es jetzt ohne zu blocken funktioniert. EDIT: Nein geht nicht hängt bei SimpleAudio := nil. Ich gebe es bald auf.. LOL gruss |
AW: TAudioVolume Komponente incl. System Mixer
Bring doch erstmal ein bisschen Übersicht rein.
Es ist ja wieder so eine 3000 Zeilen Unit. Du hast fünf Stellen, bei denen du
Delphi-Quellcode:
aufrufst.
...Device.Activate(IID_IAudioSessionManager...
Baue das doch bitte so um, dass du pro Device (in der Regel nutzt du ja das Default) das nur einmal machst. Speichere dir alle Referenzen von den Interfaces ab, die du dann benötigst (IAudioSessionControl2, IAudioSessionEnumerator usw.). Am besten in einen Container in einer generischen Liste/Dictionary. Vielleicht ist das ständige Neuholen und Überschreiben der Member-Variablen SessionManager, SessionManager2, AudioClient, SessionEnumerator und SessionControl nicht ohne Gefahr. Dann haben wir erstmal ganz viel Quelltext, der weg kann. Weniger Quelltext -> weniger Fehler. |
AW: TAudioVolume Komponente incl. System Mixer
Zitat:
Aber wo du recht hast.. hast du recht. EDIT: Bringt nichts.. Aber egal denke es liegt an Win7 und der alten Version der AUDIOKSE.dll (Audio KS endpoint) oder was auch immer. gruss |
AW: TAudioVolume Komponente incl. System Mixer
Ein Nachtrag..
Zitat:
Nicht mit den vermehrten Aufrufen von Device.Activate(IID_IAudioSessionManager) die ich im übrigen entfernt habe sondern wegen deinem Deadlock funktioniert sie nicht. TThread.Synchronize du blocks meine Nachfolgenden GUI Threads die ich dann erstellen will\muss mit .wait. Also bei solchen dingen wäre es angebracht TThread.Queue zu verwenden. Ach was soll's funktioniert jetzt. vorher.. siehe shot nachher.. siehe shot Wenn ich aus OTTB heraus mein Virtual Piano starte werden zwei neue Controls addiert. Einmal "Over The Task Bar wenn nicht vorhanden" weil dieses beim klick auf das VPiano Icon Sound wiedergibt und dann das Piano selbst was beim Start ebenfalls Sound wiedergibt. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:36 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 by Thomas Breitkreuz