Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  17:19[Войти] | [Зарегистрироваться]
Ответ на вопрос № 80887

16-04-2012 12:02
Доброго времени суток.
Пытаюсь сделать программу, которая автоматически могла бы менять источник звука по умолчанию. Реализацию в Delphi я к сожалению не нашел, но нашел реализацию на VC++, ссылка на ресурс:
Код HTML:
http://eretik.omegahg.com/art/07.html
Пытаюсь перенести код из С++ на Delphi, но на последней функции застрял
Код моего проекта:
Код:

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,ActiveX,  OleServer, StdVCL,  MMSystem,ShlObj, StdCtrls;

const
  CLSID_MMDeviceEnumerator : TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';
  Class_PolicyConfigClient:TGUID ='{870af99c-171d-4f9e-af0d-e63df40c2bc9}';
  IID_IMMDeviceEnumerator : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
  IID_IMMDevice : TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';
  IID_IMMDeviceCollection : TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
  IID_IAudioEndpointVolume : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
  IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
  IID_IAudioEndpointVolumeCallback : TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';
  IID_IMMNotificationClient : TGUID = '{7991EEC9-7E89-4D85-8390-6C703CEC60C0}';
  IID_IPropertyStore: TGUID = '{886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}';

  DEVICE_STATE_ACTIVE = $00000001;
  DEVICE_STATE_UNPLUGGED = $00000002;
  DEVICE_STATE_NOTPRESENT = $00000004;
  DEVICE_STATEMASK_ALL = $00000007;

type
  EDataFlow = TOleEnum;

const
  eRender = $00000000;
  eCapture = $00000001;
  eAll = $00000002;
  EDataFlow_enum_count = $00000003;

type
  ERole = TOleEnum;

const
  eConsole = $00000000;
  eMultimedia = $00000001;
  eCommunications = $00000002;
  ERole_enum_count = $00000003;

type
  IAudioEndpointVolumeCallback = interface(IUnknown)
  [IID_IAudioEndpointVolumeCallback]
  end;

  IAudioEndpointVolume = interface(IUnknown)
  [IID_IAudioEndpointVolume]
  end;

  IAudioMeterInformation = interface(IUnknown)
  [IID_IAudioMeterInformation]
  end;

  IPropertyStore = interface(IUnknown)
  end;

  IMMDevice = interface(IUnknown)
  [IID_IMMDevice]
    function Activate(const refId: TGUID; dwClsCtx: DWORD; pActivationParams: PInteger; out pEndpointVolume: IAudioEndpointVolume): HRESULT; stdCall;
    function OpenPropertyStore(stgmAccess: DWORD; out ppProperties: IPropertyStore): HRESULT; stdcall;
    function GetId(out ppstrId: PWideChar): HRESULT; stdcall;
  end;

  IMMDeviceCollection = interface(IUnknown)
  [IID_IMMDeviceCollection]
    function GetCount(out pcDevices: UINT): HRESULT; stdcall;
    function Item(nDevice: UINT; out ppDevice: IMMDevice): HRESULT; stdcall;
  end;

  IMMNotificationClient = interface(IUnknown)
  [IID_IMMNotificationClient]
  end;

  IMMDeviceEnumerator = interface(IUnknown)
  [IID_IMMDeviceEnumerator]
    function EnumAudioEndpoints(dataFlow: EDataFlow; deviceState: SYSUINT; out DevCollection: IMMDeviceCollection): HRESULT; stdcall;
  end;


  IPolicyConfig = interface(IUnknown)
    ['{f8679f50-850a-41cf-9c72-430f290290c8}']
    function SetDefaultEndpoint (wszDeviceID:PWideChar; ERole:ERole):Hresult; stdcall;
  end;

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
var
AudioEndpoints:IMMDeviceEnumerator;
Collection:IMMDeviceCollection;
Device:IMMDevice;

Proper:IPropertyStore;

Id_Dev:PWideChar;

Def_Dev_Ch:IPolicyConfig;
begin
CoCreateInstance (CLSID_MMDeviceEnumerator,nil,CLSCTX_INPROC_SERVER,IID_IMMDeviceEnumerator,AudioEndpoints);
AudioEndpoints.EnumAudioEndpoints(eAll, DEVICE_STATE_ACTIVE, &Collection);

Collection.Item(0,Device);
Device.GetId(Id_Dev);

if Succeeded(CoCreateInstance (Class_PolicyConfigClient,nil,CLSCTX_INPROC_SERVER,IPolicyConfig,Def_Dev_Ch)) then
begin
if Succeeded(Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eMultimedia)) then
begin
  showmessage ('eMultimedia');
end;
end;
end;

end.



Дело в том, чот инициализация всех указателей происходит нормально, ID устройства (для примера выбираю первое) получаю верное, но при попытке выполнить Def_Dev_Ch.SetDefaultEndpoint(Id_De v,eMultimedia) появляется ошибка: raise exception class eaccessviolation with message 'Access violation at address 73a44fbb in module 'audioses.dll' Write of address 00000001', причем ошибка записи в память меняется в зависимости от роли, которую я указываю (при консольной роли ошибки не появляется, но я думаю что это из-за того, что eConsole = $00000000;, при роли eMultimedia запись 00000001, при eCommunications запись в адрес 00000002).
Прошу помочь мне с этой проблемой, объяснить где я накасячил.
Заранее огромное спасибо!

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

05-09-2012 11:08 | Сообщение от автора вопроса
Код моей тестовой программки для отображения и выбора устройства по умолчанию:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,ActiveX,  OleServer, StdVCL,  MMSystem,ShlObj, StdCtrls;

const
  CLSID_MMDeviceEnumerator : TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';
  Class_PolicyConfigClient:TGUID ='{870af99c-171d-4f9e-af0d-e63df40c2bc9}';
  IID_IMMDeviceEnumerator : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
  IID_IMMDevice : TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';
  IID_IMMDeviceCollection : TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
  IID_IAudioEndpointVolume : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
  IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
  IID_IAudioEndpointVolumeCallback : TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';
  IID_IMMNotificationClient : TGUID = '{7991EEC9-7E89-4D85-8390-6C703CEC60C0}';
  IID_IPropertyStore: TGUID = '{886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}';

  DEVICE_STATE_ACTIVE = $00000001;
  DEVICE_STATE_UNPLUGGED = $00000002;
  DEVICE_STATE_NOTPRESENT = $00000004;
  DEVICE_STATEMASK_ALL = $00000007;

type
  EDataFlow = TOleEnum;

const
  eRender = $00000000;
  eCapture = $00000001;
  eAll = $00000002;
  EDataFlow_enum_count = $00000003;

type
  ERole = TOleEnum;

const
  eConsole = $00000000;
  eMultimedia = $00000001;
  eCommunications = $00000002;
  ERole_enum_count = $00000003;

  PKEY_Device_FriendlyName:TPropertyKey=(fmtid:(D1:$a45c254e;D2:$df1c;D3:$4efd;D4:($80,$20,$67,$d1,$46,$a8,$50,$e0));pid:14);

type
  IAudioEndpointVolumeCallback = interface(IUnknown)
  [IID_IAudioEndpointVolumeCallback]
  end;

  IAudioEndpointVolume = interface(IUnknown)
  [IID_IAudioEndpointVolume]
  end;

  IAudioMeterInformation = interface(IUnknown)
  [IID_IAudioMeterInformation]
  end;

  IPropertyStore = interface(IUnknown)
  ['{886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}']
  function GetCount(out cProps: LongWord): HResult; stdcall;
    function GetAt(iProp: LongWord; out pkey: _tagpropertykey): HResult; stdcall;
    function GetValue(const key: TPropertyKey; out pv: TPROPVARIANT): HResult; stdcall;
    function SetValue(const key: TPropertyKey; out propvar: TPROPVARIANT): HResult; stdcall;
    function Commit: HResult; stdcall;
  end;

  IMMDevice = interface(IUnknown)
  [IID_IMMDevice]
    function Activate(const refId: TGUID; dwClsCtx: DWORD; pActivationParams: PInteger; out pEndpointVolume: IAudioEndpointVolume): HRESULT; stdCall;
    function OpenPropertyStore(stgmAccess: DWORD; out ppProperties: IPropertyStore): HRESULT; stdcall;
    function GetId(out ppstrId: PWideChar): HRESULT; stdcall;
  end;

  IMMDeviceCollection = interface(IUnknown)
  [IID_IMMDeviceCollection]
    function GetCount(out pcDevices: UINT): HRESULT; stdcall;
    function Item(nDevice: UINT; out ppDevice: IMMDevice): HRESULT; stdcall;
  end;

  IMMNotificationClient = interface(IUnknown)
  [IID_IMMNotificationClient]
  end;

  IMMDeviceEnumerator = interface(IUnknown)
  [IID_IMMDeviceEnumerator]
    function EnumAudioEndpoints(dataFlow: EDataFlow; deviceState: SYSUINT; out DevCollection: IMMDeviceCollection): HRESULT; stdcall;
  end;


  IPolicyConfig = interface(IUnknown)
    ['{f8679f50-850a-41cf-9c72-430f290290c8}']
    // не уверен в правильности параметров, но как заглушки работает
      function GetMixFormat(a: PWideChar; var b: TWAVEFORMATEX): HRESULT; // stdcall?
      function GetDeviceFormat(a: PWideChar; b: integer; var c: TWAVEFORMATEX): HRESULT; stdcall;
      function ResetDeviceFormat(a: PWideChar): HRESULT; stdcall;
      function SetDeviceFormat(a: PWideChar; var b: TWAVEFORMATEX; var c: TWAVEFORMATEX): HRESULT; stdcall;
      function GetProcessingPeriod(a: PWideChar; b: integer; c: PINT64; d: PINT64): HRESULT; stdcall;
      function SetProcessingPeriod(a: PWideChar; b: PINT64): HRESULT; stdcall;
      function GetShareMode(a: PWideChar; b: pointer{struct DeviceShareMode *}): HRESULT; stdcall;
      function SetShareMode(a: PWideChar; b: pointer{struct DeviceShareMode *}): HRESULT; stdcall;
      function GetPropertyValue(devID: PWideChar; const Key: _tagpropertykey; V: TPROPVARIANT): HRESULT; stdcall;
      function SetPropertyValue(devID: PWideChar; const Key: _tagpropertykey; V: TPROPVARIANT): HRESULT; stdcall;
// а вот и нужный метод
    function SetDefaultEndpoint(wszDeviceID: PWideChar; ARole: ERole):Hresult; stdcall;
  end;

type
  TForm1 = class(TForm)
    Button_Find_Sound: TButton;
    Button_Ch_Sound: TButton;
    ListBox_Sound: TListBox;
    Button1: TButton;
    procedure Button_Find_SoundClick(Sender: TObject);
    procedure Button_Ch_SoundClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button_Ch_SoundClick(Sender: TObject);
var
AudioEndpoints:IMMDeviceEnumerator;
Collection:IMMDeviceCollection;
Device:IMMDevice;
Def_Dev_Ch:IPolicyConfig;

Id_Dev:PWideChar;
ID_Dev_Def:WideString;
begin
CoCreateInstance (CLSID_MMDeviceEnumerator,nil,CLSCTX_INPROC_SERVER,IID_IMMDeviceEnumerator,AudioEndpoints);
AudioEndpoints.EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, Collection);

Collection.Item(ListBox_Sound.ItemIndex,Device);
Device.GetId(Id_Dev);

if Succeeded(CoCreateInstance (Class_PolicyConfigClient,nil,CLSCTX_INPROC_SERVER,IPolicyConfig,&Def_Dev_Ch)) then
begin

  if Succeeded(Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eConsole)) then
  begin
  //showmessage ('eConsole')
  end
  else begin
  showmessage (IntToStr(HResult (Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eConsole))));
  end;

  if Succeeded(Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eMultimedia)) then
  begin
  //showmessage ('eMultimedia')
  end
  else begin
  showmessage (IntToStr(HResult (Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eMultimedia))));
  end;

  if Succeeded(Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eCommunications)) then
  begin
  //showmessage ('eCommunications')
  end
  else begin
  showmessage (IntToStr(HResult (Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eCommunications))));
  end;
end;
end;

procedure TForm1.Button_Find_SoundClick(Sender: TObject);
var
AudioEndpoints:IMMDeviceEnumerator;
Collection:IMMDeviceCollection;
Device:IMMDevice;

Proper:IPropertyStore;

Id_Dev:PWideChar;


I:Integer;
Count_Dev:UINT;

DId:WideString;

Prop:IPropertyStore;

DeviceName:PROPVARIANT;

begin
ListBox_Sound.Items.Clear;

CoCreateInstance (CLSID_MMDeviceEnumerator,nil,CLSCTX_INPROC_SERVER,IID_IMMDeviceEnumerator,AudioEndpoints);
AudioEndpoints.EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &Collection);

Collection.GetCount(Count_Dev);

for I := 0 to Count_Dev-1 do
begin
Collection.Item(i,Device);
If Succeeded(Device.GetId(Id_Dev)) and (Id_Dev<>nil) then
begin
  DId:=Widestring(Id_Dev);

  Device.OpenPropertyStore(STGM_READ,Prop);
  Prop.GetValue(PKEY_Device_FriendlyName,DeviceName);



  CoTaskMemFree(Id_Dev);
  ListBox_Sound.Items.Append(DId+' '+PROPVARIANT(DeviceName).pwszVal);
end;
end;


end;

end.


С записывающими устройствами к сожалению не подскажу - у меня не было необходимости менять устройства по умолчанию для записи.

17-08-2012 12:01
а можно выложить весь рабочий код?
и еще интересует как сделать тоже самое но для записывающих устройств?

09-06-2012 02:19 | Сообщение от автора вопроса
TSX, icWasya Спасибо за советы. Все отлично получилось! :)
Еще раз благодарю за подсказки!

05-06-2012 14:27
Да, и еще по поводу IMMDevice.GetID()
получать его корректно так


var lpwStr: PWideChar;
  FID: wideString;
  ppDevice: IMMDevice;
...
FID := '';
if Succeeded(ppDevice.GetId(lpwStr)) and (lpwStr<>nil) then begin
  FID := wideString(lpwStr);
  // надо освободить память
  CoTaskMemFree(lpwStr);
end;


05-06-2012 14:16
В описании интерфейса IPolicyConfig перед методом SetDefaultEndpoint есть еще методы, надо их указать.
У меня заработало с таким определением IPolicyConfig:


type
  PCWSTR = PWideChar;

  IPolicyConfig = interface(IUnknown)
  ['{f8679f50-850a-41cf-9c72-430f290290c8}']
// не уверен в правильности параметров, но как заглушки работает
      function GetMixFormat(a: PCWSTR; var b: TWAVEFORMATEX): HRESULT; // stdcall?
      function GetDeviceFormat(a: PCWSTR; b: integer; var c: TWAVEFORMATEX): HRESULT; stdcall;
      function ResetDeviceFormat(a: PCWSTR): HRESULT; stdcall;
      function SetDeviceFormat(a: PCWSTR; var b: TWAVEFORMATEX; var c: TWAVEFORMATEX): HRESULT; stdcall;
      function GetProcessingPeriod(a: PCWSTR; b: integer; c: PINT64; d: PINT64): HRESULT; stdcall;
      function SetProcessingPeriod(a: PCWSTR; b: PINT64): HRESULT; stdcall;
      function GetShareMode(a: PCWSTR; b: pointer{struct DeviceShareMode *}): HRESULT; stdcall;
      function SetShareMode(a: PCWSTR; b: pointer{struct DeviceShareMode *}): HRESULT; stdcall;
      function GetPropertyValue(devID: PCWSTR; const Key: _tagpropertykey; V: tag_inner_PROPVARIANT): HRESULT; stdcall;
      function SetPropertyValue(devID: PCWSTR; const Key: _tagpropertykey; V: tag_inner_PROPVARIANT): HRESULT; stdcall;
// а вот и нужный метод
    function SetDefaultEndpoint(wszDeviceID: PCWSTR; ARole: ERole):Hresult; stdcall;
  end;


ибо, насколько я помню, интерфейс - это VMT и порядок методов имеет значение.

17-04-2012 05:09 | Сообщение от автора вопроса
При попытке получить Id устройста через строчку Device.GetId(Id_Dev), если в функции поменять тип возвращаемого параметра с PWideChar на WideString с изменением типа переменной Id_Dev, переменная становится Inaccessible value :(
Поэтому функцию GetId оставил в PWideChar, а потом значение передавал в переменную с типом WideString, но так все равно не работает :(

17-04-2012 03:39 | Вопрос к автору: запрос дополнительной информации
ну а здесь
function GetId(out ppstrId: PWideChar): HRESULT; stdcall;

17-04-2012 02:49 | Сообщение от автора вопроса
Извиняюсь, взял старый листинг.

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,ActiveX,  OleServer, StdVCL,  MMSystem,ShlObj, StdCtrls;

const
  CLSID_MMDeviceEnumerator : TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';
  IID_IMMDeviceEnumerator : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
  IID_IMMDevice : TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';
  IID_IMMDeviceCollection : TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
  IID_IAudioEndpointVolume : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
  IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
  IID_IAudioEndpointVolumeCallback : TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';
  IID_IMMNotificationClient : TGUID = '{7991EEC9-7E89-4D85-8390-6C703CEC60C0}';
  IID_IPropertyStore: TGUID = '{886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}';

  CLSID_PolicyConfigClient:TGUID ='{870af99c-171d-4f9e-af0d-e63df40c2bc9}';
  IID_IPolicyConfig : TGUID ='{f8679f50-850a-41cf-9c72-430f290290c8}';

  //CLSID_PolicyConfigClient:TGUID ='{294935CE-F637-4E7C-A41B-AB255460B862}';
  //IID_IPolicyConfig : TGUID ='{568b9108-44bf-40b4-9006-86afe5b5a620}';

  DEVICE_STATE_ACTIVE = $00000001;
  DEVICE_STATE_UNPLUGGED = $00000002;
  DEVICE_STATE_NOTPRESENT = $00000004;
  DEVICE_STATEMASK_ALL = $00000007;

type
  EDataFlow = TOleEnum;

const
  eRender = $00000000;
  eCapture = $00000001;
  eAll = $00000002;
  EDataFlow_enum_count = $00000003;

type
  ERole = TOleEnum;

const
  eConsole = $00000000;
  eMultimedia = $00000001;
  eCommunications = $00000002;
  ERole_enum_count = $00000003;

type
  IAudioEndpointVolumeCallback = interface(IUnknown)
  [IID_IAudioEndpointVolumeCallback]
  end;

  IAudioEndpointVolume = interface(IUnknown)
  [IID_IAudioEndpointVolume]
  end;

  IAudioMeterInformation = interface(IUnknown)
  [IID_IAudioMeterInformation]
  end;

  IPropertyStore = interface(IUnknown)
  end;

  IMMDevice = interface(IUnknown)
  [IID_IMMDevice]
    function Activate(const refId: TGUID; dwClsCtx: DWORD; pActivationParams: PInteger; out pEndpointVolume: IAudioEndpointVolume): HRESULT; stdCall;
    function OpenPropertyStore(stgmAccess: DWORD; out ppProperties: IPropertyStore): HRESULT; stdcall;
    function GetId(out ppstrId: PWideChar): HRESULT; stdcall;
  end;

  IMMDeviceCollection = interface(IUnknown)
  [IID_IMMDeviceCollection]
    function GetCount(out pcDevices: UINT): HRESULT; stdcall;
    function Item(nDevice: UINT; out ppDevice: IMMDevice): HRESULT; stdcall;
  end;

  IMMNotificationClient = interface(IUnknown)
  [IID_IMMNotificationClient]
  end;

  IMMDeviceEnumerator = interface(IUnknown)
  [IID_IMMDeviceEnumerator]
    function EnumAudioEndpoints(dataFlow: EDataFlow; deviceState: SYSUINT; out DevCollection: IMMDeviceCollection): HRESULT; stdcall;
  end;


  IPolicyConfig = interface(IUnknown)
    [IID_IPolicyConfig]
    function SetDefaultEndpoint (wszDeviceID:WideString; ERole:ERole):Hresult; stdcall;
  end;

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
var
AudioEndpoints:IMMDeviceEnumerator;
Collection:IMMDeviceCollection;
Device:IMMDevice;
Def_Dev_Ch:IPolicyConfig;

Id_Dev:PWideChar;
ID_Dev_Def:WideString;

begin
CoCreateInstance (CLSID_MMDeviceEnumerator,nil,CLSCTX_INPROC_SERVER,IID_IMMDeviceEnumerator,AudioEndpoints);
AudioEndpoints.EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, Collection);

Collection.Item(1,Device);
Device.GetId(Id_Dev);

ID_Dev_Def:=Id_Dev;

if Succeeded(CoCreateInstance (CLSID_PolicyConfigClient,nil,CLSCTX_INPROC_SERVER,IID_IPolicyConfig,&Def_Dev_Ch)) then
begin

  if Succeeded(Def_Dev_Ch.SetDefaultEndpoint(ID_Dev_Def,eConsole)) then
  begin
  showmessage ('eConsole')
  end
  else begin
  showmessage (IntToStr(HResult (Def_Dev_Ch.SetDefaultEndpoint(ID_Dev_Def,eConsole))));
  end;

  if Succeeded(Def_Dev_Ch.SetDefaultEndpoint(ID_Dev_Def,eMultimedia)) then
  begin
  showmessage ('eMultimedia')
  end
  else begin
  showmessage (IntToStr(HResult (Def_Dev_Ch.SetDefaultEndpoint(ID_Dev_Def,eMultimedia))));
  end;

  if Succeeded(Def_Dev_Ch.SetDefaultEndpoint(ID_Dev_Def,eCommunications)) then
  begin
  showmessage ('eCommunications')
  end
  else begin
  showmessage (IntToStr(HResult (Def_Dev_Ch.SetDefaultEndpoint(ID_Dev_Def,eCommunications)));
  end;
end;
end;

end.


17-04-2012 02:44 | Сообщение от автора вопроса
Добрый день еще раз. Спасибо за ответ. Попробовал сделать как Вы посоветовали, ошибка та же :(
Может быть я опять что-нибудь неверно сделал, я товичек в использовании недокментированных функций, да и в использовании API, если не сказать больше.
Немного подправил код:

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,ActiveX,  OleServer, StdVCL,  MMSystem,ShlObj, StdCtrls;

const
  CLSID_MMDeviceEnumerator : TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';
  IID_IMMDeviceEnumerator : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
  IID_IMMDevice : TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';
  IID_IMMDeviceCollection : TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
  IID_IAudioEndpointVolume : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
  IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
  IID_IAudioEndpointVolumeCallback : TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';
  IID_IMMNotificationClient : TGUID = '{7991EEC9-7E89-4D85-8390-6C703CEC60C0}';
  IID_IPropertyStore: TGUID = '{886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}';

  CLSID_PolicyConfigClient:TGUID ='{870af99c-171d-4f9e-af0d-e63df40c2bc9}';
  IID_IPolicyConfig : TGUID ='{f8679f50-850a-41cf-9c72-430f290290c8}';

  //CLSID_PolicyConfigClient:TGUID ='{294935CE-F637-4E7C-A41B-AB255460B862}';
  //IID_IPolicyConfig : TGUID ='{568b9108-44bf-40b4-9006-86afe5b5a620}';

  DEVICE_STATE_ACTIVE = $00000001;
  DEVICE_STATE_UNPLUGGED = $00000002;
  DEVICE_STATE_NOTPRESENT = $00000004;
  DEVICE_STATEMASK_ALL = $00000007;

type
  EDataFlow = TOleEnum;

const
  eRender = $00000000;
  eCapture = $00000001;
  eAll = $00000002;
  EDataFlow_enum_count = $00000003;

type
  ERole = TOleEnum;

const
  eConsole = $00000000;
  eMultimedia = $00000001;
  eCommunications = $00000002;
  ERole_enum_count = $00000003;

type
  IAudioEndpointVolumeCallback = interface(IUnknown)
  [IID_IAudioEndpointVolumeCallback]
  end;

  IAudioEndpointVolume = interface(IUnknown)
  [IID_IAudioEndpointVolume]
  end;

  IAudioMeterInformation = interface(IUnknown)
  [IID_IAudioMeterInformation]
  end;

  IPropertyStore = interface(IUnknown)
  end;

  IMMDevice = interface(IUnknown)
  [IID_IMMDevice]
    function Activate(const refId: TGUID; dwClsCtx: DWORD; pActivationParams: PInteger; out pEndpointVolume: IAudioEndpointVolume): HRESULT; stdCall;
    function OpenPropertyStore(stgmAccess: DWORD; out ppProperties: IPropertyStore): HRESULT; stdcall;
    function GetId(out ppstrId: PWideChar): HRESULT; stdcall;
  end;

  IMMDeviceCollection = interface(IUnknown)
  [IID_IMMDeviceCollection]
    function GetCount(out pcDevices: UINT): HRESULT; stdcall;
    function Item(nDevice: UINT; out ppDevice: IMMDevice): HRESULT; stdcall;
  end;

  IMMNotificationClient = interface(IUnknown)
  [IID_IMMNotificationClient]
  end;

  IMMDeviceEnumerator = interface(IUnknown)
  [IID_IMMDeviceEnumerator]
    function EnumAudioEndpoints(dataFlow: EDataFlow; deviceState: SYSUINT; out DevCollection: IMMDeviceCollection): HRESULT; stdcall;
  end;


  IPolicyConfig = interface(IUnknown)
    [IID_IPolicyConfig]
    function SetDefaultEndpoint (wszDeviceID:WideString; ERole:ERole):Hresult; stdcall;
  end;

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
var
AudioEndpoints:IMMDeviceEnumerator;
Collection:IMMDeviceCollection;
Device:IMMDevice;
Def_Dev_Ch:IPolicyConfig;

Id_Dev:PWideChar;
ID_Dev_Def:WideString;

begin
CoCreateInstance (CLSID_MMDeviceEnumerator,nil,CLSCTX_INPROC_SERVER,IID_IMMDeviceEnumerator,AudioEndpoints);
AudioEndpoints.EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, Collection);

Collection.Item(1,Device);
Device.GetId(Id_Dev);

ID_Dev_Def:=Id_Dev;

if Succeeded(CoCreateInstance (CLSID_PolicyConfigClient,nil,CLSCTX_INPROC_SERVER,IID_IPolicyConfig,&Def_Dev_Ch)) then
begin

  if Succeeded(Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eConsole)) then
  begin
  showmessage ('eConsole')
  end
  else begin
  showmessage (IntToStr(HResult (Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eConsole))));
  end;

  if Succeeded(Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eMultimedia)) then
  begin
  showmessage ('eMultimedia')
  end
  else begin
  showmessage (IntToStr(HResult (Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eConsole))));
  end;

  if Succeeded(Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eCommunications)) then
  begin
  showmessage ('eCommunications')
  end
  else begin
  showmessage (IntToStr(HResult (Def_Dev_Ch.SetDefaultEndpoint(Id_Dev,eConsole))));
  end;
end;
end;

end.


Если выбираю другой класс и другой интерфейс (CLSID_PolicyConfigClient:TGUID ='{294935CE-F637-4E7C-A41B-AB255460B862}'; IID_IPolicyConfig : TGUID ='{568b9108-44bf-40b4-9006-86afe5b5a620}';),который описан на сайте и в VC++ программе, то программа отрабатывает без ошибок, но не меняет звуковое устройство "по умолчанию". Может я еще что то пропустил?
Заранее спасибо :)

17-04-2012 00:42
Сдаётся мне, что вместо PWideChar надо использовать WideString. В COM-протоколе это обычная практика. И в сишных текстах написано PCWSTR, а не PWSTR

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Раз дощечка, два дощечка будет лесенка. Раз словечко, два словечко, будет ЧТО?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования