extern "C" const GUID IID_AudioOleCtrl;class RichEditAudioOle :public RichEditOleBase{DECLARE_REOBJ(RichEditAudioOle, L"audio")public:enum ReAudioState{REAUDIO_STATE_NOPLAY,       //  未播放状态REAUDIO_STATE_PLAYING,     //  正在播放状态REAUDIO_STATE_PLAYFINISH,   //    播放完成状态};RichEditAudioOle();~RichEditAudioOle();BOOL InitOleWindow(IRichEditObjHost* pHost);int GetAudioState(){return _state;}SStringW GetAudioPath(){return _audio_path;}SStringW GetAudioDuration(){return _audio_duration;}SStringW GetAudioId(){return GetId();}void AudioPlayFinish();protected:void UpdatePosition();bool OnAudioPlayClick(SOUI::EventArgs* pEvt);bool OnAudioPlayingClick(SOUI::EventArgs* pEvt);protected:SOUI_ATTRS_BEGIN()ATTR_STRINGW(L"audio_duration", _audio_duration, FALSE)ATTR_STRINGW(L"audio_path", _audio_path, FALSE)SOUI_ATTRS_END()private:int           _state;SIZE        _maxSize;SStringW    _audio_duration;SStringW    _audio_path;};
 //////{9DB5554F-7BB7-4d2f-B4D7-3BD9F6E8901A}static const GUID IID_AudioOleCtrl = { 0x9db5554f, 0x7bb7, 0x4d2f, { 0xb4, 0xd7, 0x3b, 0xd9, 0xf6, 0xe8, 0x90, 0x1a } };RichEditAudioOle::RichEditAudioOle(){_oleGuid = IID_AudioOleCtrl;_maxSize.cx = _maxSize.cy = 180;_state = REAUDIO_STATE_NOPLAY;_canBeSelect = FALSE;_xmlLayout = L"LAYOUT:AudioOleLayout";}RichEditAudioOle::~RichEditAudioOle(){//// 把图片skin的内存由_oleView管理,当_oleView释放时,会调用skin的release// }void RichEditAudioOle::AudioPlayFinish(){_state = REAUDIO_STATE_PLAYFINISH;SImageView* pImgPlay = _oleView.FindChildByName2<SImageView>(L"play");if (pImgPlay){pImgPlay->SetVisible(TRUE, TRUE);}SImageView* pImgPlaying = _oleView.FindChildByName2<SImageView>(L"playing");if (pImgPlaying){pImgPlaying->SetVisible(FALSE, TRUE);}SImageView* pImageReddot= _oleView.FindChildByName2<SImageView>(L"isplayed");if (pImageReddot)pImageReddot->SetVisible(FALSE, TRUE);std::wstring wstrDuration;wstrDuration.append(_audio_duration);wstrDuration.append(L"\"");SWindow* pAudioDuration = _oleView.FindChildByName2<SWindow>(L"audio_duration");if (pAudioDuration){pAudioDuration->SetWindowText(wstrDuration.c_str());pAudioDuration->SetVisible(TRUE, TRUE);}}bool RichEditAudioOle::OnAudioPlayClick(SOUI::EventArgs* pEvt){_state = REAUDIO_STATE_PLAYING;SImageView* pImgPlay = _oleView.FindChildByName2<SImageView>(L"play");if (pImgPlay){pImgPlay->SetVisible(FALSE, TRUE);}SImageView* pImgPlaying = _oleView.FindChildByName2<SImageView>(L"playing");if (pImgPlaying){pImgPlaying->SetVisible(TRUE, TRUE);pImgPlaying->Resume();}SImageView* pImageReddot= _oleView.FindChildByName2<SImageView>(L"isplayed");if (pImageReddot)pImageReddot->SetVisible(FALSE, TRUE);std::wstring wstrDuration;wstrDuration.append(_audio_duration);wstrDuration.append(L"\"");SWindow* pAudioDuration = _oleView.FindChildByName2<SWindow>(L"audio_duration");if (pAudioDuration){pAudioDuration->SetWindowText(wstrDuration.c_str());pAudioDuration->SetVisible(TRUE, TRUE);}_pObjHost->NotifyRichObjEvent(this, CLICK_15AUDIO_PLAY, 0, 0);return true;}bool RichEditAudioOle::OnAudioPlayingClick(SOUI::EventArgs* pEvt){      _state = REAUDIO_STATE_PLAYFINISH;SImageView* pImgPlay = _oleView.FindChildByName2<SImageView>(L"play");if (pImgPlay){pImgPlay->SetVisible(TRUE, TRUE);}SImageView* pImgPlaying = _oleView.FindChildByName2<SImageView>(L"playing");if (pImgPlaying){pImgPlaying->SetVisible(FALSE, TRUE);}SImageView* pImageReddot= _oleView.FindChildByName2<SImageView>(L"isplayed");if (pImageReddot)pImageReddot->SetVisible(FALSE, TRUE);std::wstring wstrDuration;wstrDuration.append(_audio_duration);wstrDuration.append(L"\"");SWindow* pAudioDuration = _oleView.FindChildByName2<SWindow>(L"audio_duration");if (pAudioDuration){pAudioDuration->SetWindowText(wstrDuration.c_str());pAudioDuration->SetVisible(TRUE, TRUE);}_pObjHost->NotifyRichObjEvent(this, CLICK_15AUDIO_PLAYING, 0, 0);return true;}BOOL RichEditAudioOle::InitOleWindow(IRichEditObjHost * pHost){BOOL ret = RichEditOleBase::InitOleWindow(pHost);ISkinObj* pSkinPlay = GETSKIN(L"skin.richaudio_15play", 100);SImageView* pImgPlay = _oleView.FindChildByName2<SImageView>(L"play");if (pImgPlay && pSkinPlay){pImgPlay->SetSkin(pSkinPlay);pImgPlay->SetVisible(TRUE, TRUE);pImgPlay->Resume();SUBSCRIBE(pImgPlay, EVT_CMD, RichEditAudioOle::OnAudioPlayClick);}ISkinObj* pSkinPlaying = GETSKIN(L"skin.richaudio_15playing", 100);SImageView* pImgPlaying = _oleView.FindChildByName2<SImageView>(L"playing");if (pImgPlaying && pSkinPlaying){pImgPlaying->SetSkin(pSkinPlaying);pImgPlaying->SetVisible(FALSE, TRUE);}ISkinObj* pSkinReddot = GETSKIN(L"skin.richaudio_reddot", 100);SImageView* pImageReddot= _oleView.FindChildByName2<SImageView>(L"isplayed");if (pImageReddot && pSkinReddot){pImageReddot->SetSkin(pSkinReddot);pImageReddot->SetVisible(TRUE, TRUE);pImageReddot->Resume();SUBSCRIBE(pImgPlaying, EVT_CMD, RichEditAudioOle::OnAudioPlayingClick);}std::wstring wstrDuration;wstrDuration.append(_audio_duration);wstrDuration.append(L"\"");SWindow* pAudioDuration = _oleView.FindChildByName2<SWindow>(L"audio_duration");if (pAudioDuration){pAudioDuration->SetWindowText(wstrDuration.c_str());pAudioDuration->SetVisible(TRUE, TRUE);}return ret;}void RichEditAudioOle::UpdatePosition(){if (_spAdviseSink){double fRatio = GetZoomRatio(_sizeNatural, _maxSize);_sizeNatural.cx = 130;_sizeNatural.cy = 40;_oleView.SetOleWindowRect(CRect(0, 0, 0, 0)); // 已经失效_oleView.Move(0, 0, _sizeNatural.cx, _sizeNatural.cy);CalculateExtentSize(_sizeNatural);_spAdviseSink->OnViewChange(DVASPECT_CONTENT, -1);}}

以上为控件实现代码;

IID_AudioOleCtrl为控件GUID,可以自己生成。

接口说明:

InitOleWindow:初始化Ole窗口

GetAudioState:获取Audio状态

GetAudioPath:获取Audio文件路径

GetAudioDuration:获取Audio文件播放时长

GetAudioId:获取元素ID

AudioPlayFinish:Audio播放完成时调用

OnAudioPlayClick:静态状态点击事件

OnAudioPlayingClick:播放状态点击事件

以下是控件布局相关XML:

<root><window pos="0,0,-0,-0" skin="skin.empty"><image name="play" cursor="hand" pos="0,0"/><image name="playing" cursor="hand" pos="0,0" /><text name="audio_duration" pos="[5,22" align="center" colorText="#000000" dotted="1" font="size:12"/><image name="isplayed" pos="110,15" skin="skin.richaudio_reddot" show="1" /></window>
</root>

控件需要在uires.idx文件中添加相关映射关系

注意:

在使用时还需要在以下文件的接口中添加相关代码:

RichEditObjFactory.cpp文件的RichEditObjFactory接口中添加_creaters[RichEditAudioOle::GetClassName()] = RichEditAudioOle::CreateObject;

如下所示:

    RichEditObjFactory::RichEditObjFactory(){_creaters[RichEditText::GetClassName()] = RichEditText::CreateObject;_creaters[RichEditBkElement::GetClassName()] = RichEditBkElement::CreateObject;_creaters[RichEditPara::GetClassName()] = RichEditPara::CreateObject;_creaters[RichEditContent::GetClassName()] = RichEditContent::CreateObject;_creaters[RichEditFetchMoreOle::GetClassName()] = RichEditFetchMoreOle::CreateObject;_creaters[RichEditImageOle::GetClassName()] = RichEditImageOle::CreateObject;_creaters[RichEditFileOle::GetClassName()] = RichEditFileOle::CreateObject;_creaters[RichEditSeparatorBar::GetClassName()] = RichEditSeparatorBar::CreateObject;_creaters[RichEditMetaFileOle::GetClassName()] = RichEditMetaFileOle::CreateObject;_creaters[RichEditReminderOle::GetClassName()] = RichEditReminderOle::CreateObject;_creaters[RichEditAudioOle::GetClassName()] = RichEditAudioOle::CreateObject;}

RichEditOleCallback.cpp文件的QueryInsertObject接口中添加相关代码,如下所示:

    HRESULT RichEditOleCallback::QueryInsertObject(LPCLSID lpclsid,LPSTORAGE lpstg,LONG cp){if (lpclsid == NULL){return E_INVALIDARG;}if (*lpclsid == IID_ImageOleCtrl ||*lpclsid == IID_FileOleCtrl ||*lpclsid == IID_FetchMoreOleCtrl ||*lpclsid == IID_SeparatorBarCtrl ||*lpclsid == IID_RichMetaFileOle ||*lpclsid == IID_RemainderOleCtrl ||*lpclsid == IID_AudioOleCtrl){return S_OK;}return E_FAIL;}

以上为OLE控件相关代码;

下边我们看看新控件的使用:

SStringW strAudio;
std::string strAudioId = KfUtility::GenerateUUID();
std::wstring wstrAudioId;
KfUtility::ConvertUtf8ToUtf16(strAudioId, wstrAudioId);
strAudio.Format(L"<audio id=\"%s\" audio_duration=\"12\" audio_path=\"D:\\imrepose\\trunk\\KFClient6\\output\\Debug_Unicode\\default_res\\test.amr\"/>", wstrAudioId.c_str());
SStringW strContent;
strContent.Format(L"<RichEditContent  type=\"ContentLeft\" align=\"left\">"L"<para>"L"</para>"L"<bkele data=\"avatar\" id=\"%s\" skin=\"%s\" pos=\"0,]-2,@40,@40\" cursor=\"hand\" interactive=\"1\"/>"L"<para id=\"msgbody\" margin=\"50,0,0,0\" break=\"1\" simulate-align=\"1\">"      L"%s"L"</para>"L"%s"L"</RichEditContent>",wstrId.c_str(), wstrFaceId.c_str(), strAudio, pEmpty);
pRecvRichEdit->InsertContent(strContent, RECONTENT_LAST);

拓展SOUI中SImRichEdit控件的语音OLE控件(AudioOle)相关推荐

  1. 拓展SOUI中SImRichEdit控件的视频OLE控件(VideoOle)

    视频定位控件数据可分为两部分: 可见部分:播放按钮.加载按钮.视频第一帧图片.视频时长 不可见部分:视频URL 以下为VideoOle控件头文件部分: extern "C" con ...

  2. PowerBuilder打开OLE控件页崩溃的解决办法

    PowerBuilder打开OLE控件页崩溃的解决办法 PB 执行 Insert -> OLE... -> Insert Control  - 崩溃 的解决办法 工具/原料 * PB12及 ...

  3. android 继承现有控件,Android继承现有控件拓展实现自定义控件textView

    通常情况下,Android实现自定义控件无非三种方式. Ⅰ.继承现有控件,对其控件的功能进行拓展. Ⅱ.将现有控件进行组合,实现功能更加强大控件. Ⅲ.重写View实现全新的控件 本文重点讨论继承现有 ...

  4. DELPHI下基于APRO控件的语音系统开发

    开始设计 下面我们就来看看如何利用这组控件实现语音功能,对于我们程序的应用来说,只需要使用两个 TAPI 控件 TApdComPort 和 TApdTapiDevice 即可,其中 TApdComPo ...

  5. dev treeview控件_在Winform开发框架中使用DevExpress的TreeList和TreeListLookupEdit控件

    DevExpress提供的树形列表控件TreeList和树形下拉列表控件TreeListLookupEdit都是非常强大的一个控件,它和我们传统Winform的TreeView控件使用上有所不同,我一 ...

  6. vue树形结构html,怎么在vue中利用递归组件实现一个树形控件

    怎么在vue中利用递归组件实现一个树形控件 发布时间:2021-06-11 17:26:48 来源:亿速云 阅读:81 作者:Leah 本篇文章为大家展示了怎么在vue中利用递归组件实现一个树形控件, ...

  7. C#中如何将光标定位在某个控件中?

    C#中如何将光标定位在某个控件中? 例子:当打开如下界面时,如何将光标定位在Form9界面中的用户名combox1框中? (1)首先将界面Form9事件中的shown选择Form9_Load,如下图所 ...

  8. Windows Presentation Foundation(WPF)中的数据绑定(使用XmlDataProvider作控件绑定)

    原文:Windows Presentation Foundation(WPF)中的数据绑定(使用XmlDataProvider作控件绑定) ------------------------------ ...

  9. Leaflet中实现添加比例尺控件与自定义版权控件与链接

    场景 Leaflet快速入门与加载OSM显示地图: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/122290880 上面加载显示 ...

  10. activex 控件的id 定义位置+使用ocx控件的客户端程序中对控件定义的文件中控件id定义的位置...

    activex 控件的id 定义位置 // SuperDisplayCtl.cpp IMPLEMENT_OLECREATE_EX(CSuperDisplayCtrl, "SuperDispl ...

最新文章

  1. 十大排序算法 导图总结
  2. 安装QT的时候出现PATH_MAX错误
  3. html中某个名称不能修改,解决type=file 文件修改表单 名称不能正常回显的问题
  4. java模拟退火程序
  5. boost::multiprecision模块complex128相关的测试程序
  6. java帧结构_Java虚拟机运行时栈帧结构--《深入理解Java虚拟机》学习笔记及个人理解(二)...
  7. 拍摄女生人像,摄影师觉得最大的困难是什么?
  8. 二维码用的完吗?有没有二维码图案用完的那天?
  9. Linux使用Mac键盘,System76 推出 Linux 键盘 看完手痒了!
  10. 设置无效,为什么下载分数经常变化?
  11. 图神经网络初探:build a simple graph nets
  12. 【T+】畅捷通T+认证报错,提示:“当前加密狗信息无效,无法进行企业认证”
  13. HTML标记大全参考手册
  14. 语音学习笔记3------matlab实现傅里叶反变换ifft()函数
  15. 微信支付商户平台开通流程
  16. 无线降噪耳机推荐,热销火爆的四款降噪耳机推荐
  17. 按键精灵手机版 找图(Findpic)以及其与点击、runapp和找点的对比
  18. 无人洗车小程序源码开发
  19. LAPACK的C/C++接口及代码实例
  20. 在Unity中获得一个物体的所有子物体包括孙物体。

热门文章

  1. 成功烧写TMS320F2812经验
  2. Android 文字转语音之TextToSpeech
  3. 百度编辑器Ueditor 多图上传出现部分照片尺寸不压缩的问题解决
  4. 介绍一些新手都能看的明白的基础破解教程
  5. android实现半透明,Android应用开发中半透明效果实现方案总结
  6. win10用账户登录计算机,图文详解让你的win10系统实现微软账户自动登录-系统操作与应用 -亦是美网络...
  7. adb的环境搭建,下载和卸载app
  8. 一个高仿追书神器的vue阅读器。已成功做成app
  9. 推荐更好用的网络检测命令
  10. ISO27001信息安全管理体系认证范围及用处