VC 操作word部分代码(利用剪切板取得Word中的图片,ClipBoard, Addpicture)

来源:互联网 发布:数据库设计方法有哪些 编辑:程序博客网 时间:2024/06/07 03:27

在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;}
0 0
原创粉丝点击