⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmdsedtr.pas

📁 一套及时通讯的原码
💻 PAS
字号:
{========================================================================}
{=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
{========================================================================}
{=                          All Rights Reserved                         =}
{========================================================================}
{=  D 01099 Dresden             = Fax.: +49 (0)351-8037944              =}
{=  Loewenstr.7a                = info@swiftsoft.de                     =}
{========================================================================}
{=  Actual versions on http://www.swiftsoft.de/mmtools.html             =}
{========================================================================}
{=  This code is for reference purposes only and may not be copied or   =}
{=  distributed in any format electronic or otherwise except one copy   =}
{=  for backup purposes.                                                =}
{=                                                                      =}
{=  No Delphi Component Kit or Component individually or in a collection=}
{=  subclassed or otherwise from the code in this unit, or associated   =}
{=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
{=  without express permission from SwiftSoft.                          =}
{=                                                                      =}
{=  For more licence informations please refer to the associated        =}
{=  HelpFile.                                                           =}
{========================================================================}
{=  $Date: 11.08.98 - 14:40:29 $                                        =}
{========================================================================}
unit MMDSEdtr;

{$I COMPILER.INC}

interface

uses
    Windows,
    SysUtils,
    Classes,
    Dialogs,
    MMDSETyp,
    MMUtils,
    MMDSMix,
    MMObj;

type
  {-- TMMDSEditor --------------------------------------------------------------}
  TMMDSEditor   = class(TMMNonVisualComponent)
  private
    FObj        : TComponent;
    FBDummy     : Boolean;

    function    GetAvailable: Boolean;
  public
    function    Execute: Boolean;
  published
    property    EditObject: TComponent read FObj write FObj;
    property    Available: Boolean read GetAvailable write FBDummy;
  end;

  EMMDSEditor   = class(Exception);

var
    DSEDCreateScene         : function(var Scene: THandle): Boolean; stdcall = nil;
    DSEDSetMixerParams      : function(Scene: THandle; const Params: TMMDSEDMixerParams): Boolean; stdcall;
    DSEDSetListenerParams   : function(Scene: THandle; const Params: TMMDSEDListenerParams): Boolean; stdcall;
    DSEDGetMixerParams      : function(Scene: THandle; var Params: TMMDSEDMixerParams): Boolean; stdcall;
    DSEDGetListenerParams   : function(Scene: THandle; var Params: TMMDSEDListenerParams): Boolean; stdcall;
    DSEDSetBufferParams     : function(Scene: THandle; Index: Integer; const Params: TMMDSEDBufferParams): Boolean; stdcall;
    DSEDSetSourceParams     : function(Scene: THandle; Index: Integer; const Params: TMMDSEDSourceParams): Boolean; stdcall;
    DSEDGetBufferParams     : function(Scene: THandle; Index: Integer; var Params: TMMDSEDBufferParams): Boolean; stdcall;
    DSEDGetSourceParams     : function(Scene: THandle; Index: Integer; var Params: TMMDSEDSourceParams): Boolean; stdcall;
    DSEDSetSourceWave       : function(Scene: THandle; Index: Integer; const WaveData: TMMDSEDWaveRecord): Boolean; stdcall;
    DSEDSetObjectName       : function(Scene: THandle; Index: Integer; Name: PChar): Boolean; stdcall = nil;
    DSEDSetFocusIndex       : function(Scene: THandle; Index: Integer): Boolean; stdcall = nil;
    DSEDAddSource           : function(Scene: THandle; var Index: Integer): Boolean; stdcall = nil;
    DSEDDestroyScene        : function(Scene: THandle): Boolean; stdcall = nil;
    DSEDEditScene           : function(Scene: THandle; var Modified: Boolean): Boolean; stdcall = nil;
    DSEDGetLastError        : function: Integer; stdcall = nil;
    // User is responsible to keep a copy of returned string
    DSEDGetLastErrorMessage : function: PChar; stdcall = nil;

function DSEDIsAvailable: Boolean;
function EditMixer(Mixer: TMMDSWaveMixer): Boolean;
function EditChannel(Channel: TMMDSMixChannel): Boolean;

implementation

uses
{$IFDEF BUILD_ACTIVEX}
    ActiveX, ComObj, MMTypesX2_TLB, AxCtrlsUtil,
{$ENDIF}
    TypInfo;

const
    DLLName     = 'MMDSEDTR.DLL';

var
    Handle      : THandle = 0;
    Loaded      : Boolean = False;
    ErrorMode   : DWORD;

function DSEDIsAvailable: Boolean;
begin
    Result := Loaded;
end;

procedure DSEDCheck(Result: Boolean);
begin
    if not Result then
        raise EMMDSEditor.Create(DSEDGetLastErrorMessage);
end;

{$IFDEF BUILD_ACTIVEX}
  function BuildChannelList(Mixer: TMMDSWaveMixer): TList;
  var
    ControlX, C: TMMActiveXControl;
    Dispatcher: TMMDispatcher;
    MMControl: IMMControl;
    ControlCP: IConnectionPoint;
    Enum: IEnumConnections;
    ConnectData: TConnectData;
    Fetched: Integer;
    Control: TMMDSMixChannel;
    Index: Integer;
  begin
    Result := TList.Create;
    try
      ControlX := MMActiveXControls.ControlsByDelphiControl[Mixer];
      Dispatcher := MMActiveXControls.DispatcherOfControl(ControlX);
      for Index := Dispatcher.List.Count-1 downto 0 do
      begin
        C := TMMActiveXControl(Dispatcher.List[Index]);
        if (InheritsFromEx(C.Control, TMMDSMixChannel)) and
           (TMMDSMixChannel(C.Control).Mixer = Mixer) then
        begin
          Result.Add(Control);
        end;
      end;
    except
      Result.Clear
    end;
  end;

  {// Newer MMTypesX stuff
  function BuildChannelList(Mixer: TMMDSWaveMixer): TList;
  var
    MMControl: IMMControl;
    Dispatcher: IMMDispatcher;
    ControlCP: IConnectionPoint;
    Enum: IEnumConnections;
    ConnectData: TConnectData;
    Fetched: Integer;
    Control: TMMDSMixChannel;
  begin
    Result := TList.Create;
    try
      MMControl := DelphiControlToAxControl(Mixer);
      if Assigned(MMControl) then
      begin
        MMControl.GetDispatcher(Dispatcher);
        OleCheck((Dispatcher as IConnectionPointContainer).
          FindConnectionPoint(IMMControl, ControlCP));
        OleCheck(ControlCP.EnumConnections(Enum));
        while Enum.Next(1, ConnectData, @Fetched) = S_OK do
        begin
          Control := Pointer((ConnectData.pUnk as IMMControl).DelphiControl);
          ConnectData.pUnk := nil;
          if (InheritsFromEx(Control, TMMDSMixChannel)) and
             (Control.Mixer = Mixer) then
            Result.Add(Control);
        end;
      end;
    except
      Result.Clear
    end;
  end;
}
{$ELSE}
  function BuildChannelList(Mixer: TMMDSWaveMixer): TList;
  var
    i: Integer;
    C: TMMDSMixChannel;
  begin
    Result := TList.Create;
    try
      for i := 0 to Mixer.Owner.ComponentCount - 1 do
        if Mixer.Owner.Components[i] is TMMDSMixChannel then
        begin
          C := Mixer.Owner.Components[i] as TMMDSMixChannel;
          if C.Mixer = Mixer then
            Result.Add(C);
        end;
    except
      Result.Clear
    end;
  end;
{$ENDIF}

function ShowEditor(Obj: TMMDSWaveMixer; Focus: TComponent): Boolean;

    function BuildScene(Mixer: TMMDSWaveMixer): THandle;
    var
        MixP    : TMMDSEDMixerParams;
        ListP   : TMMDSEDListenerParams;
        WavR    : TMMDSEDWaveRecord;
        BufP    : TMMDSEDBufferParams;
        SrcP    : TMMDSEDSourceParams;
        i       : Integer;
        C       : TMMDSMixChannel;
        Index   : Integer;
        List    : TList;
    begin
        MMDSEDRecordFromMixer(Mixer,MixP);
        MMDSEDRecordFromListener(Mixer,ListP);
        try
            DSEDCheck(DSEDCreateScene(Result));
            DSEDCheck(DSEDSetMixerParams(Result,MixP));
            DSEDCheck(DSEDSetListenerParams(Result,ListP));
            DSEDCheck(DSEDSetObjectName(Result,0,PChar(Mixer.Name)));

            List := BuildChannelList(Mixer);
            try
              for i := 0 to List.Count-1 do
              begin
                C := TMMDSMixChannel(List[i]);

                MMDSEDRecordFromBuffer(C,BufP);
                MMDSEDRecordFromSource(C,SrcP);
                DSEDCheck(DSEDAddSource(Result,Index));
                DSEDCheck(DSEDSetBufferParams(Result,Index,BufP));
                DSEDCheck(DSEDSetSourceParams(Result,Index,SrcP));

                WavR := MMDSEDCreateWaveRecord(C.Wave);
                try
                    DSEDCheck(DSEDSetSourceWave(Result,Index,WavR));
                finally
                    MMDSEDFreeWaveRecord(WavR);
                end;

                DSEDCheck(DSEDSetObjectName(Result,Index,PChar(C.Name)));

                if C = Focus then
                    DSEDCheck(DSEDSetFocusIndex(Result,Index));
              end;
            finally
              List.Free
            end;

        except
            DSEDDestroyScene(Result);
            raise;
        end;
    end;

    function EditScene(Scene: THandle): Boolean;
    begin
        DSEDCheck(DSEDEditScene(Scene, Result));
    end;

    procedure DestroyScene(Scene: THandle);
    begin
        DSEDCheck(DSEDDestroyScene(Scene));
    end;

    procedure CollectParams(Scene: THandle; Mixer: TMMDSWaveMixer);
    var
      ListP   : TMMDSEDListenerParams;
      SrcP    : TMMDSEDSourceParams;
      i       : Integer;
      C       : TMMDSMixChannel;
      Index   : Integer;
      List    : TList;
    begin
      DSEDCheck(DSEDGetListenerParams(Scene,ListP));
      MMDSEDListenerFromRecord(Mixer,ListP);

      Index := 1;
      List := BuildChannelList(Mixer);
      try
        for i := 0 to List.Count-1 do
        begin
          C := TMMDSMixChannel(List[i]);
          DSEDCheck(DSEDGetSourceParams(Scene,Index,SrcP));
          Inc(Index);
          MMDSEDSourceFromRecord(C, SrcP);
        end;
      finally
        List.Free
      end;
    end;

var
   Scene: THandle;

begin
    Scene := BuildScene(Obj);
    try
        Result := EditScene(Scene);
        if Result then
            CollectParams(Scene,Obj);
    finally
        DestroyScene(Scene);
    end;
end;

function EditMixer(Mixer: TMMDSWaveMixer): Boolean;
begin
   Result := ShowEditor(Mixer,Mixer);
end;

function EditChannel(Channel: TMMDSMixChannel): Boolean;
begin
   if Channel.Mixer <> nil then
      Result := ShowEditor(Channel.Mixer,Channel)
   else
      raise EMMDSEditor.Create('Channel should be connected to mixer');
end;

{== TMMDSEditor ==============================================================}
function TMMDSEditor.GetAvailable: Boolean;
begin
    Result := DSEDIsAvailable;
end;

{-- TMMDSEditor --------------------------------------------------------------}
function TMMDSEditor.Execute: Boolean;
begin
    Result := False;

    if FObj = nil then
        Exit;

    if not Available then
        { TODO: string to resource }
        raise EMMDSEditor.Create('MMDSEdtr.DLL not loaded');

    if InheritsFromEx(FObj, TMMDSWaveMixer) then
       Result := EditMixer(TMMDSWaveMixer(FObj))
    else
       Result := EditChannel(TMMDSMixChannel(FObj));
end;

function GetAddress(Proc: PChar): TFarProc;
begin
    Result := GetProcAddress(Handle,Proc);
    if Result = nil then
        Loaded := False;
end;

initialization

    ErrorMode := SetErrorMode(SEM_NOOPENFILEERRORBOX);
    try

        Handle := LoadLibrary(DLLName);

        if Handle <> 0 then
        begin
            @DSEDCreateScene            := GetAddress('DSEDCreateScene');
            @DSEDSetMixerParams         := GetAddress('DSEDSetMixerParams');
            @DSEDSetListenerParams      := GetAddress('DSEDSetListenerParams');
            @DSEDGetMixerParams         := GetAddress('DSEDGetMixerParams');
            @DSEDGetListenerParams      := GetAddress('DSEDGetListenerParams');
            @DSEDSetBufferParams        := GetAddress('DSEDSetBufferParams');
            @DSEDSetSourceParams        := GetAddress('DSEDSetSourceParams');
            @DSEDGetBufferParams        := GetAddress('DSEDGetBufferParams');
            @DSEDGetSourceParams        := GetAddress('DSEDGetSourceParams');
            @DSEDSetSourceWave          := GetAddress('DSEDSetSourceWave');
            @DSEDSetObjectName          := GetAddress('DSEDSetObjectName');
            @DSEDSetFocusIndex          := GetAddress('DSEDSetFocusIndex');
            @DSEDAddSource              := GetAddress('DSEDAddSource');
            @DSEDDestroyScene           := GetAddress('DSEDDestroyScene');
            @DSEDEditScene              := GetAddress('DSEDEditScene');
            @DSEDGetLastError           := GetAddress('DSEDGetLastError');
            @DSEDGetLastErrorMessage    := GetAddress('DSEDGetLastErrorMessage');

            Loaded := True;
        end;

    finally
        SetErrorMode(ErrorMode);
    end;

finalization
    if Handle <> 0 then FreeLibrary(Handle);
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -