如何在Lotus Notes中将文本附加到邮件正文(C API)

时间:2015-06-01 12:32:00

标签: lotus-notes lotus-domino

我一直试图将一些文本附加到Lotus Notes客户端的外发邮件中。为此,我已在EM_REG_BEFORE事件中注册了EM_MAILSENDNOTE。在这个事件中,我将一些富文本附加到邮件正文。 但该文本仅出现在已发送的文件夹邮件中,而不出现在接收端。我错过了什么? 以下代码来自this文档。

void appendRichTextToBody(NOTEHANDLE note_handle, const char *szString1) {
    #define PARA_STYLE_ID 1
    char     itemname[] = "Body";
    WORD wBuffLen; /* required buffer length */
    BYTE *rt_field; /* allocated rich-text field */
    BYTE *buff_ptr; /* position in allocated memory */
    CDPABDEFINITION pabdef; /* rich-text paragraph style */
    CDPARAGRAPH para; /* rich-text paragraph header */
    CDPABREFERENCE ref; /* rich-text style reference */
    CDTEXT cdtext; /* rich-text text header */
    WORD wString1Len = strlen( szString1 ); /* Length of actual string */
    WORD wString1BufLen = wString1Len + (wString1Len%2);

    FONTIDFIELDS *pFontID; /* font definitions in text header */
    DWORD rt_size; /* size of rich-text field */
    STATUS error = NOERROR; /* return code from API calls */

    wBuffLen = ODSLength( _CDPABDEFINITION ) +
        ODSLength( _CDPARAGRAPH ) + ODSLength( _CDPABREFERENCE) +
        ODSLength(_CDTEXT) + wString1BufLen;

    rt_field = (BYTE *) malloc ( wBuffLen );
    if( rt_field == (BYTE *)NULL ) {
            return;
    }
    //* Keep a pointer to our current position in the buffer. */
    buff_ptr = rt_field;
    /* Initialize a CDPABDEFINITION structure.We use all defaults, except for centered
    justification.*/
    memset(&pabdef, 0, sizeof(CDPABDEFINITION));
    pabdef.Header.Signature = SIG_CD_PABDEFINITION;
    pabdef.Header.Length = ODSLength( _CDPABDEFINITION );
    pabdef.PABID = PARA_STYLE_ID;
    pabdef.JustifyMode = JUSTIFY_CENTER;
    pabdef.LineSpacing = DEFAULT_LINE_SPACING;

    pabdef.ParagraphSpacingBefore = DEFAULT_ABOVE_PAR_SPACING;
    pabdef.ParagraphSpacingAfter = DEFAULT_BELOW_PAR_SPACING;
    pabdef.LeftMargin = DEFAULT_LEFT_MARGIN;
    pabdef.RightMargin = DEFAULT_RIGHT_MARGIN;
    pabdef.FirstLineLeftMargin = DEFAULT_FIRST_LEFT_MARGIN;
    pabdef.Tabs = DEFAULT_TABS;
    pabdef.Tab[0] = DEFAULT_TAB_INTERVAL;
    pabdef.Flags = 0;
    pabdef.TabTypes = TAB_DEFAULT;
    pabdef.Flags2 = 0;
    /* Call ODSWriteMemory to convert the CDPABDEFINITION structure to
    Domino and Notes canonical format and write the converted structure into
    the buffer at location buff_ptr. This advances buff_ptr to the
    next byte in the buffer after the canonical format strucure.
    */
    ODSWriteMemory( &buff_ptr, _CDPABDEFINITION, &pabdef, 1 );
    /* Put a paragraph header in the field. */
    para.Header.Signature = SIG_CD_PARAGRAPH;
    para.Header.Length = (BYTE) ODSLength( _CDPARAGRAPH );

    ODSWriteMemory( &buff_ptr, _CDPARAGRAPH, &para, 1 );
    /* Add the CDTEXT record to the field. A CDTEXT record consists
    of a CDTEXT structure followed by a run of text. Initialize the
    CDTEXT structure by filling in the signature and the length.
    The CDTEXT structure also contains the font information that
    controls how Domino and Notes displays this first run of text.
        */
    cdtext.Header.Signature = SIG_CD_TEXT;
    cdtext.Header.Length = ODSLength( _CDTEXT ) + wString1Len ;
    pFontID = (FONTIDFIELDS *) &(cdtext.FontID);
    pFontID->Face = FONT_FACE_SWISS;
    pFontID->Attrib = ISBOLD;
    pFontID->Color = NOTES_COLOR_BLUE;
    pFontID->PointSize = 24;
    ODSWriteMemory( &buff_ptr, _CDTEXT, &cdtext, 1 );
    /* Write the actual characters of this first text run to the buffer.
    Since the run of text may contian embedded null characters, use
    memcpy, not strcpy. No need to terminate the run of text with a
    null because the Header.Length member of the CDTEXT structure
    specifies the length explicitly. Only copy the null if the
    number of characters is odd.
    */
    memcpy( (char *)buff_ptr, szString1, wString1BufLen );
    /* Advance the pointer to the next even-byte boundary */
    buff_ptr += wString1BufLen;
    rt_size = (DWORD)(buff_ptr - rt_field);
    if (error = NSFItemAppend( note_handle, 0, itemname, (WORD) strlen(itemname), TYPE_COMPOSITE, rt_field, rt_size ) ){
            Log("%s: NSFItemAppend failed\n", __FUNCTION__);
            return;
    }
    free( rt_field );
}

EDIT1:

注册事件处理程序的代码:

error = EMRegister(EM_MAILSENDNOTE, EM_REG_BEFORE,(EMHANDLER)MailSendNoteHandler, gRecursionID, &hMailSendNote);
error = EMRegister(EM_NSFNOTEUPDATEMAILBOX, EM_REG_BEFORE,(EMHANDLER)UpdateMailboxHandler, gRecursionID, &hNSFUpdateMailbox);

事件处理函数:

STATUS MailSendNoteHandler(EMRECORD FAR * pExRecord) {
    VARARG_PTR ap = pExRecord->Ap;
    DHANDLE hNote = VARARG_GET (ap, DHANDLE);
    appendRichTextToBody(hNote, " Test Rich Text EM_MAILSENDNOTE BEFORE ");
    return (EM_ERR_CONTINUE);
}

STATUS UpdateMailboxHandler(EMRECORD FAR * pExRecord) {
    VARARG_PTR ap = pExRecord->Ap;
    DHANDLE hNote = VARARG_GET (ap, DHANDLE);
    appendRichTextToBody(hNote, " Test Rich Text EM_NSFNOTEUPDATEMAILBOX BEFORE ");
    return (EM_ERR_CONTINUE);
}

我在收件方看不到任何附加文字。 但是“已发送”文件夹中的邮件都有附加文本。

1 个答案:

答案 0 :(得分:0)

我认为这是客户端EM。我熟悉的大多数邮件处理代码都是通过在服务器上的mail.box文件中挂起EM_NSFNOTEUPDATE而在服务器端运行的。但是,那里的诀窍是你必须阻止路由器在完成处理之前发送消息,所以你要做的第一件事就是将消息的状态改为“保持”,这样路由器就不会甚至尝试邮寄它。然后你可以做它的工作,最后发布它。 (通常在服务器端,这涉及发信号通知单独的服务器任务来完成工作,因为您不希望在工作完成时保持主服务器线程不从NSFNoteUpdate返回。)

即使使用EM_BEFORE处理,您也可能需要在客户端执行类似操作才能完成此操作。您至少可以为EM_NSFNOTEUPDATE添加EM_BEFORE和EM_AFTER事件处理程序,以监视mail.box文件,以确定在EM_MAILSENDNOTE事件触发之前或之后是否触发了这些事件。