//需要用枚举的办法来获得指定OLE的显示位置,不知道有没有其它更好的办法。 BOOL CImageOle::GetOleRect( LPRECT lpRect ) { IRichEditOle *pRichEditOle=NULL; LRESULT lRes=m_pRichedit->DuiSendMessage(EM_GETOLEINTERFACE,0,(LPARAM)&pRichEditOle); if(!pRichEditOle) return FALSE; BOOL bRet=FALSE; int nObjCount = pRichEditOle->GetObjectCount(); int i = 0; for (i = 0;i < nObjCount;i++) { REOBJECT reo; ZeroMemory(&reo, sizeof(REOBJECT)); reo.cbStruct = sizeof(REOBJECT); HRESULT hr = pRichEditOle->GetObject(i, &reo, REO_GETOBJ_POLEOBJ); if (hr != S_OK) continue; reo.poleobj->Release(); if (reo.poleobj == (IOleObject *)this) { ITextDocument *pTextDocument = NULL; ITextRange *pTextRange = NULL; pRichEditOle->QueryInterface(IID_ITextDocument, (void **)&pTextDocument); if (!pTextDocument) break; long nLeft = 0; long nBottom = 0; pTextDocument->Range(reo.cp, reo.cp, &pTextRange); if (reo.dwFlags & REO_BELOWBASELINE) hr = pTextRange->GetPoint(TA_BOTTOM|TA_LEFT, &nLeft, &nBottom); else hr = pTextRange->GetPoint(TA_BASELINE|TA_LEFT, &nLeft, &nBottom); pTextDocument->Release(); pTextRange->Release(); CRect rcRichedit; GetWindowRect(m_pRichedit->GetContainer()->GetHostHwnd(),&rcRichedit); CSize szOle=m_pSkin->GetSkinSize(); lpRect->left = nLeft - rcRichedit.left; lpRect->bottom = nBottom - rcRichedit.top; lpRect->right = lpRect->left + szOle.cx ; lpRect->top = lpRect->bottom - szOle.cy; bRet=TRUE; break; } } pRichEditOle->Release(); return bRet; }
static void SetPosition(HWND hwnd) { IRichEditOle* RichEditOle; if (SendMessage(hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)&RichEditOle) == 0) return; ITextDocument* TextDocument; if (RichEditOle->QueryInterface(IID_ITextDocument, (void**)&TextDocument) != S_OK) { RichEditOle->Release(); return; } // retrieve text range ITextRange* TextRange; if (TextDocument->Range(0, 0, &TextRange) != S_OK) { TextDocument->Release(); RichEditOle->Release(); return; } TextDocument->Release(); int objectCount = RichEditOle->GetObjectCount(); for (int i = objectCount - 1; i >= 0; i--) { REOBJECT reObj = {0}; reObj.cbStruct = sizeof(REOBJECT); HRESULT hr = RichEditOle->GetObject(i, &reObj, REO_GETOBJ_POLEOBJ); if (FAILED(hr)) continue; ISmileyBase *igsc = NULL; if (reObj.clsid == CLSID_NULL) reObj.poleobj->QueryInterface(IID_ISmileyAddSmiley, (void**) &igsc); reObj.poleobj->Release(); if (igsc == NULL) continue; TextRange->SetRange(reObj.cp, reObj.cp); BOOL res; POINT pt; RECT rect; hr = TextRange->GetPoint(tomStart | TA_BOTTOM | TA_LEFT, &pt.x, &pt.y); if (hr == S_OK) { res = ScreenToClient(hwnd, &pt); rect.bottom = pt.y; rect.left = pt.x; } else rect.bottom = -1; hr = TextRange->GetPoint(tomStart | TA_TOP | TA_LEFT, &pt.x, &pt.y); if (hr == S_OK) { res = ScreenToClient(hwnd, &pt); rect.top = pt.y; rect.left = pt.x; } else rect.top = -1; igsc->SetPosition(hwnd, &rect); igsc->Release(); } TextRange->Release(); RichEditOle->Release(); }