//------------------------------------------------------------------------------------------- // 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; }
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 ; }
//------------------------------------------------------------------------------ // 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; }