按段落读取RTF富文本格式文件内容

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

最近写游戏公告服务器,需要按分段落读取RTF格式文本文件内容到内存中,然后下发客户端.

网络上没找到类似功能的代码,费了些功夫研究了一下,感觉在Windows下写些自由度较大的功能都像是在做hack.

// 创建一个临时RichEdit控件

HMODULE hInstRich = ::LoadLibrary("RICHED20.DLL");

ATLASSERT(hInstRich != NULL);

CRichEditCtrl ctrlRichEdit;

ctrlRichEdit.Create(NULL, NULL, NULL, WS_POPUP | ES_MULTILINE);

// 取得ITextDocument接口

IRichEditOle* pRichEditOle = ctrlRichEdit.GetOleInterface();

if(!pRichEditOle) return false;

ITextDocument* pRichDoc = NULL;

pRichEditOle->QueryInterface(__uuidof(ITextDocument), (LPVOID*)&pRichDoc);

SAFE_RELEASE(pRichEditOle);

if(!pRichDoc) return false;

// 打开RTF文件

CComVariant varFileName = szFileName;

HRESULT hr = pRichDoc->Open(&varFileName, tomReadOnly | tomRTF, 0);

if(FAILED(hr))

{

SAFE_RELEASE(pRichDoc);

return false;

}

// 读取RTF文件

CIntArray arrParas;

arrParas.push_back(0);

// 分析文章每个段的位置

int lineCount = ctrlRichEdit.GetLineCount();

for(int i = 0; i < lineCount; i++)

{

char szLineText[16] = { 0 };

int nLineBeginCharIndex = ctrlRichEdit.LineIndex(i);// 行首CharIndex

int nLineLength = ctrlRichEdit.LineLength(nLineBeginCharIndex);

if(nLineLength == 0) continue;

int nLineEndCharIndex = nLineBeginCharIndex + nLineLength;// 行末CharIndex

ctrlRichEdit.GetTextRange(nLineEndCharIndex, nLineEndCharIndex + 1, szLineText);

if(szLineText[0] == '\r')

{

arrParas.push_back(nLineEndCharIndex + 1);

}

}

// 读取每个段的内容到内存

FORMATETC fmtEtc = { RegisterClipboardFormat(CF_RTF), NULL, DVASPECT_CONTE NT, -1, TYMED_HGLOBAL };

for(uint32 i = 0; i < arrParas.size() - 1; i++)

{

ITextRange* pTextRange = NULL;

if(SUCCEEDED(pRichDoc->Range(arrParas[i], arrParas[i+1], &pTextRange)) && pText Range != NULL)

{

CComVariant varDataObject;

IDataObject* pDataObject = NULL;

varDataObject.vt = VT_UNKNOWN | VT_BYREF;

varDataObject.ppunkVal = (IUnknown**)&pDataObject;

hr = pTextRange->Copy(&varDataObject);

if(SUCCEEDED(hr) && pDataObject != NULL)

{

STGMEDIUM stgMedium = { TYMED_HGLOBAL, 0 };

hr = pDataObject->GetData(&fmtEtc, &stgMedium);

if(SUCCEEDED(hr) && stgMedium.hGlobal != NULL)

{

DWORD nLen = ::GlobalSize(stgMedium.hGlobal);

void* pData = (void*)::GlobalLock(stgMedium.hGlobal);

CMemChunkBase chunk(nLen);

chunk.WriteData(pData, nLen);

m_arrSysMsgs.push_back(chunk);

::GlobalUnlock(pData);

}

}

SAFE_RELEASE(pDataObject);

SAFE_RELEASE(pTextRange);

相关文档
最新文档