2 * Speech API (SAPI) text-to-speech implementation.
4 * Copyright 2019 Jactry Zeng for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wine/debug.h"
33 #include "sapi_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(sapi
);
39 ISpeechVoice ISpeechVoice_iface
;
40 ISpVoice ISpVoice_iface
;
41 IConnectionPointContainer IConnectionPointContainer_iface
;
45 static inline struct speech_voice
*impl_from_ISpeechVoice(ISpeechVoice
*iface
)
47 return CONTAINING_RECORD(iface
, struct speech_voice
, ISpeechVoice_iface
);
50 static inline struct speech_voice
*impl_from_ISpVoice(ISpVoice
*iface
)
52 return CONTAINING_RECORD(iface
, struct speech_voice
, ISpVoice_iface
);
55 static inline struct speech_voice
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
57 return CONTAINING_RECORD(iface
, struct speech_voice
, IConnectionPointContainer_iface
);
60 /* ISpeechVoice interface */
61 static HRESULT WINAPI
speech_voice_QueryInterface(ISpeechVoice
*iface
, REFIID iid
, void **obj
)
63 struct speech_voice
*This
= impl_from_ISpeechVoice(iface
);
65 TRACE("(%p, %s %p).\n", iface
, debugstr_guid(iid
), obj
);
67 if (IsEqualIID(iid
, &IID_IUnknown
) ||
68 IsEqualIID(iid
, &IID_IDispatch
) ||
69 IsEqualIID(iid
, &IID_ISpeechVoice
))
70 *obj
= &This
->ISpeechVoice_iface
;
71 else if (IsEqualIID(iid
, &IID_ISpVoice
))
72 *obj
= &This
->ISpVoice_iface
;
73 else if (IsEqualIID(iid
, &IID_IConnectionPointContainer
))
74 *obj
= &This
->IConnectionPointContainer_iface
;
78 FIXME("interface %s not implemented.\n", debugstr_guid(iid
));
82 IUnknown_AddRef((IUnknown
*)*obj
);
86 static ULONG WINAPI
speech_voice_AddRef(ISpeechVoice
*iface
)
88 struct speech_voice
*This
= impl_from_ISpeechVoice(iface
);
89 ULONG ref
= InterlockedIncrement(&This
->ref
);
91 TRACE("(%p): ref=%u.\n", iface
, ref
);
96 static ULONG WINAPI
speech_voice_Release(ISpeechVoice
*iface
)
98 struct speech_voice
*This
= impl_from_ISpeechVoice(iface
);
99 ULONG ref
= InterlockedDecrement(&This
->ref
);
101 TRACE("(%p): ref=%u.\n", iface
, ref
);
111 static HRESULT WINAPI
speech_voice_GetTypeInfoCount(ISpeechVoice
*iface
, UINT
*info
)
113 FIXME("(%p, %p): stub.\n", iface
, info
);
118 static HRESULT WINAPI
speech_voice_GetTypeInfo(ISpeechVoice
*iface
, UINT info
, LCID lcid
,
119 ITypeInfo
**type_info
)
121 FIXME("(%p, %u, %u, %p): stub.\n", iface
, info
, lcid
, type_info
);
126 static HRESULT WINAPI
speech_voice_GetIDsOfNames(ISpeechVoice
*iface
, REFIID riid
, LPOLESTR
*names
,
127 UINT count
, LCID lcid
, DISPID
*dispid
)
129 FIXME("(%p, %s, %p, %u, %u, %p): stub.\n", iface
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
134 static HRESULT WINAPI
speech_voice_Invoke(ISpeechVoice
*iface
, DISPID dispid
, REFIID riid
, LCID lcid
,
135 WORD flags
, DISPPARAMS
*params
, VARIANT
*result
,
136 EXCEPINFO
*excepinfo
, UINT
*argerr
)
138 FIXME("(%p, %d, %s, %#x, %#x, %p, %p, %p, %p): stub.\n", iface
, dispid
, debugstr_guid(riid
),
139 lcid
, flags
, params
, result
, excepinfo
, argerr
);
144 static HRESULT WINAPI
speech_voice_get_Status(ISpeechVoice
*iface
, ISpeechVoiceStatus
**status
)
146 FIXME("(%p, %p): stub.\n", iface
, status
);
151 static HRESULT WINAPI
speech_voice_get_Voice(ISpeechVoice
*iface
, ISpeechObjectToken
**voice
)
153 FIXME("(%p, %p): stub.\n", iface
, voice
);
158 static HRESULT WINAPI
speech_voice_putref_Voice(ISpeechVoice
*iface
, ISpeechObjectToken
*voice
)
160 FIXME("(%p, %p): stub.\n", iface
, voice
);
165 static HRESULT WINAPI
speech_voice_get_AudioOutput(ISpeechVoice
*iface
, ISpeechObjectToken
**output
)
167 FIXME("(%p, %p): stub.\n", iface
, output
);
172 static HRESULT WINAPI
speech_voice_putref_AudioOutput(ISpeechVoice
*iface
, ISpeechObjectToken
*output
)
174 FIXME("(%p, %p): stub.\n", iface
, output
);
179 static HRESULT WINAPI
speech_voice_get_AudioOutputStream(ISpeechVoice
*iface
, ISpeechBaseStream
**output
)
181 FIXME("(%p, %p): stub.\n", iface
, output
);
186 static HRESULT WINAPI
speech_voice_putref_AudioOutputStream(ISpeechVoice
*iface
, ISpeechBaseStream
*output
)
188 FIXME("(%p, %p): stub.\n", iface
, output
);
193 static HRESULT WINAPI
speech_voice_get_Rate(ISpeechVoice
*iface
, LONG
*rate
)
195 FIXME("(%p, %p): stub.\n", iface
, rate
);
200 static HRESULT WINAPI
speech_voice_put_Rate(ISpeechVoice
*iface
, LONG rate
)
202 FIXME("(%p, %d): stub.\n", iface
, rate
);
207 static HRESULT WINAPI
speech_voice_get_Volume(ISpeechVoice
*iface
, LONG
*volume
)
209 FIXME("(%p, %p): stub.\n", iface
, volume
);
214 static HRESULT WINAPI
speech_voice_put_Volume(ISpeechVoice
*iface
, LONG volume
)
216 FIXME("(%p, %d): stub.\n", iface
, volume
);
221 static HRESULT WINAPI
speech_voice_put_AllowAudioOutputFormatChangesOnNextSet(ISpeechVoice
*iface
,
224 FIXME("(%p, %d): stub.\n", iface
, allow
);
229 static HRESULT WINAPI
speech_voice_get_AllowAudioOutputFormatChangesOnNextSet(ISpeechVoice
*iface
, VARIANT_BOOL
*allow
)
231 FIXME("(%p, %p): stub.\n", iface
, allow
);
236 static HRESULT WINAPI
speech_voice_get_EventInterests(ISpeechVoice
*iface
, SpeechVoiceEvents
*flags
)
238 FIXME("(%p, %p): stub.\n", iface
, flags
);
243 static HRESULT WINAPI
speech_voice_put_EventInterests(ISpeechVoice
*iface
, SpeechVoiceEvents flags
)
245 FIXME("(%p, %#x): stub.\n", iface
, flags
);
250 static HRESULT WINAPI
speech_voice_put_Priority(ISpeechVoice
*iface
, SpeechVoicePriority priority
)
252 FIXME("(%p, %d): stub.\n", iface
, priority
);
257 static HRESULT WINAPI
speech_voice_get_Priority(ISpeechVoice
*iface
, SpeechVoicePriority
*priority
)
259 FIXME("(%p, %p): stub.\n", iface
, priority
);
264 static HRESULT WINAPI
speech_voice_put_AlertBoundary(ISpeechVoice
*iface
, SpeechVoiceEvents boundary
)
266 FIXME("(%p, %#x): stub.\n", iface
, boundary
);
271 static HRESULT WINAPI
speech_voice_get_AlertBoundary(ISpeechVoice
*iface
, SpeechVoiceEvents
*boundary
)
273 FIXME("(%p, %p): stub.\n", iface
, boundary
);
278 static HRESULT WINAPI
speech_voice_put_SynchronousSpeakTimeout(ISpeechVoice
*iface
, LONG timeout
)
280 FIXME("(%p, %d): stub.\n", iface
, timeout
);
285 static HRESULT WINAPI
speech_voice_get_SynchronousSpeakTimeout(ISpeechVoice
*iface
, LONG
*timeout
)
287 FIXME("(%p, %p): stub.\n", iface
, timeout
);
292 static HRESULT WINAPI
speech_voice_Speak(ISpeechVoice
*iface
, BSTR text
, SpeechVoiceSpeakFlags flags
, LONG
*number
)
294 FIXME("(%p, %s, %#x, %p): stub.\n", iface
, debugstr_w(text
), flags
, number
);
299 static HRESULT WINAPI
speech_voice_SpeakStream(ISpeechVoice
*iface
, ISpeechBaseStream
*stream
,
300 SpeechVoiceSpeakFlags flags
, LONG
*number
)
302 FIXME("(%p, %p, %#x, %p): stub.\n", iface
, stream
, flags
, number
);
307 static HRESULT WINAPI
speech_voice_Pause(ISpeechVoice
*iface
)
309 FIXME("(%p): stub.\n", iface
);
314 static HRESULT WINAPI
speech_voice_Resume(ISpeechVoice
*iface
)
316 FIXME("(%p): stub.\n", iface
);
321 static HRESULT WINAPI
speech_voice_Skip(ISpeechVoice
*iface
, const BSTR type
, LONG items
, LONG
*skipped
)
323 FIXME("(%p, %s, %d, %p): stub.\n", iface
, debugstr_w(type
), items
, skipped
);
328 static HRESULT WINAPI
speech_voice_GetVoices(ISpeechVoice
*iface
, BSTR required
, BSTR optional
,
329 ISpeechObjectTokens
**tokens
)
331 FIXME("(%p, %s, %s, %p): stub.\n", iface
, debugstr_w(required
), debugstr_w(optional
), tokens
);
336 static HRESULT WINAPI
speech_voice_GetAudioOutputs(ISpeechVoice
*iface
, BSTR required
, BSTR optional
,
337 ISpeechObjectTokens
**tokens
)
339 FIXME("(%p, %s, %s, %p): stub.\n", iface
, debugstr_w(required
), debugstr_w(optional
), tokens
);
344 static HRESULT WINAPI
speech_voice_WaitUntilDone(ISpeechVoice
*iface
, LONG timeout
, VARIANT_BOOL
*done
)
346 FIXME("(%p, %d, %p): stub.\n", iface
, timeout
, done
);
351 static HRESULT WINAPI
speech_voice_SpeakCompleteEvent(ISpeechVoice
*iface
, LONG
*handle
)
353 FIXME("(%p, %p): stub.\n", iface
, handle
);
358 static HRESULT WINAPI
speech_voice_IsUISupported(ISpeechVoice
*iface
, const BSTR typeui
, const VARIANT
*data
,
359 VARIANT_BOOL
*supported
)
361 FIXME("(%p, %s, %p, %p): stub.\n", iface
, debugstr_w(typeui
), data
, supported
);
366 static HRESULT WINAPI
speech_voice_DisplayUI(ISpeechVoice
*iface
, LONG hwnd
, BSTR title
,
367 const BSTR typeui
, const VARIANT
*data
)
369 FIXME("(%p, %d, %s, %s, %p): stub.\n", iface
, hwnd
, debugstr_w(title
), debugstr_w(typeui
), data
);
374 static const ISpeechVoiceVtbl speech_voice_vtbl
=
376 speech_voice_QueryInterface
,
378 speech_voice_Release
,
379 speech_voice_GetTypeInfoCount
,
380 speech_voice_GetTypeInfo
,
381 speech_voice_GetIDsOfNames
,
383 speech_voice_get_Status
,
384 speech_voice_get_Voice
,
385 speech_voice_putref_Voice
,
386 speech_voice_get_AudioOutput
,
387 speech_voice_putref_AudioOutput
,
388 speech_voice_get_AudioOutputStream
,
389 speech_voice_putref_AudioOutputStream
,
390 speech_voice_get_Rate
,
391 speech_voice_put_Rate
,
392 speech_voice_get_Volume
,
393 speech_voice_put_Volume
,
394 speech_voice_put_AllowAudioOutputFormatChangesOnNextSet
,
395 speech_voice_get_AllowAudioOutputFormatChangesOnNextSet
,
396 speech_voice_get_EventInterests
,
397 speech_voice_put_EventInterests
,
398 speech_voice_put_Priority
,
399 speech_voice_get_Priority
,
400 speech_voice_put_AlertBoundary
,
401 speech_voice_get_AlertBoundary
,
402 speech_voice_put_SynchronousSpeakTimeout
,
403 speech_voice_get_SynchronousSpeakTimeout
,
405 speech_voice_SpeakStream
,
409 speech_voice_GetVoices
,
410 speech_voice_GetAudioOutputs
,
411 speech_voice_WaitUntilDone
,
412 speech_voice_SpeakCompleteEvent
,
413 speech_voice_IsUISupported
,
414 speech_voice_DisplayUI
,
417 /* ISpVoice interface */
418 static HRESULT WINAPI
spvoice_QueryInterface(ISpVoice
*iface
, REFIID iid
, void **obj
)
420 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
422 TRACE("(%p, %s %p).\n", iface
, debugstr_guid(iid
), obj
);
424 return ISpeechVoice_QueryInterface(&This
->ISpeechVoice_iface
, iid
, obj
);
427 static ULONG WINAPI
spvoice_AddRef(ISpVoice
*iface
)
429 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
431 TRACE("(%p).\n", iface
);
433 return ISpeechVoice_AddRef(&This
->ISpeechVoice_iface
);
436 static ULONG WINAPI
spvoice_Release(ISpVoice
*iface
)
438 struct speech_voice
*This
= impl_from_ISpVoice(iface
);
440 TRACE("(%p).\n", iface
);
442 return ISpeechVoice_Release(&This
->ISpeechVoice_iface
);
445 static HRESULT WINAPI
spvoice_SetNotifySink(ISpVoice
*iface
, ISpNotifySink
*sink
)
447 FIXME("(%p, %p): stub.\n", iface
, sink
);
452 static HRESULT WINAPI
spvoice_SetNotifyWindowMessage(ISpVoice
*iface
, HWND hwnd
, UINT msg
,
453 WPARAM wparam
, LPARAM lparam
)
455 FIXME("(%p, %p, %u, %lx, %lx): stub.\n", iface
, hwnd
, msg
, wparam
, lparam
);
460 static HRESULT WINAPI
spvoice_SetNotifyCallbackFunction(ISpVoice
*iface
, SPNOTIFYCALLBACK
*callback
,
461 WPARAM wparam
, LPARAM lparam
)
463 FIXME("(%p, %p, %lx, %lx): stub.\n", iface
, callback
, wparam
, lparam
);
468 static HRESULT WINAPI
spvoice_SetNotifyCallbackInterface(ISpVoice
*iface
, ISpNotifyCallback
*callback
,
469 WPARAM wparam
, LPARAM lparam
)
471 FIXME("(%p, %p, %lx, %lx): stub.\n", iface
, callback
, wparam
, lparam
);
476 static HRESULT WINAPI
spvoice_SetNotifyWin32Event(ISpVoice
*iface
)
478 FIXME("(%p): stub.\n", iface
);
483 static HRESULT WINAPI
spvoice_WaitForNotifyEvent(ISpVoice
*iface
, DWORD milliseconds
)
485 FIXME("(%p, %d): stub.\n", iface
, milliseconds
);
490 static HANDLE WINAPI
spvoice_GetNotifyEventHandle(ISpVoice
*iface
)
492 FIXME("(%p): stub.\n", iface
);
497 static HRESULT WINAPI
spvoice_SetInterest(ISpVoice
*iface
, ULONGLONG event
, ULONGLONG queued
)
499 FIXME("(%p, %s, %s): stub.\n", iface
, wine_dbgstr_longlong(event
), wine_dbgstr_longlong(queued
));
504 static HRESULT WINAPI
spvoice_GetEvents(ISpVoice
*iface
, ULONG count
, SPEVENT
*array
, ULONG
*fetched
)
506 FIXME("(%p, %u, %p, %p): stub.\n", iface
, count
, array
, fetched
);
511 static HRESULT WINAPI
spvoice_GetInfo(ISpVoice
*iface
, SPEVENTSOURCEINFO
*info
)
513 FIXME("(%p, %p): stub.\n", iface
, info
);
518 static HRESULT WINAPI
spvoice_SetOutput(ISpVoice
*iface
, IUnknown
*unk
, BOOL changes
)
520 FIXME("(%p, %p, %d: stub.\n)", iface
, unk
, changes
);
525 static HRESULT WINAPI
spvoice_GetOutputObjectToken(ISpVoice
*iface
, ISpObjectToken
**token
)
527 FIXME("(%p, %p): stub.\n", iface
, token
);
532 static HRESULT WINAPI
spvoice_GetOutputStream(ISpVoice
*iface
, ISpStreamFormat
**stream
)
534 FIXME("(%p, %p): stub.\n", iface
, stream
);
539 static HRESULT WINAPI
spvoice_Pause(ISpVoice
*iface
)
541 FIXME("(%p): stub.\n", iface
);
546 static HRESULT WINAPI
spvoice_Resume(ISpVoice
*iface
)
548 FIXME("(%p): stub.\n", iface
);
553 static HRESULT WINAPI
spvoice_SetVoice(ISpVoice
*iface
, ISpObjectToken
*token
)
555 FIXME("(%p, %p): stub.\n", iface
, token
);
560 static HRESULT WINAPI
spvoice_GetVoice(ISpVoice
*iface
, ISpObjectToken
**token
)
562 FIXME("(%p, %p): stub.\n", iface
, token
);
567 static HRESULT WINAPI
spvoice_Speak(ISpVoice
*iface
, const WCHAR
*contents
, DWORD flags
, ULONG
*number
)
569 FIXME("(%p, %p, %#x, %p): stub.\n", iface
, contents
, flags
, number
);
574 static HRESULT WINAPI
spvoice_SpeakStream(ISpVoice
*iface
, IStream
*stream
, DWORD flags
, ULONG
*number
)
576 FIXME("(%p, %p, %#x, %p): stub.\n", iface
, stream
, flags
, number
);
581 static HRESULT WINAPI
spvoice_GetStatus(ISpVoice
*iface
, SPVOICESTATUS
*status
, WCHAR
**bookmark
)
583 FIXME("(%p, %p, %p): stub.\n", iface
, status
, bookmark
);
588 static HRESULT WINAPI
spvoice_Skip(ISpVoice
*iface
, const WCHAR
*type
, LONG items
, ULONG
*skipped
)
590 FIXME("(%p, %s, %d, %p): stub.\n", iface
, debugstr_w(type
), items
, skipped
);
595 static HRESULT WINAPI
spvoice_SetPriority(ISpVoice
*iface
, SPVPRIORITY priority
)
597 FIXME("(%p, %d): stub.\n", iface
, priority
);
602 static HRESULT WINAPI
spvoice_GetPriority(ISpVoice
*iface
, SPVPRIORITY
*priority
)
604 FIXME("(%p, %p): stub.\n", iface
, priority
);
609 static HRESULT WINAPI
spvoice_SetAlertBoundary(ISpVoice
*iface
, SPEVENTENUM boundary
)
611 FIXME("(%p, %d): stub.\n", iface
, boundary
);
616 static HRESULT WINAPI
spvoice_GetAlertBoundary(ISpVoice
*iface
, SPEVENTENUM
*boundary
)
618 FIXME("(%p, %p): stub.\n", iface
, boundary
);
623 static HRESULT WINAPI
spvoice_SetRate(ISpVoice
*iface
, LONG adjust
)
625 FIXME("(%p, %d): stub.\n", iface
, adjust
);
630 static HRESULT WINAPI
spvoice_GetRate(ISpVoice
*iface
, LONG
*adjust
)
632 FIXME("(%p, %p): stub.\n", iface
, adjust
);
637 static HRESULT WINAPI
spvoice_SetVolume(ISpVoice
*iface
, USHORT volume
)
639 FIXME("(%p, %d): stub.\n", iface
, volume
);
644 static HRESULT WINAPI
spvoice_GetVolume(ISpVoice
*iface
, USHORT
*volume
)
646 FIXME("(%p, %p): stub.\n", iface
, volume
);
651 static HRESULT WINAPI
spvoice_WaitUntilDone(ISpVoice
*iface
, ULONG timeout
)
653 FIXME("(%p, %d): stub.\n", iface
, timeout
);
658 static HRESULT WINAPI
spvoice_SetSyncSpeakTimeout(ISpVoice
*iface
, ULONG timeout
)
660 FIXME("(%p, %d): stub.\n", iface
, timeout
);
665 static HRESULT WINAPI
spvoice_GetSyncSpeakTimeout(ISpVoice
*iface
, ULONG
*timeout
)
667 FIXME("(%p, %p): stub.\n", iface
, timeout
);
672 static HANDLE WINAPI
spvoice_SpeakCompleteEvent(ISpVoice
*iface
)
674 FIXME("(%p): stub.\n", iface
);
679 static HRESULT WINAPI
spvoice_IsUISupported(ISpVoice
*iface
, const WCHAR
*type
, void *extra
,
680 ULONG count
, BOOL
*supported
)
682 FIXME("(%p, %p, %p, %d, %p): stub.\n", iface
, type
, extra
, count
, supported
);
687 static HRESULT WINAPI
spvoice_DisplayUI(ISpVoice
*iface
, HWND parent
, const WCHAR
*title
,
688 const WCHAR
*type
, void *extra
, ULONG count
)
690 FIXME("(%p, %p, %p, %p, %p, %d): stub.\n", iface
, parent
, title
, type
, extra
, count
);
695 static const ISpVoiceVtbl spvoice_vtbl
=
697 spvoice_QueryInterface
,
700 spvoice_SetNotifySink
,
701 spvoice_SetNotifyWindowMessage
,
702 spvoice_SetNotifyCallbackFunction
,
703 spvoice_SetNotifyCallbackInterface
,
704 spvoice_SetNotifyWin32Event
,
705 spvoice_WaitForNotifyEvent
,
706 spvoice_GetNotifyEventHandle
,
711 spvoice_GetOutputObjectToken
,
712 spvoice_GetOutputStream
,
723 spvoice_SetAlertBoundary
,
724 spvoice_GetAlertBoundary
,
729 spvoice_WaitUntilDone
,
730 spvoice_SetSyncSpeakTimeout
,
731 spvoice_GetSyncSpeakTimeout
,
732 spvoice_SpeakCompleteEvent
,
733 spvoice_IsUISupported
,
737 /* IConnectionPointContainer interface */
738 static HRESULT WINAPI
container_QueryInterface(IConnectionPointContainer
*iface
, REFIID iid
, void **obj
)
740 struct speech_voice
*This
= impl_from_IConnectionPointContainer(iface
);
742 TRACE("(%p, %s %p).\n", iface
, debugstr_guid(iid
), obj
);
744 return ISpeechVoice_QueryInterface(&This
->ISpeechVoice_iface
, iid
, obj
);
747 static ULONG WINAPI
container_AddRef(IConnectionPointContainer
*iface
)
749 struct speech_voice
*This
= impl_from_IConnectionPointContainer(iface
);
751 TRACE("(%p).\n", iface
);
753 return ISpeechVoice_AddRef(&This
->ISpeechVoice_iface
);
756 static ULONG WINAPI
container_Release(IConnectionPointContainer
*iface
)
758 struct speech_voice
*This
= impl_from_IConnectionPointContainer(iface
);
760 TRACE("(%p).\n", iface
);
762 return ISpeechVoice_Release(&This
->ISpeechVoice_iface
);
765 static HRESULT WINAPI
container_EnumConnectionPoints(IConnectionPointContainer
*iface
,
766 IEnumConnectionPoints
**enum_cp
)
768 FIXME("(%p, %p): stub.\n", iface
, enum_cp
);
773 static HRESULT WINAPI
container_FindConnectionPoint(IConnectionPointContainer
*iface
, REFIID riid
,
774 IConnectionPoint
**cp
)
776 FIXME("(%p, %s, %p): stub.\n", iface
, debugstr_guid(riid
), cp
);
781 const static IConnectionPointContainerVtbl container_vtbl
=
783 container_QueryInterface
,
786 container_EnumConnectionPoints
,
787 container_FindConnectionPoint
790 HRESULT
speech_voice_create(IUnknown
*outer
, REFIID iid
, void **obj
)
792 struct speech_voice
*This
= heap_alloc(sizeof(*This
));
795 if (!This
) return E_OUTOFMEMORY
;
796 This
->ISpeechVoice_iface
.lpVtbl
= &speech_voice_vtbl
;
797 This
->ISpVoice_iface
.lpVtbl
= &spvoice_vtbl
;
798 This
->IConnectionPointContainer_iface
.lpVtbl
= &container_vtbl
;
801 hr
= ISpeechVoice_QueryInterface(&This
->ISpeechVoice_iface
, iid
, obj
);
803 ISpeechVoice_Release(&This
->ISpeechVoice_iface
);