📄 tomrange.cpp
字号:
#endif
}
/*
* CTxtRange::Cut (pVar)
*
* @mfunc
* Cut the plain and/or rich text to a data object and return the
* object ptr in <p pVar>. If <p pVar> is null,
* cut to the clipboard.
*
* @rdesc
* HRESULT = (if success) ? NOERROR : E_OUTOFMEMORY
*/
STDMETHODIMP CTxtRange::Cut (
VARIANT * pVar) //@parm Out parm for data object
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::Cut");
if(IsZombie())
return CO_E_RELEASED;
CCallMgr callmgr(GetPed());
if( WriteAccessDenied())
return E_ACCESSDENIED;
HRESULT hr = Copy(pVar);
Replacer(0, NULL);
return hr;
}
/*
* CTxtRange::Delete (Unit, Count, pDelta)
*
* @mfunc
* If this range is nondegenerate, delete it along with |Count| - 1 Units
* in the direction specified by the sign of Count. If this range is
* degenerate, delete Count Units.
*
* @rdesc
* HRESULT = (WriteAccessDenied) ? E_ACCESSDENIED :
* (all requested Units deleted) ? NOERROR : S_FALSE
*/
STDMETHODIMP CTxtRange::Delete (
long Unit, //@parm Unit to use
long Count, //@parm Number of chars to delete
long * pDelta) //@parm Out parm to receive count of units deleted
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::Delete");
if(pDelta)
*pDelta = 0;
if(IsZombie())
return CO_E_RELEASED;
CCallMgr callmgr(GetPed());
if( WriteAccessDenied())
return E_ACCESSDENIED;
LONG cchSave = _cch; // Remember initial count
LONG cchText = GetAdjustedTextLength();
LONG CountOrg = Count;
LONG cpMin, cpMost;
LONG cUnit = 0; // Default no Units
MOVES Mode = (Count >= 0) ? MOVE_END : MOVE_START;
GetRange(cpMin, cpMost);
if(cpMost > cchText) // Can't delete final CR. To get
{ // *pDelta right, handle here
Set(cpMin, cpMin - cchText); // Backup before CR & set active
if(Count > 0) // end at cpMin since there's
{ // nothing to delete forward
Count = 0;
if(!_cch) // Only collapsed selection of
Mode = MOVE_IP; // final CR: set up nothing
} // deleted (MOVE_IP = 0)
}
if(Count)
{
if((_cch ^ Mode) < 0) // Be sure active end is in
FlipRange(); // deletion direction
if(cchSave) // Deleting nondegenerate range
Count -= Mode; // counts as one unit
if(Mover(Unit, Count, &cUnit, Mode) // Try to expand range for
== E_INVALIDARG) // remaining Count Units
{
if(pDelta)
*pDelta = 0;
return E_INVALIDARG;
}
if(GetCp() > cchText && cUnit > 0) // Range includes final CR, which
{ // cannot be deleted. Reduce
if(Unit == tomCharacter) // counts for some Units
cUnit -= GetTextLength() - cchText;
else if(Unit == tomWord)
cUnit--; // An EOP qualifies as a tomWord
}
}
if(cchSave) // Deleting nondegenerate range
cUnit += Mode; // counts as a Unit
if(pDelta)
*pDelta = cUnit;
if(_cch) // Mover() may have changed _cch
{
CGenUndoBuilder undobldr(GetPed(), UB_AUTOCOMMIT);
undobldr.StopGroupTyping();
// FUTURE (murrays): the cchSave case should set up undo to
// restore the original range, not the extended range resulting
// when |CountOrg| > 1. This could be done using two calls to
// ReplaceRange(), one to delete the original range and one to
// delete the rest
SELRR selrr = !_fSel || cchSave ? SELRR_REMEMBERRANGE :
CountOrg > 0 ? SELRR_REMEMBERCPMIN :
SELRR_REMEMBERENDIP;
ReplaceRange(0, NULL, &undobldr, selrr);
if (cUnit == CountOrg || // Delete(Unit,0,0)
cUnit == 1 && !CountOrg) // deletes one "Unit", namely
{ // what's selected
return NOERROR; // Signal everything deleted as
} // requested
}
else if(cchSave) // Collapsed selection of final CR
{ // but didn't delete anything
Update(TRUE); // Selection highlighting changed
}
return S_FALSE; // Less deleted than requested
}
/*
* CTxtRange::EndOf (Unit, Extend, pDelta)
*
* @mfunc
* Move this range end(s) to end of the first overlapping Unit in
* the range.
*
* @rdesc
* HRESULT = (if change) ? NOERROR :
* (if Unit supported) ? S_FALSE : E_NOTIMPL
*/
STDMETHODIMP CTxtRange::EndOf (
long Unit, //@parm Unit to use
long Extend, //@parm If true, leave other end alone
long * pDelta) //@parm Count of chars that End is moved
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::EndOf");
CCallMgr callmgr(GetPed());
LONG cpMost;
HRESULT hr = Expander (Unit, Extend, pDelta, NULL, &cpMost);
if(hr == NOERROR)
{
Update(TRUE); // Update selection
}
return hr;
}
/*
* CTxtRange::Expand (Unit, pDelta)
*
* @mfunc
* Expand this range so that any partial Units it contains are
* completely contained. If this range consists of one or more full
* Units, no change is made. If this range is an insertion point at
* the beginning or within a Unit, Expand() expands this range to include
* that Unit. If this range is an insertion point at the end of the
* story, Expand() tries to set this range to include the last Unit in
* the story. The active end is always cpMost except for the last case.
*
* @rdesc
* HRESULT = (if change) ? NOERROR :
* (if Unit supported) ? S_FALSE : E_NOTIMPL
*/
STDMETHODIMP CTxtRange::Expand (
long Unit, //@parm Unit to expand range to
long * pDelta) //@parm Out parm to receive count of chars added
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::Expand");
CCallMgr callmgr(GetPed());
LONG cpMin, cpMost;
HRESULT hr = Expander (Unit, TRUE, pDelta, &cpMin, &cpMost);
if(hr == NOERROR)
{
Update(TRUE); // Update selection
}
return hr;
}
/*
* CTxtRange::FindText (bstr, cch, Flags, pLength)
*
* @mfunc
* If this range isn't an insertion point already, convert it into an
* insertion point at its End if <p cch> <gt> 0 and at its Start if
* <p cch> <lt> 0. Then search up to <p cch> characters of the range
* looking for the string <p bstr> subject to the compare flags
* <p Flags>. If <p cch> <gt> 0, the search is forward and if <p cch>
* <lt> 0 the search is backward. If the string is found, the range
* limits are changed to be those of the matched string and *<p pLength>
* is set equal to the length of the string. If the string isn't found,
* the range remains unchanged and *<p pLength> is set equal to 0.
*
* @rdesc
* HRESULT = (if <p bstr> found) ? NOERROR : S_FALSE
*
* @devnote
* Argument validation of the three Find methods is done by the helper
* function CTxtRange::Finder(bstr, cch, dwFlags, pDelta, fExtend, fFlip)
*/
STDMETHODIMP CTxtRange::FindText (
BSTR bstr, //@parm String to find
long Count, //@parm Max count of chars to search
long Flags, //@parm Flags governing compares
long * pDelta) //@parm Out parm to receive count of chars moved
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::FindText");
return Finder(bstr, Count, Flags, pDelta, MOVE_IP);
}
/*
* CTxtRange::FindTextEnd (bstr, cch, Flags, pLength)
*
* @mfunc
* Starting from this range's End, search up to <p cch> characters
* looking for the string <p bstr> subject to the compare flags
* <p Flags>. If <p cch> <gt> 0, the search is forward and if <p cch>
* <lt> 0 the search is backward. If the string is found, the range
* limits are changed to be those of the matched string and *<p pLength>
* is set equal to the length of the string. If the string isn't found,
* the range remains unchanged and *<p pLength> is set equal to 0.
*
* @rdesc
* HRESULT = (if <p bstr> found) ? NOERROR : S_FALSE
*/
STDMETHODIMP CTxtRange::FindTextEnd (
BSTR bstr, //@parm String to find
long Count, //@parm Max count of chars to search
long Flags, //@parm Flags governing compares
long * pDelta) //@parm Out parm to receive count of chars moved
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::FindTextEnd");
return Finder(bstr, Count, Flags, pDelta, MOVE_END);
}
/*
* CTxtRange::FindTextStart (bstr, cch, Flags, pDelta)
*
* @mfunc
* Starting from this range's Start, search up to <p cch> characters
* looking for the string <p bstr> subject to the compare flags
* <p Flags>. If <p cch> <gt> 0, the search is forward and if <p cch>
* <lt> 0 the search is backward. If the string is found, the range
* limits are changed to be those of the matched string and *<p pLength>
* is set equal to the length of the string. If the string isn't found,
* the range remains unchanged and *<p pLength> is set equal to 0.
*
* @rdesc
* HRESULT = (if <p bstr> found) ? NOERROR : S_FALSE
*/
STDMETHODIMP CTxtRange::FindTextStart (
BSTR bstr, //@parm String to find
long Count, //@parm Max count of chars to search
long Flags, //@parm Flags governing compares
long * pDelta) //@parm Out parm to receive count of chars moved
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::FindTextStart");
return Finder(bstr, Count, Flags, pDelta, MOVE_START);
}
/*
* CTxtRange::GetChar (pChar)
*
* @mfunc
* Set *<p pChar> equal to the character at cpFirst
*
* @rdesc
* HRESULT = (<p pChar>) NOERROR ? E_INVALIDARG
*
* @devnote
* This method is very handy for walking a range character by character
* from the Start. Accordingly, it's desirable that the active end
* is at the Start. We set this up for a range, since the API doesn't
* care which range end is active. But we can't do this for a selection,
* since the selection API depends on the active end.
*/
STDMETHODIMP CTxtRange::GetChar (
long * pChar) //@parm Out parm for char
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::GetChar");
HRESULT hr = GetLong(0, pChar);
if(hr != NOERROR)
return hr;
if(_cch > 0) // Active end at cpMost (End)
{
if(_fSel)
{
CTxtPtr tp(_rpTX); // For selection, can't change
tp.AdvanceCp(-_cch); // active end
*pChar = (long)(tp.GetChar());
return NOERROR;
}
FlipRange(); // For range, it's more efficient
} // to work from cpFirst and API
*(DWORD *)pChar = _rpTX.GetChar(); // doesn't expose RichEdit active
// end
return NOERROR;
}
/*
* CTxtRange::GetDuplicate (ppRange)
*
* @mfunc
* Get a clone of this range object. For example, you may want to
* create an insertion point to traverse a range, so you clone the
* range and then set the clone's cpLim equal to its cpFirst. A range
* is characterized by its cpFirst, cpLim, and the story it belongs to.
*
* @rdesc
* HRESULT = (if success) ? NOERROR :
* (<p ppRange>) ? E_OUTOFMEMORY : E_INVALIDARG
*
* @comm
* Even if this range is a selection, the clone returned is still only
* a range.
*/
STDMETHODIMP CTxtRange::GetDuplicate (
ITextRange ** ppRange) //@parm Out parm to receive duplicate of range
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::GetDuplicate");
HRESULT hr = GetLong(NULL, (LONG *)ppRange);
if(hr != NOERROR)
return hr;
ITextRange *prg = new CTxtRange(*this);
if(prg)
{
*ppRange = prg;
prg->AddRef();
return NOERROR;
}
return E_OUTOFMEMORY;
}
/*
* ITextRange::GetEmbeddedObject (ppV)
*
* @mfunc
* Property get method that gets a ptr to the object at cpFirst
*
* @rdesc
* HRESULT = (!ppV) ? E_INVALIDARG :
* (object found) ? NOERROR : S_FALSE
*/
STDMETHODIMP CTxtRange::GetEmbeddedObject (
IUnknown **ppV) //@parm Out parm to receive embedded object
{
HRESULT hr = GetLong(NULL, (LONG *)ppV);
if(hr != NOERROR)
return hr;
if(GetObjectCount())
{
COleObject *pobj = GetPed()->_pobjmgr->GetObjectFromCp(GetCpMin());
if(pobj && (*ppV = pobj->GetIUnknown()) != NULL)
{
(*ppV)->AddRef();
return NOERROR;
}
}
return S_FALSE;
}
/*
* CTxtRange::GetEnd (pcpLim)
*
* @mfunc
* Get this range's End (cpMost) cp
*
* @rdesc
* HRESULT = (<p pcpLim>) ? NOERROR : E_INVALIDARG
*/
STDMETHODIMP CTxtRange::GetEnd (
long * pcpLim) //@parm Out parm to receive End cp value
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::GetEnd");
return GetLong(GetCpMost(), pcpLim);
}
/*
* CTxtRange::GetFont (ppFont)
*
* @mfunc
* Get an ITextFont object with the character attributes of this range
*
* @rdesc
* HRESULT = <p ppFont> ? NOERROR : E_INVALIDARG
*/
STDMETHODIMP CTxtRange::GetFont (
ITextFont ** ppFont) //@parm Out parm to receive ITextFont object
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::GetFont");
HRESULT hr = GetLong(NULL, (LONG *)ppFont);
if(hr != NOERROR)
return hr;
*ppFont = (ITextFont *) new CTxtFont(this);
return *ppFont ? NOERROR : E_OUTOFMEMORY;
}
/*
* CTxtRange::GetFormattedText (ppRange)
*
* @mfunc
* Retrieves an ITextRange with this range's formatted text.
* If <p ppRange> is NULL, the clipboard is the target.
*
* @rdesc
* HRESULT = (if success) ? NOERROR :
* (<p ppRange>) ? E_OUTOFMEMORY : E_INVALIDARG
*/
STDMETHODIMP CTxtRange::GetFormattedText (
ITextRange ** ppRange) //@parm Out parm to receive formatted text
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::GetFormattedText");
return GetDuplicate(ppRange);
}
/*
* CTxtRange::GetIndex (Unit, pIndex)
*
* @mfunc
* Set *<p pIndex> equal to the Unit number at this range's cpFirst
*
* @rdesc
* HRESULT = (!<p pIndex>) ? E_INVALIDARG :
* (Unit not implemented) ? E_NOTIMPL :
* (Unit available) ? NOERROR : S_FALSE
* @future
* implement tomWindow?
*/
STDMETHODIMP CTxtRange::GetIndex (
long Unit, //@parm Unit to index
long * pIndex) //@parm Out parm to receive index value
{
TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::GetIndex");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -