Reputation: 11399
I need to populate the members of a struct:
typedef struct SPEVENT
{
SPEVENTENUM eEventId : 16;
SPEVENTLPARAMTYPE elParamType : 16;
ULONG ulStreamNum;
ULONGLONG ullAudioStreamOffset;
WPARAM wParam;
LPARAM lParam;
} SPEVENT;
The information on how to use this is sparse. The only examples for populating it are from other users, but nothing official.
The app receiving this event should get the string. With my approach, it doesn't work: The string is "".
Can anybody tell me if he spots anything obvious wrong in my attempt?
wstring wsBookmark = L"MyBookmark";
CSpEvent nBookmarkEvent;
nBookmarkEvent.eEventId = SPEI_TTS_BOOKMARK;
nBookmarkEvent.elParamType = SPET_LPARAM_IS_STRING;
nBookmarkEvent.ullAudioStreamOffset = 0;
nBookmarkEvent.lParam = _wtol(wsBookmark.c_str());
nBookmarkEvent.wParam = (LPARAM)wsBookmark.c_str();
As I have explained, there doesn't seem to be any official guide on how to populate these members.
What I found so far are these user codes:
https://github.com/m-toman/SALB/blob/master/sapi/htstts.cpp In this link I see this:
CHECKASSERTId(( !wcscmp( (WCHAR*)Event.lParam, szwBMarkStr ) ), tpr, IDS_STRING9);
But I have no idea if that would help me.
Thank you for any input or help!!
Upvotes: 0
Views: 1298
Reputation: 597051
The SPEVENT
struct is documented on MSDN.
In your case, the documentation for the SPET_LPARAM_IS_STRING
flag says:
SPET_LPARAM_IS_STRING
TheSPEVENT.lParam
value represents a pointer to a string. For example, the TTS bookmark event (i.e.,SPEI_TTS_BOOKMARK
) includes a pointer the bookmark name, so thelParam
type isSPET_LPARAM_IS_STRING
. The user must callCoTaskMemFree
on thelParam
member (as pointer) to release the associated memory.
Which means the memory pointed to by the lParam
MUST by allocated with CoTaskMemAlloc()
(or related function), which std::wstring
is not, so you cannot just pass the std::wstring::c_str()
pointer in the lParam
, you must make a copy to a CoTask-allocated memory block.
Also, the SPEI_TTS_BOOKMARK
says:
SPEI_TTS_BOOKMARK
The bookmark element is used to insert a bookmark into the output stream. If an application specifies interest in bookmark events, it will receive the bookmark events during synthesis.wParam
is the current bookmark name (in base 10) converted to a long integer. If name of current bookmark is not an integer,wParam
will be zero.lParam
is the bookmark string.elParamType
has to beSPET_LPARAM_IS_STRING
.
So, with that said, try this instead:
wstring wsBookmark = L"MyBookmark";
UINT size = (wsBookmark.size() + 1) * sizeof(wchar_t);
wchar_t *ptr = (wchar_t*) CoTaskMemAlloc(size);
CopyMemory(ptr, wsBookmark.c_str(), size);
CSpEvent nBookmarkEvent;
nBookmarkEvent.eEventId = SPEI_TTS_BOOKMARK;
nBookmarkEvent.elParamType = SPET_LPARAM_IS_STRING;
nBookmarkEvent.ullAudioStreamOffset = 0;
nBookmarkEvent.wParam = 0;
nBookmarkEvent.lParam = (LPARAM) ptr;
Upvotes: 1