拓展SOUI中SImRichEdit控件的语音OLE控件(AudioOle)

	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);


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值