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

📄 advoip.pas

📁 测试用例
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    DisconnectTheCall;
  end;
end;

procedure TApdCustomVoIP.DoStatusEvent(TapiEvent, Status, SubStatus : Word);
  { generate the OnStatus event }
begin
  FEventLog.AddLogString(True, 'DoStatusEvent (TapiEvent=' +
    IntToStr(TapiEvent) + ', Status=' + IntToStr(Status) +
    ', SubStatus=' + IntToStr(SubStatus) + ')');
  if Assigned(FOnStatus) then begin
    FOnStatus(Self, TapiEvent, Status, SubStatus);
  end;
end;

function TApdCustomVoIP.EnablePreviewWindow(pAddress: ITAddress;
  pStream: ITStream): HRESULT;
  { hook up the preview dynamic terminal }
var
  pTerminal : ITTerminal;
begin
  Result := GetVideoRenderTerminal(pAddress, pTerminal);
  if Result = S_OK then
    pStream.SelectTerminal(pTerminal);
end;

function TApdCustomVoIP.FindTerminal(DevName: string;
  MediaType: TOleEnum; MediaDir: TOleEnum;
  var ppTerminal: ITTerminal): HRESULT;
  { searches the collection for the selected terminal }
var
  pTerminalSupport : ITTerminalSupport;
  pTerminal : ITTerminal;
  pTermEnum : IEnumTerminal;
  Fetched : DWORD;
begin
  Result := S_FALSE;

  pTerminalSupport := (gpAddress as ITTerminalSupport);

  pTermEnum := pTerminalSupport.EnumerateStaticTerminals;
  if pTermEnum <> nil then begin
    while pTermEnum.Next(1, pTerminal, Fetched) = S_OK do begin
      { got a terminal, see if it is the one that was selected }
      if (pTerminal.Name = DevName) and (pTerminal.Get_MediaType = Integer(MediaType))
        and (pTerminal.Get_Direction = MediaDir) then begin
          Result := S_OK;
          ppTerminal := pTerminal;
          Exit;
        end;
    end;
  end;
end;

function TApdCustomVoIP.FindTheAddress: HRESULT;
var
  pEnumAddress : IEnumAddress;
  pAddress : ITAddress;
  Fetched : DWORD;
  lMediaTypes : TOleEnum;
begin
  { enumerate the addresses }
  pEnumAddress := gpTapi.EnumerateAddresses;
  if pEnumAddress = nil then begin
    Result := E_INVALIDARG;
    Exit;
  end;
  Result := S_OK;
  {for each address found}
  while Result in [S_OK, S_FALSE] do begin
    Result := pEnumAddress.Next(1, pAddress, Fetched);

    if pAddress = nil then
      {at end of address enumerations}
      Break;

    { we only support H.323 }
    {if pAddress.AddressName = 'H323 Line' then begin}                   {!!.01}
    if UpperCase(pAddress.ServiceProviderName) = 'H323.TSP' then begin   {!!.01}
      gpAddress := pAddress;
      { register for event notifications }
      lMediaTypes := TAPIMEDIATYPE_AUDIO;
      if FEnableVideo and not((FVideoInDevice = '') or
        (FVideoInDevice = ApdNoTerminalName)) then
        if AddressSupportsMediaType(pAddress, TAPIMEDIATYPE_VIDEO) then
          lMediaTypes := lMediaTypes or TAPIMEDIATYPE_Video;
      NotifyRegister := gpTapi.RegisterCallNotifications(pAddress,
        True, True, lMediaTypes, gulAdvise);
      { found the address, we can exit now }
      Result := S_OK;                                                    {!!.01}
      Exit;                                                              {!!.01}
    end;
  end;
  { if we got here, we didn't find our address }
  Result := S_FALSE;                                                     {!!.01}
  {if Result = S_FALSE then}                                             {!!.01}
    {Result := S_OK;}                                                    {!!.01}
end;

function TApdCustomVoIP.GetCallInfo: TApdVoIPCallInfo;
  { return the ITCallInfo interface for the call }
var
  pCallInfo : ITCallInfo;
  Res : Integer;

  { using nested functions to trap exceptions if the requested info is }
  { not available }
  function CallInfoString(CallInfoString: CALLINFO_STRING) : WideString;
  begin
    Result := '';
    try
      Result := pCallInfo.Get_CallInfoString(CallInfoString);
    except
      { not available, just eat the exception and move on }
    end;
  end;

  function CallInfoLong(CallInfoLong: CALLINFO_LONG): Integer;
  begin
    Result := 0;
    try
      Result := pCallInfo.Get_CallInfoLong(CallInfoLong);
    except
      { not available, just eat the exception }
    end;
  end;
begin
  if not FVoIPAvailable then
    raise EVoIPNotSupported.CreateUnknown(sVoIPNotAvailable, 0);
  { NOTE: not all of these fields are available for all TAPI3 instances   }
  {       the docs are a bit unclear why, it may be security related      }
  {       if it's not available, an exception is raised, which we'll trap }
  Res := gpCall.QueryInterface(IID_ITCallInfo, pCallInfo);
  if Res = S_OK then begin
    Result.InfoAvailable := True;
    { string types }
    Result.CallerIDName := CallInfoString(CIS_CALLERIDNAME);
    Result.CallerIDNumber := CallInfoString(CIS_CALLERIDNUMBER);
    Result.CalledIDName := CallInfoString(CIS_CALLEDIDNAME);
    Result.CalledIDNumber := CallInfoString(CIS_CALLEDIDNUMBER);
    Result.ConnectedIDName := CallInfoString(CIS_CONNECTEDIDNAME);
    Result.ConnectedIDNumber := CallInfoString(CIS_CONNECTEDIDNUMBER);
    Result.CalledPartyFriendlyName := CallInfoString(CIS_CALLEDPARTYFRIENDLYNAME);
    Result.Comment := CallInfoString(CIS_COMMENT);
    Result.DisplayableAddress := CallInfoString(CIS_DISPLAYABLEADDRESS);
    Result.CallingPartyID := CallInfoString(CIS_CALLINGPARTYID);
    { DWORD types }
    Result.MediaTypesAvailable := CallInfoLong(CIL_MEDIATYPESAVAILABLE);
    Result.CallerIDAddressType := CallInfoLong(CIL_CALLERIDADDRESSTYPE);
    Result.CalledIDAddressType := CallInfoLong(CIL_CALLEDIDADDRESSTYPE);
    Result.ConnectedIDAddressType := CallInfoLong(CIL_CONNECTEDIDADDRESSTYPE);
    Result.Origin := CallInfoLong(CIL_ORIGIN);
    Result.Reason := CallInfoLong(CIL_REASON);
    Result.MinRate := CallInfoLong(CIL_MINRATE);
    Result.MaxRate := CallInfoLong(CIL_MAXRATE);
    Result.Rate := CallInfoLong(CIL_RATE);
  end else
    Result.InfoAvailable := False;
end;

function TApdCustomVoIP.GetCallInfoInterface: ITCallInfo;
  { ITCallInfo is described in the TAPI3 MSDN documentation, available at:   }
  { http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tapi/int_itfo_8acv.asp }
  { this page seems to move around a lot, search for ITCallInfo from the     }
  { MSDN home page http://msdn.microsoft.com/default.asp for the latest info }
begin
  if not FVoIPAvailable then
    raise EVoIPNotSupported.CreateUnknown(sVoIPNotAvailable, 0);

  { if the interface is not available, the result will be nil }
  if gpCall = nil then
    Result := nil
  else
    gpCall.QueryInterface(IID_ITCallInfo, Result);
end;

function TApdCustomVoIP.GetTerminal(pAddress: ITAddress; pStream: ITStream;
  var ppTerminal: ITTerminal): HRESULT;
  { hook up the terminals for audio/video input/output }
var
  lMediaType : TOleEnum;
  dir : TOleEnum;
  pTerminalSupport : ITTerminalSupport;
begin
  lMediaType := pStream.get_MediaType;
  dir := pStream.get_Direction;

  { video render is handled differently (it's a dynamic terminal) }
  if FEnableVideo and IsVideoRenderStream(pStream) then begin
    Result := GetVideoRenderTerminal(pAddress, ppTerminal);
    Exit;
  end;

  { NOTE: we do not currently support selecting the specific static terminal }
  {   if the property is an empty string or '<none>' then we won't hook the  }
  {   terminal to the stream, otherwise we'll select the default terminal.   }

  { audio and video capture terminals are static }
  Result := pAddress.QueryInterface(IID_ITTerminalSupport, pTerminalSupport);
  if Result = S_OK then begin
    if IsAudioCaptureStream(pStream) then begin
      { select the audio capture terminal (microphone) }
      if (AudioInDevice = '') or (AudioInDevice = ApdNoTerminalName) then begin
        { don't select a terminal }
      end else if (AudioInDevice = ApdDefaultTerminalName) then begin
        { select the default terminal }
        ppTerminal := pTerminalSupport.GetDefaultStaticTerminal(lMediaType, dir)
      end else begin
        { try to find the selected terminal from the collection }
        FindTerminal(AudioInDevice, TAPIMEDIATYPE_AUDIO, TD_CAPTURE, ppTerminal);
      end;
    end else if IsAudioRenderStream(pStream) then begin
      { select the audio render terminal (speakers) }
      if (AudioOutDevice = '') or (AudioOutDevice = ApdNoTerminalName) then begin
        { don't select a terminal }
      end else if (AudioOutDevice = ApdDefaultTerminalName) then begin
        { select the default terminal }
        ppTerminal := pTerminalSupport.GetDefaultStaticTerminal(lMediaType, dir)
      end else begin
        { try to find the selected terminal from the collection }
        FindTerminal(AudioInDevice, TAPIMEDIATYPE_AUDIO, TD_RENDER, ppTerminal);
      end;
    end else if IsVideoCaptureStream(pStream) then begin
      { TAPI3 only allows the default video capture (local camera) to be selected }
      if (FVideoInDevice = '') or (FVideoInDevice = ApdNoTerminalName) then begin
        { don't select the terminal }
      end else begin
        ppTerminal := pTerminalSupport.GetDefaultStaticTerminal(lMediaType, dir);
      end;
    end;
  end;
end;

function TApdCustomVoIP.GetVideoRenderTerminal(pAddress: ITAddress;
  var ppTerminal: ITTerminal): HRESULT;
  { find the video render terminal (displays video locally) }
var
  pTerminalSupport : ITTerminalSupport;
begin
  Result := pAddress.QueryInterface(IID_ITTerminalSupport, pTerminalSupport);
  if Result = S_OK then
    ppTerminal := pTerminalSupport.CreateTerminal(
                                  GuidToString(CLSID_VideoWindowTerm),
                                  TAPIMEDIATYPE_VIDEO, TD_RENDER);
end;

function TApdCustomVoIP.GetVideoRenderTerminalFromStream(
  pCallMediaEvent: ITCallMediaEvent; var ppTerminal: ITTerminal;
  var pfRenderStream: Boolean): HRESULT;
  { hook the incoming video (or preview) stream to our window }
var
  pStream : ITStream;
  lMediaType : TOleEnum;
  pEnumTerminal : IEnumTerminal;
  Fetched : DWORD;
begin
  { get the stream for this event }
  pStream := pCallMediaEvent.get_Stream;
  if pStream = nil then begin
    Result := E_FAIL;
    Exit;
  end;

  { See if it's a video stream }
  lMediaType := pStream.get_MediaType;
  if lMediaType <> TAPIMEDIATYPE_VIDEO then begin
    Result := E_FAIL;
    Exit;
  end;

  { See if it's a render stream }
  pfRenderStream := pStream.get_Direction = TD_RENDER;

  { enumerate the terminals }
  pStream.EnumerateTerminals(pEnumTerminal);
  if pEnumTerminal = nil then begin
    Result := E_FAIL;
    Exit;
  end;

  { search for the first video render terminal }
  while pEnumTerminal.Next(1, ppTerminal, Fetched) = S_OK do begin
    if ppTerminal.Get_Direction = TD_RENDER then begin
      Result := S_OK;
      Exit;
    end;
  end;
  Result := E_FAIL;
end;

procedure TApdCustomVoIP.HostWindow(pVideoWindow: IVideoWindow;
  IsRenderStream: Boolean);
  { set up the preview/render terminals }
var
  Width, Height : Integer;
begin
  if IsRenderStream then begin
    if FEnableVideo and (FVideoOutWindow <> nil)then begin
      pVideoWindow.put_Owner(FVideoOutWindow.Handle);
      pVideoWindow.put_WindowStyle(WS_CHILDWINDOW or WS_BORDER);
      pVideoWindow.get_Width(Width);   { width of the incoming stream }
      pVideoWindow.get_Height(Height); { height of the incoming stream }
      if FVideoOutWindowAutoSize then begin
        pVideoWindow.SetWindowPosition(1, 1, Width, Height);
        FVideoOutWindow.Width := Width + 2;
        FVideoOutWindow.Height := Height + 2;
      end else
        pVideoWindow.SetWindowPosition(1, 1, FVideoOutWindow.Width - 2,
          FVideoOutWindow.Height - 2);

      pVideoWindow.put_Visible(True);
    end else if FEnableVideo then begin
      { create popup window }
      pVideoWindow.put_AutoShow(True);
      pVideoWindow.put_Visible(True);
    end;
  end else begin
    if FEnablePreview and (FPreviewWindow <> nil)then begin
      pVideoWindow.put_Owner(FPreviewWindow.Handle);
      pVideoWindow.put_WindowStyle(WS_CHILDWINDOW or WS_BORDER);
      pVideoWindow.get_Width(Width);   { width of the incoming stream }
      pVideoWindow.get_Height(Height); { height of the incoming stream }
      if FPreviewWindowAutoSize then begin
        pVideoWindow.SetWindowPosition(1, 1, Width, Height);
        FPreviewWindow.Width := Width + 2;
        FPreviewWindow.Height := Height + 2;
      end else
        pVideoWindow.SetWindowPosition(1, 1, FPreviewWindow.Width - 2,
          FPreviewWindow.Height - 2);

      pVideoWindow.put_Visible(True);
    end else if FEnablePreview then begin
      { create popup window }
      pVideoWindow.put_AutoShow(True);
      pVideoWindow.put_Visible(True);

⌨️ 快捷键说明

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