Delphi-PRAXiS
Seite 5 von 21   « Erste     345 6715     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   TAudioVolume Komponente incl. System Mixer (https://www.delphipraxis.net/196270-taudiovolume-komponente-incl-system-mixer.html)

TiGü 8. Mai 2018 10:06

AW: TAudioVolume Komponente incl. System Mixer
 
Wenn man Windows-Funktionen nachbaut, dann kommt man nicht drum herum für die verschiedenen Windows-Versionen entsprechende Pfade zu bauen.

Delphi-Quellcode:
if WindowsVersionAnnoDazumal then
...
else if WindowsVersionEtwasNeuer then
...
else
...
end.
Aber ich weiß schon was du als nächstes schreiben wirst:
Zitat:

"Ich nutze aber Windows 7 und will kein Windows 10 und werde es auch nicht unterstützen. Macht doch was ihr wollt! Ich bin raus! LOL!

gruss"

Dalai 8. Mai 2018 17:41

AW: TAudioVolume Komponente incl. System Mixer
 
Zitat:

Zitat von EWeiss (Beitrag 1401658)
Du kannst aber sehn das man sich auf die DLL und die Ordinal Nummer nicht verlassen kann.

Lad die Ressource doch einfach mit ihrem Namen - in dem Fall 3010 - und gib der Funktion zum Laden der Ressource die passenden Flags mit, so dass das Icon mit den richtigen Dimensionen und Farbtiefe geladen wird.

Grüße
Dalai

EWeiss 8. Mai 2018 18:29

AW: TAudioVolume Komponente incl. System Mixer
 
Zitat:

Zitat von Dalai (Beitrag 1401697)
Zitat:

Zitat von EWeiss (Beitrag 1401658)
Du kannst aber sehn das man sich auf die DLL und die Ordinal Nummer nicht verlassen kann.

Lad die Ressource doch einfach mit ihrem Namen - in dem Fall 3010 - und gib der Funktion zum Laden der Ressource die passenden Flags mit, so dass das Icon mit den richtigen Dimensionen und Farbtiefe geladen wird.

Grüße
Dalai

Hast du mal hier geschaut?
https://www.delphipraxis.net/1401628-post31.html

Kannst du ein Icon sehen?
Wenn ja dann ist das Problem schon 12 Beiträge vorher erledigt gewesen. :)

Delphi-Quellcode:
function TAudioVolume.SetSysItemIcon(wsItems: PWideChar): TIcon;
var
  fi: TSHFileInfoW;
begin
  Result := nil;

  ZeroMemory(@fi, SizeOf(TSHFileInfo));
  if SHGetFileInfoW(PWideChar(wsItems), 0, fi, SizeOf(TSHFileInfo),
    SHGFI_DISPLAYNAME Or SHGFI_SYSICONINDEX or SHGFI_LARGEICON or SHGFI_ICON) <> 0 then
  begin
    Icon := TIcon.Create;
    Icon.Handle := fi.HICON;
    Result := Icon;
  end;

end;
Delphi-Quellcode:
var
  WinDir: array [0..MAX_PATH] of WideChar;
//...
    FillChar(WinDir, sizeof(WinDir), 0);
    GetWindowsDirectory(WinDir, MAX_PATH);
    MasterImg.Picture.Icon := SetSysItemIcon(PWideChar(WinDir + '\System32\SndVol.exe'));

Oh.. danke
Zitat:

"Ich nutze aber Windows 7 und will kein Windows 10 und werde es auch nicht unterstützen. Macht doch was ihr wollt! Ich bin raus! LOL!

gruss"
Ich bekomme es schon vorgeschrieben.
Tigü mein Hasi.. Nehme mir bitte nicht so viel Arbeit ab, habe dann ja nichts mehr zu tun ;)

Zitat:

dann kommt man nicht drum herum
Doch in dem man die entsprechende API verwendet.
Es zwingt mich niemand das Icon über die Ordinal Nummer zu laden das geht auch anders.

gruss

EWeiss 8. Mai 2018 23:23

AW: TAudioVolume Komponente incl. System Mixer
 
Neue Version nur Master Icon addiert.
Mache jetzt erst mal pause mit dem Kram wegen den Event Problemen.
Hier ein Beispiel!
Delphi-Quellcode:
unit AudioSessionNotification;

interface

uses
  Windows, Messages, Classes, AudioSessionControl, Constants;

type
   IAudioSessionNotification = interface(IUnknown)
  ['{641DD20B-4D41-49CC-ABA3-174B9477BB08}']
    function OnSessionCreated(const NewSession: IAudioSessionControl): HResult; stdcall;
  end;

  TAudioSessionNotification = class(TInterfacedObject, IAudioSessionNotification)
  private
    MsgHandle: HWND;
  public
    function OnSessionCreated(const NewSession: IAudioSessionControl): HResult; stdcall;
    procedure SetMsgHandle(WinHandle: HWND);
  end;

implementation

{ TSessionNotification }

function TAudioSessionNotification.OnSessionCreated(const NewSession: IAudioSessionControl): HResult;
begin
  PostMessage(MsgHandle, WM_SessionCreate, integer(@NewSession), 0);

  Result := S_OK;
end;

procedure TAudioSessionNotification.SetMsgHandle(WinHandle: HWND);
begin

  MsgHandle := WinHandle;
end;

end.
Ich erstelle das Event.
Delphi-Quellcode:
TAudioVolume.Create..
var
  ISessionNotification: TAudioSessionNotification;
//...
// SessionNotification
ISessionNotification := TAudioSessionNotification.Create;
ISessionNotification.SetMsgHandle(FEventHandle);
SessionNotification := ISessionNotification;
Dann registriere ich das Notification
Delphi-Quellcode:
// Register TAudioSessionNotification to receive a notification when a session is created.
HR := SessionManager2.RegisterSessionNotification(SessionNotification);
if HR <> S_OK then
  raise Exception.Create('Error : Unable to Register Session Notification');
Jetzt sollte hier wenn eine neue Session erstellt wird außerhalb der Anwendung
Delphi-Quellcode:
function TAudioSessionNotification.OnSessionCreated(const NewSession: IAudioSessionControl): HResult;
begin
  PostMessage(MsgHandle, WM_SessionCreate, integer(@NewSession), 0);

  Result := S_OK;
end;
Das Event feuern tut es aber nicht auch das nicht OnSessionDisconnected.
Das war nur zur Info.

Ihr habt den Source also tobt euch aus.

gruss

TiGü 9. Mai 2018 09:39

AW: TAudioVolume Komponente incl. System Mixer
 
Diese Zeilen bedürfen einen Überarbeitung:

Delphi-Quellcode:
procedure TAudioVolume.WMSize(var Message: TWMSize);
var
  WinDir: array [0..MAX_PATH] of WideChar;
begin
...
    FillChar(WinDir, sizeof(WinDir), 0);
    GetWindowsDirectory(WinDir, MAX_PATH);
    MasterImg.Picture.Icon := SetSysItemIcon(PWideChar(WinDir + '\System32\SndVol.exe'));
Bei jedem Resize (und das sind bis zum ersten Zeigen des Formulars schon sechs) wird ein Icon erstellt. Das vorige wird aber nie freigegeben -> Speicherleck.
Das Ermitteln des Windows Directory und das Setzen des Icons brauchst du ja nicht bei jedem Resize machen.
Schiebe das und die Erzeugung von MasterImg in
Delphi-Quellcode:
procedure TAudioVolume.SetMasterComponents;
.

TiGü 9. Mai 2018 10:01

AW: TAudioVolume Komponente incl. System Mixer
 
Hm...die anderen Icons von den Anwendungen leaken auch...versuch mal, ob du das schöner hinkriegst.

TiGü 9. Mai 2018 10:24

AW: TAudioVolume Komponente incl. System Mixer
 
Delphi-Quellcode:
function TAudioSessionNotification.OnSessionCreated(const NewSession: IAudioSessionControl): HResult;
begin
  PostMessage(MsgHandle, WM_SessionCreate, integer(@NewSession), 0);

  Result := S_OK;
end;
Wie sag ich das jetzt? Es ist etwas suboptimal! :shock:
Du möchtest ein Interface per PostMessage weiterversenden. Erster Fehler ist das Casten des Pointers auf Integer.
Außerdem wird dadurch der Referenzzählung durcheinander gebracht. Sobald OnSessionCreated durchlaufen wird, ist die Instanz nicht mehr sicher da.
Das müsste eigentlich für angemeldete FOnSessionCreated-Eventhandler knallen.

Zumindest tut es das bei mir, wenn man einen Eventhandler anmeldet und auf die NewSession-Instanz zugreifen will:
Delphi-Quellcode:
procedure TForm1.AudioVolume1SessionCreated(NewSession: IAudioSessionControl);
var
  pRetVal: uint;
begin
  NewSession.GetState(pRetVal);
end;
Dann knallt es in System.pas
Delphi-Quellcode:
procedure _IntfAddRef(const Dest: IInterface);
begin
  if Dest <> nil then Dest._AddRef;
end;
Die Überlegung mit den PostMessage, um asynchron zu arbeiten und reagieren zu können ist problemlos für ordinale Typen (Byte, Integer, Cardinal...) umsetzbar, aber mit Interface-Instanzen kommst du in Teufelsküche.

Hast du mal überlegt die IAudioSessionEvents, IMMNotificationClient, IAudioSessionNotification und IAudioEndpointVolumeCallback in TAudioVolume zu integrieren?
Das wäre einfacher als so Zwischenklassen, die nichts weiter tun, als die Informationen per PostMessage weiterzuversenden. Weniger Quelltext würde sich dadurch auch ergeben.
Wenn man aus einen anderen Thread-Context als den Mainthread befeuert wird, muss man natürlich synchronisieren.

EWeiss 9. Mai 2018 18:17

AW: TAudioVolume Komponente incl. System Mixer
 
Delphi-Quellcode:
function TAudioSessionNotification.OnSessionCreated(const NewSession: IAudioSessionControl): HResult;


Habe hier noch gar keine Fehler bezüglich des Pointers feststellen(debuggen) können weil das Event nie ausgelöst wird.
Zitat:

Die Überlegung mit den PostMessage, um asynchron zu arbeiten und reagieren zu können ist problemlos für ordinale Typen (Byte, Integer, Cardinal...) umsetzbar, aber mit Interface-Instanzen kommst du in Teufelsküche.
Werde dem Nachgehen sobald ich eine Lösung dafür gefunden habe das dieses Event auch ausgelöst wird.
Wie ich schon sagte trotz Registrierung, Initialisierung funktioniert es nicht.

Zitat:

Diese Zeilen bedürfen einen Überarbeitung:
Jo ein

Delphi-Quellcode:
    if not Assigned(MasterImg) then
    begin
      MasterImg := TImage.Create(FMGroupBox);
      MasterImg.AutoSize := true;
      MasterImg.Parent := FMGroupBox;

      FillChar(WinDir, sizeof(WinDir), 0);
      GetWindowsDirectory(WinDir, MAX_PATH);
      MasterImg.Picture.Icon := SetSysItemIcon(PWideChar(WinDir + '\System32\SndVol.exe'));
      if Assigned(MasterImg.Picture.Icon) then
      begin
        MasterImg.Left := (ClientWidth - Icon.Width) div 2;
        MasterImg.Top := 5;
        MasterImg.Show;
      end else
      FreeAndNil(MasterImg);
    end;
sollte reichen.

Zitat:

Das vorige wird aber nie freigegeben -> Speicherleck.
im Destroy.
Delphi-Quellcode:
if Assigned(MasterImg) then
  FreeAndNil(MasterImg);
Zitat:

Zumindest tut es das bei mir, wenn man einen Eventhandler anmeldet und auf die NewSession-Instanz zugreifen will:
Delphi-Quellcode:
procedure TForm1.AudioVolume1SessionCreated(NewSession: IAudioSessionControl);



Sorry das muss knallen.
1. SessionCreated wird nie aufgerufen daran kann es also nicht liegen.
2. Du erstellst ein Event für eine Session was eigentlich nichts mit den\der Session zu tun hat.
AudioVolume1 ist das HauptVolumen (Lautsprecher) und hat nix mit den Session zu tun. Aber du weist ihm ein SessionCreated zu :shock:

Deine Zuweisung ist korrekt ein Denkfehler meinerseits.

gruss

TiGü 9. Mai 2018 19:05

AW: TAudioVolume Komponente incl. System Mixer
 
Habe den Quelltext jetzt nicht vor mir, aber ich habe in dem Beispielformular den oben genannten Eventhändler definiert und jeder tempSessionDingsbums an OnSessionCreated rangetackert. Bei neuen Programm mit Audioausgabe, z.B. FooBar2000, wurde das Event mehrfach ausgelöst. Also der Teil wo das Postmessage machst.

EWeiss 9. Mai 2018 19:12

AW: TAudioVolume Komponente incl. System Mixer
 
Zitat:

Zitat von TiGü (Beitrag 1401742)
Habe den Quelltext jetzt nicht vor mir, aber ich habe in dem Beispielformular den oben genannten Eventhändler definiert und jeder tempSessionDingsbums an OnSessionCreated rangetackert. Bei neuen Programm mit Audioausgabe, z.B. FooBar2000, wurde das Event mehrfach ausgelöst. Also der Teil wo das Postmessage machst.

OK dann habe ich einen Denkfehler.
Muss dann wohl über AudioVolume1 doch das Event initialisieren.
Bin da wohl selbst über den Session und MasterVolumen Kram gestolpert. :wall::duck:

Trotzdem bekomme ich kein Event..
Kann es sein das dieses nur von Anwendungen ausgelöst wird die das Interface auch unterstützen?
Denn wenn ich einen meiner Player starte passiert da gar nichts. Der Mixer selbst erkennt ihn aber und addiert ihn als Session.

Delphi-Quellcode:
{ TSessionNotification }

function TAudioSessionNotification.OnSessionCreated(const NewSession: IAudioSessionControl): HResult;
begin
  PostMessage(MsgHandle, WM_SessionCreate, integer(@NewSession), 0);

  Result := S_OK;
end;
Hier passiert nix.

Danke..

Zitat:

Hast du mal überlegt die IAudioSessionEvents, IMMNotificationClient, IAudioSessionNotification und IAudioEndpointVolumeCallback in TAudioVolume zu integrieren?
Mir ist jetzt nicht ganz klar wie du das bewerkstelligen würdest.
Bin mit dem VCL Kram nicht gerade sehr bewandert.
Zitat:


Zitat:

Hm...die anderen Icons von den Anwendungen leaken auch...versuch mal, ob du das schöner hinkriegst.

Mache ich.. Danke

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:19 Uhr.
Seite 5 von 21   « Erste     345 6715     Letzte »    

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