在32位WIN7 VS2012环境下测试通过,在64位WIN7 VS2013环境下GlobalLock和GlobalSize函数返回NULL,具体参见注释
// 读取给定文件名的Doc文档中的数据
BOOL CWordOperator::ReadInDataFromDoc(CString strFileName)
{
// 读取Config文件,获得需要读取的单元格坐标
LoadConfig();
// COM相关变量
COleVariant vTrue((short)TRUE);
COleVariant vFalse((short)FALSE);
COleVariant vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
// Word相关变量
CApplication wordApp; // 在对象继承结构中是最顶层的对象,可以通过它的方法访问别的工作类型的对象(本例主要是word)
CDocuments docs; // 代表所有打开的文档对象
CDocument0 doc; // 单一文件
CSelection selection; // 选择区域
CRange rangeWord; // 文档区域
CTables0 tables; // 所有表格
CTable0 table; // 单一表格
CCell cell; // 单元格
CnlineShapes shapes; // 图片集合
CnlineShape shape; // 图片
// 启动Word程序
if (!wordApp.CreateDispatch(_T("word.application"))) // 启动Word
{
AfxMessageBox(_T("无法启动Word"));
return FALSE;
}
// 设置Word不可见
wordApp.put_Visible(FALSE);
// 打开指定Doc
docs = wordApp.get_Documents();
doc = docs.Open(COleVariant(strFileName), vFalse, vTrue, vFalse, vOpt, vOpt,
vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt);
if (!doc) // 打开失败
{
AfxMessageBox(_T("无法打开文件"));
return FALSE;
}
// 获得选择焦点
selection = wordApp.get_Selection();
// 获得表格
tables = doc.get_Tables();
table = tables.Item(1); // 索引从1开始
// 根据XML中定义的节点中的行列进行读取
// for each (DocCellData data in m_lstDocDatas)
for (std::list<DocCellData>::iterator it = m_lstDocDatas.begin();
it != m_lstDocDatas.end(); it++)
{
DocCellData& data = *it;
// 根据节点中设定的行列获得单元格
cell = table.Cell(data.nRowIndex, data.nColIndex);
if (!cell) // 错误提示
{
CString strErr;
strErr.Format(_T("%s指定的%d行%d列的单元格不存在"), data.strXMLName,
&data.nRowIndex, &data.nColIndex);
AfxMessageBox(strErr);
break;
}
// 取得单元格内容
rangeWord = cell.get_Range();
// 判断类型
switch (data.type)
{
case TextType: // 文本类型
data.strValue = rangeWord.get_Text();
// OpenClipboard(NULL);
// // 清除剪切板内容
// EmptyClipboard();
// // 不关闭则复制操作不起作用,无法复制到剪切板里
// CloseClipboard();
// rangeWord.Copy();
// OpenClipboard(NULL);
// if (true)
// {
// HGLOBAL hClipBoard = ::GetClipboardData(CF_TEXT);
// void* pMem = ::GlobalLock(hClipBoard);
// n = GlobalSize(hClipBoard);
// CString str((char*)pMem);
// }
break;
case PicType: // 图片类型
// 取得所有图片集合
shapes = rangeWord.get_InlineShapes();
if (shapes.get_Count()) // 存在图片
{
// 利用剪切板获得图片
// 取得第一张图
shape = shapes.Item(1);
shape.Select();
// 复制到剪切板
selection = wordApp.get_Selection();
// 打开剪切板(占用状态,此时进行复制粘贴等操作将无效果)
::OpenClipboard(NULL);
// 清除剪切板内容
::EmptyClipboard();
// 不关闭则复制操作不起作用,无法复制到剪切板里
::CloseClipboard();
selection.CopyAsPicture();
// 32位WIN7下VS2012可以运行
// 打开剪切板,并且剪切板里存在图片
// if (::IsClipboardFormatAvailable(CF_DIB) &&
// ::OpenClipboard(NULL))
// {
// // 取得剪切板中的图片数据
// HGLOBAL hClipBoard = ::GetClipboardData(CF_DIB);
// // 锁定内存位置吗,以防系统将内存页移位
// LPVOID pMem = ::GlobalLock(hClipBoard);
//
// // 如果存在图片,则进行复制
// if (pMem)
// {
// // 取得位图大小
// data.nPicSize = ::GlobalSize(hClipBoard);
// // 复制到结构中
// data.pBmp = new BYTE[data.nPicSize];
// memcpy(data.pBmp, pMem, data.nPicSize);
// // 解锁内存
// ::GlobalUnlock(hClipBoard);
// }
// else
// {
// data.nPicSize = 0;
// }
// //关闭剪贴板,释放剪贴板资源的占用权
// ::CloseClipboard();
// }
// 64位WIN7下VS2013可以运行
if (::IsClipboardFormatAvailable(CF_ENHMETAFILE) &&
::OpenClipboard(NULL))
{
// 首先生成EMF图片文件并存储
CString strTempBmp(GetAppPath());
strTempBmp += EMFFILENAME; // 指定存储路径
HANDLE hClipBoard = ::GetClipboardData(CF_ENHMETAFILE); // 从剪切板读取EMF格式内容(其它格式读不出来)
HENHMETAFILE hTempBmp =
::CopyEnhMetaFile((HENHMETAFILE)hClipBoard, strTempBmp); // 存成文件
// 关闭剪切板,释放剪贴板资源的占用权
::CloseClipboard();
if (hTempBmp) // 图片存在
{
// 释放内存
DeleteEnhMetaFile(hTempBmp);
// 读入内存
CFile emfFile(strTempBmp, CFile::modeRead); // 取得emf文件
data.nPicSize = emfFile.GetLength(); // 取得文件大小(再加一)
data.pBmp = new BYTE[data.nPicSize + 1]; // 分配内存
emfFile.Read(data.pBmp, data.nPicSize); // 读入
data.pBmp[data.nPicSize] = 0; // 将最后一位置为结束位
emfFile.Close(); // 关闭emf文件
emfFile.Remove(strTempBmp); // 删除emf文件
// 打开剪切板(占用状态,此时进行复制粘贴等操作将无效果)
::OpenClipboard(NULL);
// 清除剪切板内容
::EmptyClipboard();
// 不关闭则复制操作不起作用,无法复制到剪切板里
::CloseClipboard();
}
}
}
break;
default:
break;
}
}
// 关闭文档
doc.Close(vFalse, vOpt, vOpt);
// 退出Word
wordApp.Quit(vFalse, vOpt, vOpt);
return TRUE;
}
// 根据数据生成Doc文档
BOOL CWordOperator::WriteOutDocByData(CString strFileName)
{
// COM相关变量
COleVariant vTrue((short)TRUE);
COleVariant vFalse((short)FALSE);
COleVariant vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
// Word相关变量
CApplication wordApp; // 在对象继承结构中是最顶层的对象,可以通过它的方法访问别的工作类型的对象(本例主要是word)
CDocuments docs; // 代表所有打开的文档对象
CDocument0 doc; // 单一文件
CSelection selection; // 选择区域
CRange rangeWord; // 文档区域
CTables0 tables; // 所有表格
CTable0 table; // 单一表格
CCell cell; // 单元格
CnlineShapes shapes; // 图片集合
CnlineShape shape; // 图片
// 启动Word程序
if (!wordApp.CreateDispatch(_T("word.application"))) // 启动Word
{
AfxMessageBox(_T("无法启动Word"));
return FALSE;
}
// 设置Word不可见
wordApp.put_Visible(TRUE);
// 打开指定Doc
docs = wordApp.get_Documents();
CComVariant Template("");
CComVariant NewTemplate(false), DocumentType(0), Visible;
docs.Add(&Template, &NewTemplate, &DocumentType, &Visible);
doc = docs.Item(&CComVariant(1));
if (!doc) // 打开失败
{
AfxMessageBox(_T("无法创建文件"));
return FALSE;
}
// 获得选择焦点
selection = wordApp.get_Selection();
rangeWord = selection.get_Range();
// 获得表格
tables = doc.get_Tables();
tables.Add(rangeWord, 10, 10, vOpt, vOpt);
table = tables.Item(1); // 索引从1开始
// 根据节点中设定的行列获得单元格
cell = table.Cell(1, 1);
// 根据XML中定义的节点中的行列进行读取
for each (DocCellData data in m_lstDocDatas)
{
// 取得单元格内容
rangeWord = cell.get_Range();
cell.Select();
// 判断类型
switch (data.type)
{
case TextType: // 文本类型
rangeWord.put_Text(data.strValue);
break;
case PicType: // 图片类型
// 64位WIN7下VS2013调试通过
if (TRUE) // 跳过switch的语法检查
{
// 先存成文件
CString strTempBmpFileName(GetAppPath());
strTempBmpFileName += EMFFILENAME; // 生成路径
// 创建emf文件
CFile emfFile(strTempBmpFileName,
CFile::modeCreate | CFile::modeReadWrite);
emfFile.Write(data.pBmp, data.nPicSize); // 写入位图
emfFile.Close(); // 关闭文件
// 将图片插入到文档
rangeWord.Select();
shapes = selection.get_InlineShapes(); // 得到图片集合
// 插入emf图片
shapes.AddPicture(strTempBmpFileName, vFalse, vTrue,
&_variant_t(rangeWord));
// 删除emf文件
emfFile.Remove(strTempBmpFileName);
}
// 32位WIN7下VS2012调试通过
// // 打开剪切板(占用状态,此时进行复制粘贴等操作将无效果)
// ::OpenClipboard(NULL);
// // 清除剪切板内容
// ::EmptyClipboard();
// // 不关闭则复制操作不起作用,无法复制到剪切板里
// ::CloseClipboard();
//
// if (::OpenClipboard(NULL))
// {
// // 申请全局内存来存放BMP,以便交给剪切板
// HGLOBAL hClipBoard = ::GlobalAlloc(GMEM_MOVEABLE, data.nPicSize);
// // 锁定内存地址
// LPVOID pMem = ::GlobalLock(hClipBoard);
// // 复制位图
// memcpy(pMem, data.pBmp, data.nPicSize);
// // 解锁内存
// ::GlobalUnlock(hClipBoard);
// // 将位图设置到剪切板中
// ::SetClipboardData(CF_DIB, hClipBoard);
// // 关闭剪切板
// ::CloseClipboard();
// rangeWord.Paste();
// rangeWord.Paste();
// }
// //关闭剪贴板,释放剪贴板资源的占用权
// ::CloseClipboard();
break;
default:
break;
}
cell = cell.get_Next();
}
// 保存文档
doc.Save();
// 关闭文档
doc.Close(vTrue, vOpt, vOpt);
// 退出Word
wordApp.Quit(vTrue, vOpt, vOpt);
return TRUE;
}