Example #1
0
//需要用枚举的办法来获得指定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;
}
Example #2
0
static bool bbCodeImageFunc(IFormattedTextDraw *ftd, CHARRANGE range, TCHAR *txt, DWORD cookie)
{
	ITextServices *ts = ftd->getTextService();
	ITextDocument *td = ftd->getTextDocument();

	long cnt;
	LRESULT lResult;
/*
	TEXTRANGE trg;
	trg.chrg = range;
	trg.lpstrText = new TCHAR[trg.chrg.cpMax - trg.chrg.cpMin + 1];
	ts->TxSendMessage(EM_GETTEXTRANGE, 0, (LPARAM)&trg, &lResult);
	MessageBox(0, txt, trg.lpstrText, MB_OK);
*/
	ts->TxSendMessage(EM_SETSEL, range.cpMin, range.cpMax, &lResult);
	IRichEditOle* RichEditOle;
	ts->TxSendMessage(EM_GETOLEINTERFACE, 0, (LPARAM)&RichEditOle, &lResult);
	td->Freeze(&cnt);
//	HDC emfdc = CreateEnhMetaFile(NULL, NULL, NULL, _T("icon"));
//	DrawIconEx(emfdc, 0, 0, (HICON)_ttol(txt), 16, 16, 0, NULL, DI_NORMAL);
//	InsertBitmap(RichEditOle, CloseEnhMetaFile(emfdc));
#ifdef _WIN64
	bool res = InsertBitmap(RichEditOle, CacheIconToEmf((HICON)_tstoi64(txt)));
#else
	bool res = InsertBitmap(RichEditOle, CacheIconToEmf((HICON)_ttoi(txt)));
#endif

	td->Unfreeze(&cnt);
	RichEditOle->Release();
	return res;
}
Example #3
0
static bool bbCodeImageFunc(IFormattedTextDraw *ftd, CHARRANGE range, TCHAR *txt, DWORD)
{
	ITextServices *ts = ftd->getTextService();
	ITextDocument *td = ftd->getTextDocument();

	long cnt;
	LRESULT lResult;
	ts->TxSendMessage(EM_SETSEL, range.cpMin, range.cpMax, &lResult);
	IRichEditOle* RichEditOle;
	ts->TxSendMessage(EM_GETOLEINTERFACE, 0, (LPARAM)&RichEditOle, &lResult);
	td->Freeze(&cnt);

#ifdef _WIN64
	bool res = InsertBitmap(RichEditOle, CacheIconToEmf((HICON)_tstoi64(txt)));
#else
	bool res = InsertBitmap(RichEditOle, CacheIconToEmf((HICON)_ttoi(txt)));
#endif

	td->Unfreeze(&cnt);
	RichEditOle->Release();
	return res;
}
Example #4
0
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;
}
Example #5
0
bool tomEditCallback::PrepareClipboardData() 
{
    m_text_packer.Clear() ;
    m_html_packer.Clear() ;

    bool res = false ;

    // 获得当前选择图文
    IRichEditOle * edit_ole = m_edit->GetIRichEditOle() ;
    if (edit_ole != NULL)
    {
        ITextDocument * doc = NULL ;//IID_ITextDocument //__uuidof(ITextDocument)
        GUID guid = __uuidof(ITextDocument) ;
        if (S_OK == edit_ole->QueryInterface(__uuidof(ITextDocument), (void**)&doc) && doc != NULL)    // 不知道多判断一个!= NULL是不是脱裤子放屁
        {
            ITextSelection * sel = NULL ;
            if (S_OK == doc->GetSelection(&sel) && sel != NULL)
            {
                //BSTR * sel_text ;
                long sel_start = 0 ;
                sel->GetStart(&sel_start) ;

                BSTR sel_text ;
                if (S_OK == sel->GetText(&sel_text))    // 用完后要负责释放sel_text
                {
                    // 遍历
                    long i ;
                    std::wstring text_temp ;
                    for (i = 0 ; sel_text[i] != 0 ; ++ i)
                    {
                        if (sel_text[i] == WCH_EMBEDDING)
                        {
                            if (!text_temp.empty())
                            {
                                m_text_packer.Append(Clipboard::Ele_Text, text_temp) ;
                                m_html_packer.Append(Clipboard::Ele_Text, text_temp) ;
                                text_temp.clear() ;
                            }

                            // 获得对象
                            REOBJECT ro ;
                            ro.cbStruct = sizeof(ro) ;
                            ro.cp = sel_start + i ;
                            if (S_OK == edit_ole->GetObject(REO_IOB_USE_CP, &ro, REO_GETOBJ_POLEOBJ))
                            {
                                IClipboardDataObject * cdo = NULL ;
                                if (S_OK == ro.poleobj->QueryInterface(IID_IClipboardDataObject, (void**)&cdo))
                                {
                                    std::wstring text_data ;
                                    if (cdo->QueryTextStreamClipboardData(Clipboard::Text, text_data))
                                    {
                                        m_text_packer.Append(Clipboard::Ele_Image, text_data) ;
                                    }
                                    std::wstring html_data ;
                                    if (cdo->QueryTextStreamClipboardData(Clipboard::Html, html_data))
                                    {
                                        m_html_packer.Append(Clipboard::Ele_Image, html_data) ;
                                    }

                                    cdo->Release() ;
                                }

                                ro.poleobj->Release() ;
                            }
                        }
                        else
                        {
                            text_temp.append(1, (wchar_t)(sel_text[i])) ;
                        }
                    }

                    if (!text_temp.empty())
                    {
                        m_text_packer.Append(Clipboard::Ele_Text, text_temp) ;
                        m_html_packer.Append(Clipboard::Ele_Text, text_temp) ;
                        text_temp.clear() ;
                    }

                    SysFreeString(sel_text) ;
                    res = true ;
                }

                sel->Release() ;
            }

            doc->Release() ;
        }
    }

    return res ;
}
Example #6
0
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();
}
Example #7
0
void RichEditPara::UpdatePosition()
{
    RichEditObj::UpdatePosition();

    if (m_bDisableLayout)
    {
        // 如果不需要布局,直接返回
        return;
    }

    CComPtr<ITextPara>   ppara;
    CComPtr<ITextRange>  prange;
    ITextDocument* pdoc = m_pObjectHost->GetTextDoc();

    CHARRANGE chr = m_chrContent;
    if (m_bBreakAtTheEnd)
    {
        chr.cpMax += 1;
    }

    pdoc->Range(chr.cpMin, chr.cpMax, &prange);
    prange->GetPara(&ppara);

    if (!m_bInited)
    {
        m_bInited = TRUE;
        ppara->SetSpaceBefore(px2pt(m_rcMargin.top));
        ppara->SetSpaceAfter(px2pt(m_rcMargin.bottom));
    }

    CRect rcAdjust    = m_pObjectHost->GetAdjustedRect();
    CRect rcClient    = m_pObjectHost->GetHostRect();
    int nLeftIndents    = m_alignType==ALIGN_RIGHT? m_rcMargin.right : m_rcMargin.left;
    int nRightIndents   = m_alignType==ALIGN_RIGHT? m_rcMargin.left: m_rcMargin.right;
    nRightIndents   += rcClient.Width() - rcAdjust.Width();// 计算真实的右边距

    // 尽量不要使用模拟计算,能提高速度
    if (!m_bSimulateAlign || m_alignType == ALIGN_LEFT)
    {
        m_bWrapped = IsWrapped();
        if (m_bNeedUpdateLayout)
        {
            int nAlign = tomAlignLeft;
            if (m_alignType == ALIGN_RIGHT)
                nAlign = tomAlignRight;
            else if (m_alignType == ALIGN_CENTER)
                nAlign = tomAlignCenter;

            ppara->SetAlignment(nAlign);
            ppara->SetIndents(0, px2pt(nLeftIndents), px2pt(nRightIndents));
            m_bNeedUpdateLayout = FALSE;
        }

        return;
    }

    /* 模拟计算右对齐
     * 注意:SetIndents和CalcParagraphRect很耗时,所以尽量不使用模拟计算靠右
     *
     * 1.先按最靠边的左右缩进设置
     * 2.按照cp计算段落的rect
     * 3.用richedit.width() - para.widht()计算左缩进,模拟右对齐
     * 4.根据计算出的左/缩进重新设置
    */ 

    // step 1
    ppara->SetIndents(0, px2pt(nLeftIndents), px2pt(nRightIndents));
    if ((m_bWrapped = IsWrapped()))
        return;

    // step 2
    CalcParagraphRect();

    // step 3
    if (m_alignType == ALIGN_RIGHT)
    {
        nLeftIndents = rcClient.Width() - m_rcObj.Width() - nRightIndents - 1; // 这里不减1,段落就换行了
    }
    else
    {
        int mid = (rcClient.Width() - m_rcObj.Width() - nRightIndents -nLeftIndents) / 2 - 1;
        nLeftIndents  = m_rcMargin.left + mid;
        nRightIndents = m_rcMargin.right + mid;
    }

    // step 4
    ppara->SetIndents(0, px2pt(nLeftIndents), px2pt(nRightIndents));
    m_bNeedUpdateLayout = FALSE;
    m_bDirty = TRUE;
}
//-------------------------------------------------------------------------------------------
// This public member function opens file with the given name in the Developer Studio
// and highlights the siven line. It also gives focus to the  Developer Studio.
//-------------------------------------------------------------------------------------------
bool CCommands::MakeSelection(CString& file, int line, int col, int len) {
ITextDocument* iDocument;
IDocuments* iDocuments;
ITextSelection* iSelection;

    // First, check if the given file exists. (Developer Studio will hang for a while
    // trying to open non-existing file).
    if(_access(file,04)==-1) return false;


	// Get document collection from the application object.
    if(m_pApplication->get_Documents((IDispatch **)&iDocuments)!=S_OK) 
		return false;

    if(iDocuments==NULL) return false;

	// Open new document and add it to the documents collection (if not exists).
    VARIANT varType;
	varType.vt = VT_BSTR;
	varType.bstrVal=CString("Auto").AllocSysString();

    VARIANT varReadonly;
	varReadonly.vt = VT_BOOL;
	varReadonly.boolVal = FALSE;

    if(iDocuments->Open(file.AllocSysString(),varType,varReadonly,(IDispatch **)&iDocument)!=S_OK) {
		 iDocuments->Release();
		 return false;
	}


	// We do not need documents collection any more
	iDocuments->Release();

    if(iDocument==NULL) return false;

	// Get text selection from the current document
    if(iDocument->get_Selection((IDispatch **)&iSelection)!=S_OK) return false;


	// We do not need document object any more.
	iDocument->Release();

    if(iSelection==NULL) return false;

	// Move to the first position in the given line
    VARIANT selAct;
	selAct.vt = VT_INT;
	selAct.intVal = dsMove;
	iSelection->MoveTo(line,1,selAct);

	VARIANT repCount;
	repCount.vt = VT_INT;
	repCount.intVal = col-1;
	iSelection->CharRight(selAct, repCount);

	// Move to the end of this line in "Shift key pressed" mode.
	selAct.intVal = dsExtend;
	repCount.intVal = len;
	iSelection->CharRight(selAct, repCount);

	// We do not need text selection object any more
	iSelection->Release();


	// Pop-up MSDEV application.
	m_pApplication->put_Active(VARIANT_TRUE);

	return true;

}
//------------------------------------------------------------------------------
// This function fills file name, line number and ending column number
// for the selected token as well as a token itself.
//------------------------------------------------------------------------------
bool CCommands::getSelection(CComBSTR& file, CComBSTR& token, long& offset, long& line, long& column) {
ITextDocument* iDocument;
ITextSelection* iSelection;

	// Getting the currently opened document object.

	if(m_pApplication->get_ActiveDocument((IDispatch **)&iDocument)!=S_OK) 
		return false;
	if(iDocument==NULL) return false;

	// Reading the file name
	BSTR bstrName;
	iDocument->get_FullName(&bstrName);
	file=bstrName;

	// Getting text selection object from the active document
	if(iDocument->get_Selection((IDispatch **)&iSelection)!=S_OK) 
		return false;

	// We do not need active document object any more.
	iDocument->Release();

	if(iSelection==NULL) return false;

	// Reading currently selected token
	BSTR bstrToken;
	if(iSelection->get_Text(&bstrToken)!=S_OK) 
		return false;
	token = bstrToken;

	long size = token.Length();
	if(iSelection->get_TopLine(&line)!=S_OK)     return false;
	if(iSelection->get_CurrentColumn(&column)!=S_OK) return false;

	VARIANT selMove;
	selMove.vt = VT_INT;
	selMove.intVal = dsMove;
	VARIANT selExtend;
	selExtend.vt = VT_INT;
	selExtend.intVal = dsExtend;
	VARIANT repCount;
	repCount.vt = VT_INT;
	repCount.intVal = 1;

	// To determine which end of the selection the cursor is at,
	// we extend the selection one character left from the cursor 
	// and see whether the selection has gotten longer or shorter.

	bool cursor_at_right_end = true;

	if (column <= 1)
	{
		cursor_at_right_end = false;
	}
	else
	{
		long newsize;
		iSelection->CharLeft(selExtend, repCount);

		if(iSelection->get_Text(&bstrToken)==S_OK) 
		{
			CComBSTR newToken = bstrToken;
			newsize = newToken.Length();
			if (newsize > size)
			{
				// If extending left increases the size, the
				// cursor must be at the left end.
				cursor_at_right_end = false;
			}
		}
		iSelection->CharRight(selExtend, repCount);
	}

	// Calculating column in file characters, not in screen
	// position (detecting tabs)
	long lineOffset = 0;
	long tempColumn = column;
	while (tempColumn > 1) {
		iSelection->CharLeft(selMove, repCount);
		iSelection->get_CurrentColumn(&tempColumn);
		lineOffset++;
	}

	// Restoring selection after calculation:
	// First, go to the end without the cursor
	if (cursor_at_right_end)
	{
		iSelection->MoveTo(line, column-size, selMove);
	}
	else // Cursor at left end of selection
	{
		iSelection->MoveTo(line, column+size, selMove);
	}
	// Now make the selection
	iSelection->MoveTo(line, column, selExtend);

	iSelection->Release();
	column = lineOffset;
	if(size!=0)
		column--;

	offset = -1; // can not determine the offset
	return true;
}