-
Доброго времени суток, уважаемые мастера! Пытаюсь воспользоваться методом 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 = '';
...
ISpVoice = interface(ISpEventSource)
['']
...
function Speak(pwcs: PWideChar; dwFlags: LongWord; out pulStreamNumber: LongWord): HResult; stdcall;
...
end;
Что я делаю неправильно?
-
> Что я делаю неправильно?
Не тот интерфейс используешь.
Нужно использовать ISpeechVoice
-
Что через ISpeechVoice всё работает нормально я и сам доагадался, раскурив исходники класса TSpVoice. Но тем не менее всё равно не понятно, почему при работе через ISpVoice возникает такая ошибка. По идее работаю через него с тем же COM-объектом - SpVoice. Метод вызываю правильно. А ошибка всё равно вываливается.
-
> раскурив исходники класса TSpVoice
Плохо курил. Или не то.
Прочувствуй разницу:
ISpVoice = interface(ISpEventSource)
ISpeechVoice = interface(IDispatch)
-
> OleCheck(Voice.Speak('Say It', SVSFlagsAsync, V));
а чему равно V?
-
> чему равно V?
А по барабану чему равно. Вызов-то привел к отказу)
-
> Прочувствуй разницу: > > ISpVoice = interface(ISpEventSource) > > ISpeechVoice = interface(IDispatch)
Всё равно не могу понять, какую роль в данном случае играют предки этих интерфейсов. Тем более, что свои методы Speak ISpVoice и ISpeechVoice не наследуют от них. Если не трудно, объясните "для тех, кто в танке" :)
-
-
> SPERR_INVALID_FLAGS
Проблема в том, что возникающая ошибка - не SPERR_INVALID_FLAGS. Код возникающей ошибки - -2147024809 (или 80070057, если в hex-формате). Если я ничего не напутал, то это E_INVALIDARG. И все мои метания сводятся к тому, чтобы понять, какой же параметр при вызове метода Speak я задал неверно. Учитывая, что при вызове ISpeechVoice.Speak с той же строкой и тем же флагом всё работает, склоняюсь к мысли, что дело в последнем аргументе. Но что в нём не так сообразить никак не могу. По идее это out-аргумент. Поэтому дело в его значении быть не может. Оно просто не учитывается при вызове Speak. Тип соответствует объявлению ISpVoice.Speak. Так какого спрашивается ему ещё нужно?
-
> склоняюсь к мысли, что дело в последнем аргументе
Похоже так оно и есть.
> какого спрашивается ему ещё нужно?
Мне не понятно, что тебя так заклинило на ISpVoice ? Это событийный интерфейс !
-
А раз событийный, то использование его в приведенном тобой контексте скорей всего как раз и является ошибочным, о чем тебе и сообщает объект возбуждением исключения.
-
Однако в MSDN ISpVoice позиционируется как основной интерфейс для преобразования текста в речь. А встроенный в него событийный механизм согласно MSDN предназначен для обеспечения в случае необходимости обратной связи в ходе преобразования. Поэтому ошибочности его использования в данном контексте не вижу.
-
> в MSDN ISpVoice позиционируется как основной интерфейс
Не знаю как он там позиционируется, но компонент-раппер, созданный при импорте этой библ-ки типов, использует в кач-ве основного именно ISpeechVoice.
-
'Say it' в с случае с Voice := CreateComObject(CLASS_SpVoice) as ISpVoice; Voice.Speak('Say it', SPF_ASYNC, V); должен быть типа PWideChar
|