Конференция "Corba" » Проблемы при работе с SAPI [Delphi, Windows]
 
  • FunkyByte (24.10.07 22:20) [0]
    Доброго времени суток, уважаемые мастера!
    Пытаюсь воспользоваться методом Speak COM-объекта класса SpVoice через интерфейс ISpVoice:
    procedure TForm1.Button1Click(Sender: TObject);
    var
     Voice: ISpVoice;
     V: LongWord;
    begin
     Voice := CreateComObject(CLASS_SpVoice) as ISpVoice;
     OleCheck(Voice.Speak('Say It', SVSFlagsAsync, V));
    end;


    Проблема в том, что при выполнении данного кода возникает ошибка с сообщением 'Параметр задан неверно'.
    Ниже привожу объявления констант и метода Speak интерфейса ISpVoice (всё это получено при импортировании библиотеки типов Microsoft Speech Object Library):

    SVSFlagsAsync = $00000001;
    ...
    CLASS_SpVoice: TGUID = '{96749377-3391-11D2-9EE3-00C04F797396}';
    ...
    ISpVoice = interface(ISpEventSource)
     ['{6C44DF74-72B9-4992-A1EC-EF996E0422D4}']
     ...
       function Speak(pwcs: PWideChar; dwFlags: LongWord; out pulStreamNumber: LongWord): HResult; stdcall;
     ...
    end;


    Что я делаю неправильно?
  • Сергей М. © (25.10.07 09:57) [1]

    > Что я делаю неправильно?


    Не тот интерфейс используешь.

    Нужно использовать ISpeechVoice
  • FunkyByte (25.10.07 15:17) [2]
    Что через ISpeechVoice всё работает нормально я и сам доагадался, раскурив исходники класса TSpVoice. Но тем не менее всё равно не понятно, почему при работе через ISpVoice возникает такая ошибка. По идее работаю через него с тем же COM-объектом - SpVoice. Метод вызываю правильно. А ошибка всё равно вываливается.
  • Сергей М. © (25.10.07 15:54) [3]

    > раскурив исходники класса TSpVoice


    Плохо курил. Или не то.

    Прочувствуй разницу:

    ISpVoice = interface(ISpEventSource)

    ISpeechVoice = interface(IDispatch)
  • umbra © (26.10.07 16:16) [4]

    >  OleCheck(Voice.Speak('Say It', SVSFlagsAsync, V));

    а чему равно V?
  • Сергей М. © (26.10.07 17:03) [5]

    > чему равно V?


    А по барабану чему равно.
    Вызов-то привел к отказу)
  • FunkyByte (28.10.07 20:11) [6]

    > Прочувствуй разницу:
    >
    > ISpVoice = interface(ISpEventSource)
    >
    > ISpeechVoice = interface(IDispatch)

    Всё равно не могу понять, какую роль в данном случае играют предки этих интерфейсов. Тем более, что свои методы Speak ISpVoice и ISpeechVoice не наследуют от них. Если не трудно, объясните "для тех, кто в танке" :)
  • Сергей М. © (29.10.07 11:32) [7]

    > для тех, кто в танке


    http://msdn2.microsoft.com/en-us/library/ms717848.aspx


    > 'Параметр задан неверно'.


    Цитата оттуда же:

    SPERR_INVALID_FLAGS  Invalid flags specified for this operation.
  • FunkyByte (29.10.07 22:23) [8]

    > SPERR_INVALID_FLAGS

    Проблема в том, что возникающая ошибка - не SPERR_INVALID_FLAGS. Код возникающей ошибки - -2147024809 (или 80070057, если в hex-формате). Если я ничего не напутал, то это E_INVALIDARG. И все мои метания сводятся к тому, чтобы понять, какой же параметр при вызове метода Speak я задал неверно. Учитывая, что при вызове ISpeechVoice.Speak с той же строкой и тем же флагом всё работает, склоняюсь к мысли, что дело в последнем аргументе. Но что в нём не так сообразить никак не могу. По идее это out-аргумент. Поэтому дело в его значении быть не может. Оно просто не учитывается при вызове Speak. Тип соответствует объявлению ISpVoice.Speak. Так какого спрашивается ему ещё нужно?
  • Сергей М. © (30.10.07 08:31) [9]

    > склоняюсь к мысли, что дело в последнем аргументе


    Похоже так оно и есть.


    > какого спрашивается ему ещё нужно?


    Мне не понятно, что тебя так заклинило на ISpVoice ?
    Это событийный интерфейс !
  • Сергей М. © (30.10.07 08:33) [10]
    А раз событийный, то использование его в приведенном тобой контексте скорей всего как раз и является ошибочным, о чем тебе и сообщает объект возбуждением исключения.
  • FunkyByte (30.10.07 15:32) [11]
    Однако в MSDN ISpVoice позиционируется как основной интерфейс для преобразования текста в речь. А встроенный в него событийный механизм согласно MSDN предназначен для обеспечения в случае необходимости обратной связи в ходе преобразования. Поэтому ошибочности его использования в данном контексте не вижу.
  • Сергей М. © (30.10.07 16:17) [12]

    > в MSDN ISpVoice позиционируется как основной интерфейс


    Не знаю как он там позиционируется, но компонент-раппер, созданный при импорте этой библ-ки типов, использует в кач-ве основного именно ISpeechVoice.
  • keyo (30.11.07 13:51) [13]
    'Say it'  
    в с случае с
    Voice := CreateComObject(CLASS_SpVoice) as ISpVoice;
     Voice.Speak('Say it', SPF_ASYNC, V);
    должен быть типа PWideChar
 
Конференция "Corba" » Проблемы при работе с SAPI [Delphi, Windows]
Есть новые Нет новых   [120350   +20][b:0][p:0.001]