// // 单选的时候才需要画反色框 // void RichEditOleBase::InvertBorder(HDC hdc, LPRECT lpBorder) { if (!m_bCanSelect) { CHARRANGE chr={0}; m_pObjectHost->SendMessage(EM_EXGETSEL, 0, (LPARAM)&chr,NULL); if (chr.cpMax - chr.cpMin == 1 && // | chr.cpMin <= m_chrContent.cpMin && // -> 单选,并且选中了自己 m_chrContent.cpMin < chr.cpMax) // | { SComPtr<IRichEditOle> ole; m_pObjectHost->SendMessage(EM_GETOLEINTERFACE,0,(LPARAM)&ole); REOBJECT reobj={0}; reobj.cbStruct=sizeof(REOBJECT); reobj.cp = m_chrContent.cpMin; HRESULT hr=ole->GetObject(REO_IOB_USE_CP, &reobj, REO_GETOBJ_NO_INTERFACES); if (SUCCEEDED(hr)) { CRect rcBorder = lpBorder; InvertRect(hdc, rcBorder); rcBorder.InflateRect(-1,-1,-1,-1); InvertRect(hdc, rcBorder); } } } }
void CMainDlg::OnBtnInsertGif2RE() { SRichEdit *pEdit = FindChildByName2<SRichEdit>(L"re_gifhost"); if(pEdit) { CFileDialogEx openDlg(TRUE,_T("gif"),0,6,_T("gif files(*.gif)\0*.gif\0All files (*.*)\0*.*\0\0")); if(openDlg.DoModal()==IDOK) { ISmileySource* pSource = new CSmileySource2; HRESULT hr=pSource->LoadFromFile(S_CT2W(openDlg.m_szFileName)); if(SUCCEEDED(hr)) { SComPtr<ISoSmileyCtrl> pSmiley; hr=::CoCreateInstance(SoSmiley::CLSID_CSoSmileyCtrl,NULL,CLSCTX_INPROC,__uuidof(SoSmiley::ISoSmileyCtrl),(LPVOID*)&pSmiley); if(SUCCEEDED(hr)) { pSmiley->SetSource(pSource); SComPtr<IRichEditOle> ole; pEdit->SSendMessage(EM_GETOLEINTERFACE,0,(LPARAM)&ole); pSmiley->Insert2Richedit((DWORD_PTR)(void*)ole); } else { UINT uRet = SMessageBox(m_hWnd,_T("可能是因为没有向系统注册表情COM模块。\\n现在注册吗?"),_T("创建表情OLE对象失败"),MB_YESNO|MB_ICONSTOP); if(uRet == IDYES) { HMODULE hMod = LoadLibrary(_T("sosmiley.dll")); if(hMod) { typedef HRESULT (STDAPICALLTYPE *DllRegisterServerPtr)(); DllRegisterServerPtr funRegDll = (DllRegisterServerPtr)GetProcAddress(hMod,"DllRegisterServer"); if(funRegDll) { HRESULT hr=funRegDll(); if(FAILED(hr)) { SMessageBox(m_hWnd,_T("请使用管理员权限运行模块注册程序"),_T("注册表情COM失败"),MB_OK|MB_ICONSTOP); } else { SMessageBox(m_hWnd,_T("请重试"),_T("注册成功"),MB_OK|MB_ICONINFORMATION); } } FreeLibrary(hMod); } else { SMessageBox(m_hWnd,_T("没有找到表情COM模块[sosmiley.dll]。\\n现在注册吗"),_T("错误"),MB_OK|MB_ICONSTOP); } } } } else { SMessageBox(m_hWnd,_T("加载表情失败"),_T("错误"),MB_OK|MB_ICONSTOP); } pSource->Release(); } } }
HRESULT RichEditOleBase::InsertOleObject(IRichEditObjHost * pHost) { //insert this to host SComPtr<IOleObject> pOleObject; SComPtr<IOleClientSite> pClientSite; HRESULT hr = E_FAIL; REOBJECT reobject = {0}; SComPtr<IRichEditOle> ole; pHost->SendMessage(EM_GETOLEINTERFACE,0,(LPARAM)&ole); // Get site ole->GetClientSite(&pClientSite); SASSERT(pClientSite != NULL); SComPtr<IRichEditOleCallback> pCallback; hr=ole->QueryInterface(IID_IRichEditOleCallback,(void**)&pCallback); if(!SUCCEEDED(hr)) return E_FAIL; //get the IOleObject hr = QueryInterface(IID_IOleObject, (void**)&pOleObject); if (FAILED(hr)) { return E_FAIL; } //to insert into richedit, you need a struct of REOBJECT ZeroMemory(&reobject, sizeof(REOBJECT)); pOleObject->GetUserClassID(&reobject.clsid); pCallback->GetNewStorage(&reobject.pstg); reobject.cbStruct = sizeof(REOBJECT); reobject.cp = REO_CP_SELECTION; reobject.dvaspect = DVASPECT_CONTENT; reobject.dwFlags = REO_BELOWBASELINE; reobject.poleobj = pOleObject; reobject.polesite = pClientSite; hr = pOleObject->SetClientSite(pClientSite); if (SUCCEEDED(hr)) { PreInsertObject(reobject); // 给子类一个机会去修改reobject hr = ole->InsertObject(&reobject); m_chrContent.cpMin = pHost->GetContentLength() - 1; m_chrContent.cpMax = m_chrContent.cpMin + 1; } if(reobject.pstg) { reobject.pstg->Release(); } return hr; }
BOOL RichEditPara::GetLineRect(int nLineNo, CRect& rcLine) { rcLine.SetRectEmpty(); int ncpStart; int nLength; m_pObjectHost->SendMessage(EM_LINEINDEX, nLineNo, 0, (LRESULT*)&ncpStart); m_pObjectHost->SendMessage(EM_LINELENGTH, ncpStart, 0, (LRESULT*)&nLength); SComPtr<ITextRange> spRangeLine; ITextDocument * pdoc = m_pObjectHost->GetTextDoc(); pdoc->Range(ncpStart, ncpStart + nLength, &spRangeLine); if (!spRangeLine) { return FALSE; } CHARRANGE chr = {ncpStart, ncpStart + nLength}; // http://technet.microsoft.com/zh-cn/hh768766(v=vs.90) 新类型定义 #define _tomClientCoord 256 // 默认获取到的是屏幕坐标, Use client coordinates instead of screen coordinates. #define _tomAllowOffClient 512 // Allow points outside of the client area. long lTypeTopLeft = _tomAllowOffClient|_tomClientCoord|tomStart|TA_TOP|TA_LEFT; long lTypeRightBottom = _tomAllowOffClient|_tomClientCoord|tomEnd|TA_BOTTOM|TA_RIGHT; POINT ptEnd, ptStart; spRangeLine->GetPoint(lTypeTopLeft, &ptStart.x, &ptStart.y); spRangeLine->GetPoint(lTypeRightBottom, &ptEnd.x, &ptEnd.y); rcLine.SetRect(ptStart, ptEnd); if (rcLine.Width() == 0) { rcLine.right += 1; } return TRUE; }
SStringW SChatEdit::GetFormatText() { SStringW strTxt; TEXTRANGE txtRng; txtRng.chrg.cpMin =0; txtRng.chrg.cpMax = SSendMessage(WM_GETTEXTLENGTH); txtRng.lpstrText = (LPTSTR)strTxt.GetBufferSetLength(txtRng.chrg.cpMax); SSendMessage(EM_GETTEXTRANGE,0,(LPARAM)&txtRng); strTxt.ReleaseBuffer(); SComPtr<IRichEditOle> ole; SSendMessage(EM_GETOLEINTERFACE,0,(LPARAM)(void**)&ole); SStringW strMsg; int iPlainTxtBegin = 0; for(int i=0;i<strTxt.GetLength();i++) { if(strTxt[i] == 0xfffc) {//找到一个OLE对象 strMsg += strTxt.Mid(iPlainTxtBegin,i-iPlainTxtBegin); iPlainTxtBegin = i+1; REOBJECT reobj={sizeof(reobj),0}; reobj.cp = i; HRESULT hr = ole->GetObject( REO_IOB_USE_CP , &reobj, REO_GETOBJ_POLEOBJ); if(SUCCEEDED(hr) && reobj.poleobj) { if(reobj.clsid == CLSID_CSoSmileyCtrl) { SComPtr<ISoSmileyCtrl> smiley; hr = reobj.poleobj->QueryInterface(__uuidof(ISoSmileyCtrl), (void**)&smiley); if(SUCCEEDED(hr)) { SComPtr<ISmileySource> source; hr = smiley->GetSource(&source); SASSERT(SUCCEEDED(hr)); UINT uID = -1; SStringW strSmiley = L"<smiley"; if(SUCCEEDED(source->GetID(&uID))) { strSmiley += SStringW().Format(L" id=\"%d\"",uID); } BSTR strFile; if(SUCCEEDED(source->GetFile(&strFile))) { strSmiley += SStringW().Format(L" path=\"%s\"",strFile); ::SysFreeString(strFile); } strSmiley += L"/>"; strMsg += strSmiley; } } reobj.poleobj->Release(); } } } if(iPlainTxtBegin<strTxt.GetLength()) { strMsg += strTxt.Right(strTxt.GetLength()-iPlainTxtBegin); } return strMsg; }
int SChatEdit::_InsertFormatText(int iCaret,CHARFORMATW cf,pugi::xml_node xmlText,BOOL bCanUndo) { SStringW strText = xmlText.value(); if(xmlText.name() == KLabelSmiley) {//insert smiley SComPtr<ISoSmileyCtrl> pSmiley; HRESULT hr=::CoCreateInstance(CLSID_CSoSmileyCtrl,NULL,CLSCTX_INPROC,__uuidof(ISoSmileyCtrl),(LPVOID*)&pSmiley); if(FAILED(hr)) return 0; SComPtr<IRichEditOle> ole; if(SSendMessage(EM_GETOLEINTERFACE,0,(LPARAM)(void**)&ole) && ole) { SComPtr<IRichEditOleCallback> pCallback; hr=ole->QueryInterface(IID_IRichEditOleCallback,(void**)&pCallback); if(FAILED(hr)) return 0; SComPtr<ISmileyHost> host; hr = pCallback->QueryInterface(__uuidof(ISmileyHost),(void**)&host); if(FAILED(hr)) return 0; SComPtr<ISmileySource> pSource; hr = host->CreateSource(&pSource); if(FAILED(hr)) return 0; { UINT uID = xmlText.attribute(L"id").as_uint(-1); SStringW strPath = xmlText.attribute(L"path").value(); if(uID != -1) hr = pSource->LoadFromID(uID); else hr = pSource->LoadFromFile(strPath); if(SUCCEEDED(hr)) { pSmiley->SetSource(pSource); SSendMessage(EM_SETSEL,iCaret,iCaret); pSmiley->Insert2Richedit((DWORD_PTR)(void*)ole); } } } return SUCCEEDED(hr)?1:0; } CHARFORMATW cfNew = cf; cfNew.dwMask = 0; if(xmlText.name() == KLabelColor) { cfNew.crTextColor = StringToColor(xmlText.attribute(L"value").value()) & 0x00ffffff; cfNew.dwMask |= CFM_COLOR; }else if(xmlText.name()== KLabelFont) { wcscpy(cf.szFaceName,cfNew.szFaceName); wcscpy_s(cfNew.szFaceName,LF_FACESIZE-1,xmlText.attribute(L"value").value()); cfNew.dwMask |= CFM_FACE; }else if(xmlText.name()==KLabelUnderline) { cfNew.dwMask |=CFM_UNDERLINE; cfNew.dwEffects |= CFE_UNDERLINE; }else if(xmlText.name() == KLabelItalic) { cfNew.dwMask |=CFM_ITALIC; cfNew.dwEffects |= CFE_ITALIC; }else if(xmlText.name() == KLabelBold) { cfNew.dwMask |=CFM_BOLD; cfNew.dwEffects |= CFE_BOLD; }else if(xmlText.name() == KLabelStrike) { cfNew.dwMask |= CFM_STRIKEOUT; cfNew.dwEffects |= CFE_STRIKEOUT; }else if(xmlText.name() == KLabelLink) { cfNew.dwMask |= CFM_LINK; cfNew.dwEffects |= CFE_LINK; COLORREF cr = StringToColor(xmlText.attribute(L"color").value()); if(cr!=0) { cfNew.dwMask |= CFM_COLOR; cfNew.crTextColor = cr & 0x00ffffff; } }else if(xmlText.name() == KLabelSize) { cfNew.dwMask |= CFM_SIZE; HDC hdc=GetDC(NULL); LONG yPixPerInch = GetDeviceCaps(hdc, LOGPIXELSY); ReleaseDC(NULL,hdc); cfNew.yHeight = abs(MulDiv(xmlText.attribute(L"value").as_uint(12), LY_PER_INCH, yPixPerInch)); } int nRet = strText.GetLength(); SSendMessage(EM_REPLACESEL,bCanUndo,(LPARAM)(LPCWSTR)strText); int iEnd = iCaret + nRet; SSendMessage(EM_SETSEL,iCaret,iEnd); SSendMessage(EM_SETCHARFORMAT,SCF_SELECTION,(LPARAM)&cfNew); iCaret = iEnd; SSendMessage(EM_SETSEL,iCaret,iCaret); pugi::xml_node xmlChild = xmlText.first_child(); while(xmlChild) { int nSubLen = _InsertFormatText(iCaret,cfNew,xmlChild,bCanUndo); iCaret += nSubLen; nRet += nSubLen; xmlChild = xmlChild.next_sibling(); } if(cfNew.dwMask) { cf.dwMask = CFM_ALL; SSendMessage(EM_SETCHARFORMAT,SCF_SELECTION,(LPARAM)&cf); } return nRet; }