Lotus Domino/Notes 廣泛用於辦公自動化,但打印功能極弱:文檔只能按給定表單版式打印。實際中(如政府公文),同一內容需上行/下行不同版式。修改表單受限於隱藏設計,最終用戶技術有限無法操作。
表單 Note 必含三域:$TITLE、$INFO、$BODY;輔助域:$FIELDS、placeholder 域。
TYPE_TEXT,存表單名稱(客戶端「創建」菜單顯示的名稱)。ITEM_NAME_TEMPLATE_NAME 代表此域,建議用常量保兼容性。TYPE_COMPOSITE,存 CDDOCUMENT 結構體,定義通過此表單創建文檔的屬性。ITEM_NAME_DOCUMENT。結構體定義詳見 Lotus C API 參考。TYPE_COMPOSITE,常量 ITEM_NAME_TEMPLATE。CD* 結構體組成(CDTEXT、CDFIELD、CDPABDEFINITION 等)。TYPE_TEXT_LIST,列出生成文檔包含的所有域名。純打印表單可無此域。TYPE_INVALID_OR_UNKNOWN,標志 ITEM_PLACEHOLDER,域名同 $BODY 定義,值為 NULL。整體結構示例:
CDPABDEFINITION
CDPABDEFINITION
...
CDPARAGRAPH
CDPABREFERENCE
CDTEXT
text
...
CDPARAGRAPH
CDPABREFERENCE
CDBEGINRECORD
CDFIELD
CDBEGINRECORD
...
CDPABDEFINITION 定義段落屬性:對齊、頁邊距、段間距、行間距等。PABID 序號唯一即可,位置靈活。
CDPARAGRAPH:段落開始(類似換行)。CDPABREFERENCE:引用段落定義(PABID)。CDTEXT:文本頭部,含長度、字體、顏色。text:實際文本內容。CDPARAGRAPH + CDPABREFERENCE 開始。CDBEGINRECORD/CDENDRECORD 包裹前後。CDBEGINRECORD 前,作文本處理。CDEXT2FIELD 提供附加格式。CDFIELD 後,順序與長度值在結構體中一致。除域名外可省略。$TITLE)用 NSFItemSetText 創建。$INFO、$BODY):
OSMemAlloc)。ODSWriteMemory 以 Domino 規範寫入,公式經 NSFFormulaCompile 編譯後寫入。NSFItemAppend 創建域。
// 定義域屬性
char TextFieldName[] = "TextField";
char TextDescription[] = "This is a Simple Text Field";
char TextDefValFormula[] = "\"Default\"";
char far *pBufferStart, far *pBuffer;
HANDLE hMem;
CDPABREFERENCE CDPabRef;
CDPARAGRAPH CDPara;
CDBEGINRECORD CDBegin;
CDENDRECORD CDEnd;
CDEXT2FIELD CDExt2Field;
CDFIELD CDField;
FONTIDFIELDS *pFontFields;
// 申請並鎖定內存
OSMemAlloc(0, wCDBufferLength, &hMem);
pBufferStart = (char far *)OSLockObject(hMem);
memset(pBufferStart, 0, (size_t)wCDBufferLength);
pBuffer = pBufferStart;
// 填寫 PARAGRAPH
CDPara.Header.Length = (BYTE)ODSLength(_CDPARAGRAPH);
CDPara.Header.Signature = (BYTE)SIG_CD_PARAGRAPH;
ODSWriteMemory((void far * far *)&pBuffer, _CDPARAGRAPH, &CDPara, 1);
// 填寫 PABREFERENCE
CDPabRef.Header.Signature = (BYTE)SIG_CD_PABREFERENCE;
CDPabRef.Header.Length = (BYTE)ODSLength(_CDPABREFERENCE);
CDPabRef.PABID = wPabDefNumber; // 引用的段定義序號
ODSWriteMemory((void far * far *)&pBuffer, _CDPABREFERENCE, &CDPabRef, 1);
// 填寫 CDBEGINRECORD
CDBegin.Header.Length = (BYTE)ODSLength(_CDBEGINRECORD);
CDBegin.Header.Signature = SIG_CD_BEGIN;
CDBegin.Version = 0;
CDBegin.Signature = SIG_CD_FIELD;
ODSWriteMemory((void far * far *)&pBuffer, _CDBEGINRECORD, (void far *)&CDBegin, 1);
// 填寫 CDEXT2FIELD
memset(&CDExt2Field, 0, sizeof(CDEXT2FIELD));
CDExt2Field.Header.Length = (WORD)ODSLength(_CDEXT2FIELD);
CDExt2Field.Header.Signature = SIG_CD_EXT2_FIELD;
ODSWriteMemory((void far * far *)&pBuffer, _CDEXT2FIELD, (void far *)&CDExt2Field, 1);
// 填寫 CDFIELD 核心部分
CDField.Header.Signature = SIG_CD_FIELD;
CDField.Flags = FEDITABLE;
CDField.DataType = TYPE_TEXT;
CDField.ListDelim = LDDELIM_SEMICOLON;
// 數值/時間格式參數清零 ...
// 設置 FontID
pFontFields = (FONTIDFIELDS *)&CDField.FontID;
pFontFields->Face = FONT_FACE_ROMAN;
pFontFields->Attrib = 0;
pFontFields->Color = NOTES_COLOR_BLACK;
pFontFields->PointSize = 14;
// 編譯默認值公式
NSFFormulaCompile(NULL, 0, TextDefValFormula, (WORD)strlen(TextDefValFormula),
&hTextDefValFormula, &wTextDefValFormulaLen, &wdc, &wdc, &wdc, &wdc, &wdc);
// 填寫 CDFIELD 剩餘長度字段
CDField.DVLength = wTextDefValFormulaLen;
CDField.ITLength = 0; CDField.TabOrder = 0; CDField.IVLength = 0;
CDField.NameLength = strlen(TextFieldName);
CDField.DescLength = strlen(TextDescription);
CDField.TextValueLength = 0;
CDField.Header.Length = ODSLength(_CDFIELD) + CDField.DVLength + CDField.ITLength
+ CDField.IVLength + CDField.NameLength + CDField.DescLength + CDField.TextValueLength;
if (CDField.Header.Length % 2) CDField.Header.Length++; // 確保偶數長度
ODSWriteMemory((void far * far *)&pBuffer, _CDFIELD, (void far *)&CDField, 1);
// 寫入公式內容
pTextDefValFormula = OSLock(char, hTextDefValFormula);
memcpy(pBuffer, pTextDefValFormula, wTextDefValFormulaLen);
pBuffer += CDField.DVLength;
OSUnlockObject(hTextDefValFormula); OSMemFree(hTextDefValFormula);
// 寫入域名與描述
memcpy(pBuffer, TextFieldName, CDField.NameLength); pBuffer += CDField.NameLength;
memcpy(pBuffer, TextDescription, CDField.DescLength); pBuffer += CDField.DescLength;
// 確保整體偶數長度
if ((pBuffer - pBufferStart) % 2) pBuffer++;
// 填寫 CDENDRECORD
CDEnd.Header.Length = (BYTE)ODSLength(_CDENDRECORD);
CDEnd.Header.Signature = SIG_CD_END;
CDEnd.Version = 0; CDEnd.Signature = SIG_CD_FIELD;
ODSWriteMemory((void far * far *)&pBuffer, _CDENDRECORD, (void far *)&CDEnd, 1);
OSMemAlloc/Lock/Unlock/Free 管理遠指針內存。ODSWriteMemory 以 Domino 標準格式寫入(字節序、對齊)。NSFFormulaCompile 編譯為字節碼再寫入。掌握此技術,可實現 Notes 文檔的任意版式動態生成與打印,極大增強應用靈活性。