📄 richtexthandling.c
字号:
if (!( PC && pt_ctx && (t_CRSR.puc_location ? t_CRSR.pt_item &&
t_CRSR.us_recLength : TRUE)))
return eus_ERR_INVLD_ARG;
//PGP development shortcut: skip all the complexity of doing this with a
// virtual start point
if ((t_CRSR.puc_location ? t_CRSR.pt_item->i_type != mi_ACTUAL : FALSE) ||
pt_ctx->ul_ActualFrontier ==
mul_FRONTIER_NO_MORE)
return eus_ERR_INVLD_ARG;
//If we haven't already, get handles on the undocumented Notes API calls
// needed to sign the compiled formula with the current user ID. It is not
// necessary to unload the DLL loaded herein with the LoadLibrary() call
// because the normal process shutdown will force the unload when the time
// comes. So we might as well maintain the load-state for the duration of
// the session.
if (!h_dll) {
if (!( h_dll = LoadLibrary( "nnotes.dll")))
return !eus_SUCCESS;
pr_NSFBeginSignature = GetProcAddress( h_dll, "NSFBeginSignature");
pr_NSFMemorySign = GetProcAddress( h_dll, "NSFMemorySign");
pr_NSFEndSignature = GetProcAddress( h_dll, "NSFEndSignature");
if (!( pr_NSFBeginSignature && pr_NSFMemorySign &&
pr_NSFEndSignature)) {
FreeLibrary( h_dll);
return !eus_SUCCESS;
}
} //if (!h_dll)
//compile the provided formula
if (us_err = NSFFormulaCompile( NULL, NULL, PC, (WORD) strlen( PC),
&h_frmla, &us_lenFrmla,
&us, &us, &us, &us, &us))
return us_err;
//construct signature against the compiled formula
if (us_err = pr_NSFBeginSignature( &h_preSig))
goto errJump;
if (us_err = pr_NSFMemorySign( h_preSig, puc_frmla = OSLockObject(
h_frmla), us_lenFrmla))
goto errJump;
if (us_err = pr_NSFEndSignature( h_preSig, &h_sig, &us_lenSig))
goto errJump;
h_preSig = NULL;
//virtualize up to where the hotspot-begin CD record is to be written
if (t_CRSR.pt_item) {
if (us_err = us_VirtualizeThruActualLocation( t_CRSR.puc_location,
pt_ctx, NULL))
goto errJump;
}else
if (us_err = us_VirtualizeRestOfRtf( pt_ctx, NULL))
goto errJump;
//complete the hotspot-begin CD record
t_HotspotBegin.DataLength = us_lenFrmla;
t_HotspotBegin.Header.Length = (us = sizeof( CDHOTSPOTBEGIN) +
us_lenFrmla + sizeof( WORD) + us_lenSig);
//obtain the location where the record may be written, and write the record
if (us_err = us_GetVirtualCdRecAppendPointer( pt_ctx, us, &puc))
goto errJump;
memcpy( puc, &t_HotspotBegin, sizeof( CDHOTSPOTBEGIN));
memcpy( puc += sizeof( CDHOTSPOTBEGIN), puc_frmla, us_lenFrmla);
*(WORD *) (puc += us_lenFrmla) = us_lenSig;
memcpy( puc + sizeof( WORD), OSLockObject( h_sig), us_lenSig);
OSUnlockObject( h_sig);
//done with the virtualization, update the variable that tracks the length
// of the virtual item being written to
pt_ctx->pt_endVirtual->ul_length += pt_ctx->pt_endVirtual->ul_length % 2 +
us;
errJump:
if (h_sig)
OSMemFree( h_sig);
if (puc_frmla)
OSUnlockObject( h_frmla);
if (h_preSig)
OSMemFree( h_preSig);
OSMemFree( h_frmla);
return us_err;
} //eus_StartFormulaActionHotspot(
/** f_CursorToHotspotEnd( ***
Move cursor positioned at the beginning of a hotspot to the CD record marking
the end of the hotspot.
--- parameters & return ----
pt_crsr: Input & Output. Pointer to the cursor to be advanced. Output is either
an advanced cursor or a cursor whose item pointer is nullified to indicate
that no ensuing CD records are available.
pt_CTX: Optional Input. Pointer to the context of the rich-text information
being navigated. If passed in null, the cursor will not travel
automatically from a virtual or semi-virtual rich-text item to an ensuing
actual rich-text item.
pf_LeftSemiVirtuality: Optional Output. Pointer to the flag in which to store
whether the cursor has advanced out of semi-virtual rich-text content. If
passed in null, the procedure will ignore this functionality.
pf_ItemGotLocked: Optional. Pointer to the flag in which to store whether a
rich-text item was newly locked in the course of this procedure. If passed
in null, the procedure will ignore this functionality.
RETURN: TRUE if the corresponding hotspot-end record was located; FALSE
otherwise
--- side effect ------------
The rich-text environment information pointed to by pt_crsr or pt_CTX may be
adjusted due to cursor advancement.
--- revision history -------
9/6/02 PR: listing format adjustment, minor token renaming, documentation
adjustment
3/20/00 PR: created */
static BOOL f_CursorToHotspotEnd( CdRecordCursor *const pt_crsr,
const RtfTrackingInfo *const pt_CTX,
BOOL *const pf_LeftSemiVirtuality,
BOOL *const pf_ItemGotLocked) {
_ASSERTE( pt_crsr && pt_crsr->puc_location && pt_crsr->pt_item &&
pt_crsr->us_recLength &&
*pt_crsr->puc_location ==
LOBYTE( SIG_CD_HOTSPOTBEGIN));
//as applicable, indicate as a default that semi-virtuality has not been
// left and the memory associated with an item different from the current
// item has not been locked
if (pf_LeftSemiVirtuality)
*pf_LeftSemiVirtuality = FALSE;
if (pf_ItemGotLocked)
*pf_ItemGotLocked = FALSE;
do {
//advance the cursor to the next CD record
AdvanceCdCursor( pt_crsr, pt_CTX, pf_LeftSemiVirtuality,
pf_ItemGotLocked);
//If no more CD records are available in the rich-text field or if a
// hotspot-begin CD record is encountered, we have a weird situation
// where another hotspot-begin CD record is found before a
// corresponding hotspot-end CD record. This can be a valid
// configuration, but we aren't sophisticated enough yet to handle the
// situation.
if (!pt_crsr->pt_item || LOBYTE( SIG_CD_HOTSPOTBEGIN) ==
*pt_crsr->puc_location)
return FALSE;
} while (LOBYTE( SIG_CD_HOTSPOTEND) != *pt_crsr->puc_location);
return TRUE;
} //f_CursorToHotspotEnd(
/** eus_RemoveRtSpan( ***
--- parameters & return ----
RETURN: eus_SUCCESS if no error occured; the Notes API error code otherwise
--- revision history -------
12/13/98 PR: created */
//DOC!!
STATUS eus_RemoveRtSpan( const CdRecordSpan *const pt_SPAN,
RtfTrackingInfo *const pt_context) {
DWORD ul_begin, ul_end;
STATUS us_err;
if (!( pt_SPAN && pt_SPAN->t_crsrBgin.puc_location &&
pt_SPAN->t_crsrBgin.us_recLength &&
pt_SPAN->t_crsrBgin.pt_item && pt_context))
return !eus_SUCCESS;
//PGP development shortcuts: no offsets, only actuality involved
_ASSERTE( !(pt_SPAN->us_offstBgin || pt_SPAN->us_offstEnd));
ul_begin = ul_GetAbsoluteOffset( pt_SPAN->t_crsrBgin.puc_location,
pt_SPAN->t_crsrBgin.pt_item,
pt_context->pt_Actuality);
ul_end = pt_SPAN->t_crsrEnd.pt_item ? ul_GetAbsoluteOffset(
pt_SPAN->t_crsrEnd.puc_location,
pt_SPAN->t_crsrEnd.pt_item,
pt_context->pt_Actuality) :
eul_ERR_FAILURE;
_ASSERTE( ul_begin != eul_ERR_FAILURE);
if (us_err = us_VirtualizeThruActualLocation(
pt_SPAN->t_crsrBgin.puc_location,
pt_context, NULL))
return us_err;
pt_context->ul_ActualFrontier = ul_end != eul_ERR_FAILURE ? ul_end :
mul_FRONTIER_NO_MORE;
return eus_SUCCESS;
} //eus_RemoveRtSpan(
/** eus_ReplaceRtfWithStandardText( ***
Purpose is to adjust the passed-in rich-text context so that the current
actual rich-text items will be replaced with the virtual rich-text items
to be written by this fuction using the text content passed in.
--- parameters & return ----
PC: pointer to the null-terminated text content to be streamed into the
virtual rich-text items to be created by this function
f_TRANSLATE_LINEFEEDS: flag specifying whether CRLFs should be translated to
rich-text linefeeds when copying content (TRUE) or not (FALSE)
pt_context: Input & Output. Pointer to environment information about the
rich-text field being operated on. Its virtuality information will be
updated by this function.
RETURN: eus_SUCCESS if no error occured; the Notes API error code otherwise
--- revision history -------
9/12/99 PR
+ fixed bug that manifested itself when multiple CDTEXTs had to be written
+ fixed bug that manifested itself when PGP ASCII Armor exceeds 64K in length
+ added documentation
12/16/98 PR: created */
STATUS eus_ReplaceRtfWithStandardText( const char PC[],
const BOOL f_TRANSLATE_LINEFEEDS,
RtfTrackingInfo *const pt_context) {
ItemInfo * pt_item = pt_context->pt_Actuality;
DWORD ul = 0;
if (!( PC && pt_context && pt_item))
return !eus_SUCCESS;
//set the actual frontier to the end of actuality
do
ul += pt_item->ul_length + pt_item->ul_length % 2;
while (pt_item = pt_item->pt_next);
pt_context->ul_ActualFrontier = ul;
//if any virtuality obtains, clear any items beyond a first item and
// reset the length of the first item to the beginning of the item
if (pt_item = pt_context->pt_Virtuality) {
if (pt_item->pt_next) {
ClearItemList( &pt_item->pt_next);
pt_context->pt_endVirtual = pt_item;
}
pt_item->ul_length = sizeof( WORD);
} //if (pt_item = pt_context->pt_Virtuality)
return us_AppendTextToVirtuality( PC, NULL, f_TRANSLATE_LINEFEEDS, NULL,
NULL, NULL, pt_context, NULL);
} //eus_ReplaceRtfWithStandardText(
/** ul_getNearLinebreakOffset( ***
Purpose is to return the offset to the first character following the nearest,
best linebreak candidate in an ASCII text run, accounting if necessary for
translation of CRLFs to rich-text linefeed characters. If CRLF translation is
specified, the nearest CRLF will be sought as the linebreak point. If a CRLF
is not found or if CRLF translation is not specified, the nearest word break
will be sought as the linebreak point. If all else fails, a linebreak point
corresponding to the specified limit point will be returned.
--- parameters & return ----
PC: pointer to the null-terminated ASCII text run to be considered
ul_LIMIT: the maximum length at which a linebreak point may be returned
f_TRANSLATE_LINEFEEDS: flag specifying whether CRLFs should be translated to
rich-text linefeeds when copying content (TRUE) or not (FALSE)
RETURN: The offset to the first character following the nearest, best
linebreak candidate. If the linebreak is at a CRLF, the offset will be to
the beginning of the CRLF.
--- revision history -------
9/12/99 PR: created */
static unsigned long ul_getNearLinebreakOffset(
const char *const PC,
unsigned long ul_LIMIT,
const BOOL f_TRANSLATE_LINEFEEDS) {
const char * pc, * pc_limit = NULL;
DWORD ul;
_ASSERTE( PC && ul_LIMIT);
//if we're translating linefeeds, the nearest linebreak is the nearest
// linefeed, presuming one is available
if (f_TRANSLATE_LINEFEEDS) {
//determine the pointer where the ultimate limit occurs in the
// untranslated text
TranslateCrlfText( PC, ul_LIMIT, &ul, NULL, &pc_limit);
//Step back until a CRLF is encountered. If one is encountered,
// determine and return the offset in terms of the *translated*
// text. The "1" represents the length of a rich-text linefeed.
pc = pc_limit;
do
if (memcmp( pc, epc_CRLF, ei_LEN_CRLF) == ei_SAME)
return ul - (pc_limit - pc - ei_LEN_CRLF + 1);
while (--pc > PC);
} //if (f_TRANSLATE_LINEFEEDS)
//the nearest linebreak is at the beginning of the nearest word,
// presuming one is available
if (!pc_limit) {
_ASSERTE( ul_LIMIT <= strlen( PC));
pc_limit = PC + (ul = ul_LIMIT);
}
pc = pc_limit;
while (--pc > PC)
if (*pc == ec_SPACE)
return ul - (pc_limit - pc + 1);
//since there isn't a good linebreak, we'll just say the break is right
// at the limit, probably intra-word
return ul;
} //ul_getNearLinebreakOffset(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -