COM将PPT转换为BMP但获得不可读的图像

时间:2014-12-20 04:47:26

标签: com powerpoint bmp

我需要在我的应用程序中将ppt文件转换为BMP图像,但是使用CopyEnhMetaFile()到我的ppt对象会给我一些Windows应用程序无法读取的图像。我必须指出windows paint utility( Windows 7)可以很好地查看文件。另外,在我的测试win xp虚拟机上,我注意到Windows Photo Viewer可以打开那些BMP。

我使用的代码如下所示:

void PowerPointToPic(CString szDocName, CString szOutDir)
{

    CPPTApplication m_powerpointApp;
    CPPTPresentations m_powerpointPres;
    CPPTPresentation m_powerpointPre;
    CPPTSlide         slide;
    CPPTSlides       slides;
    m_powerpointPres.ReleaseDispatch();
    m_powerpointPre.ReleaseDispatch();


    try{
        CoInitialize(NULL);
        if(!m_powerpointApp.CreateDispatch(_T("PowerPoint.Application"), NULL))
        { 
            AfxMessageBox(_T("-------------------")); 
            return; 
        } 
    }
    catch(...)
    {
        return;
    }

    m_powerpointApp.m_bAutoRelease=true;
    m_powerpointApp.put_Visible(long(1));
    m_powerpointApp.put_WindowState(long(2));
    m_powerpointPres.AttachDispatch(m_powerpointApp.get_Presentations());
    m_powerpointPres.Open(szDocName,TRUE, 1, 1);
    m_powerpointPre.AttachDispatch(m_powerpointApp.get_ActivePresentation(),TRUE);

    slides = m_powerpointPre.get_Slides();
    int pageCount = slides.get_Count();
    for( int i = 1; i <= pageCount; i++ )
    {
        slide  = slides.Range(COleVariant((long)i));
        slide.Copy();
        if (::OpenClipboard(NULL)) 
        {
            //BOOL   ba=::IsClipboardFormatAvailable(CF_ENHMETAFILE); //
            BOOL   ba=::IsClipboardFormatAvailable(CF_LOCALE);

            HENHMETAFILE hEnhMetaFile = NULL;
            //CF_LOCALE
            //hEnhMetaFile = (HENHMETAFILE)GetClipboardData(CF_ENHMETAFILE); 
            hEnhMetaFile = (HENHMETAFILE)GetClipboardData(CF_LOCALE);
            if (hEnhMetaFile == NULL)
            {
                int err = GetLastError();
                m_powerpointApp.Quit();
                EmptyClipboard();
                CloseClipboard();
                return;
            }           

            CString temp;
            temp.Format(_T("%s-ppt-%d.bmp"), szOutDir, i);
        //HERE IS WHERE I SAVE MY METAFILE AS A BMP

            HENHMETAFILE   hMetaFile= CopyEnhMetaFile(hEnhMetaFile, temp);
            if (hMetaFile == NULL)
            {
                int err = GetLastError();
                m_powerpointApp.Quit();
                EmptyClipboard();
                CloseClipboard();
            }

            DeleteEnhMetaFile(hMetaFile); 
            EmptyClipboard();
            CloseClipboard(); 
        }

    }




    m_powerpointPre.Close();
    m_powerpointApp.Quit(); 
    m_powerpointPre.ReleaseDispatch();
    m_powerpointPres.ReleaseDispatch();
    slides.ReleaseDispatch();
    slide.ReleaseDispatch();
    m_powerpointApp.ReleaseDispatch();

    CoUninitialize();

}

我很感激任何指针。

感谢您的时间。

编辑:幻灯片对象上的导出方法可以按照我的意愿保存.bmp图像,但不能在word和excel上做同样的事情,因为我无法弄清楚如何保存范围。这就是我试过了。

void WordToPic(CString szDocName, CString szOutDir,QString outDir)
{
    _ApplicationWord WordApp; 
    Documents docs;   
    _Document   doc; 
    Selection   m_sel;
    Range rg;

    docs.ReleaseDispatch();
    m_sel.ReleaseDispatch();
    WordApp.m_bAutoRelease = true;
    try{
        if(CoInitialize(NULL) != 0)
            ;
        if(!WordApp.CreateDispatch(_T("Word.Application"),NULL))// 
        {   
            AfxMessageBox(_T("-----------------"));
            return ;   
        }
    }
    catch (...)
    {       
        return;
    }

    COleVariant  varfilepath((LPCTSTR)szDocName);
    COleVariant  varstrnull(_T(""));
    COleVariant  covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
    COleVariant  vartrue((short)TRUE);
    COleVariant  varfalse((short)FALSE);

    docs.AttachDispatch(WordApp.GetDocuments());

    try{
        docs.Open(varfilepath,varfalse,vartrue,varfalse,   
            covOptional,covOptional,varfalse,covOptional,   
            covOptional,COleVariant(long(1)),covOptional,vartrue,covOptional,covOptional,covOptional,covOptional);
    }
    catch (...)
    {       
        Sleep(600);
        WordApp.Quit(covOptional,covOptional,covOptional);
        return;
    }

    doc.AttachDispatch(WordApp.GetActiveDocument());
    m_sel.AttachDispatch(WordApp.GetSelection());//
    m_sel.WholeStory();
    try {
        rg.AttachDispatch(doc.Range(COleVariant(long(0)),COleVariant(m_sel.GetEnd())));
    }
    catch (...)
    {
        Sleep(600);
        WordApp.Quit(covOptional,covOptional,covOptional);
        return;
    }   
    long endDoc = rg.GetEnd(); 
    long start = 0;
    long end = 0; 

    m_sel.SetRange(endDoc,endDoc); 
    long countPage = ((LPVARIANT)COleVariant(m_sel.GetInformation(1) ) ) ->lVal;
    m_sel.SetRange(start,end); 

    int nCount = countPage;   
    CString picPath;
    int curNum=0;

    for (int num = 1; num<nCount+1; num++)//
    {
        curNum = num;
        if (num >1 )
        {           
            rg = m_sel.GoToNext( 1 );
            start = rg.GetStart();
        }
        if( num != countPage ) 
        { 
            rg = m_sel.GoToNext( 1 ); 
            end = rg.GetStart() - 1; 
        } 
        else 
            end = endDoc;

        m_sel.SetRange( start, end ); 
        rg = m_sel.GetRange();
        try
        {
            rg.CopyAsPicture();
            //SHOULD SAVE AS IMAGE  HERE.

        }
        catch (...)
        {
            WordApp.Quit(covOptional,covOptional,covOptional);
            return;
        }       


    }
    WordApp.Quit(covOptional,covOptional,covOptional);
    docs.ReleaseDispatch(); 
    m_sel.ReleaseDispatch();
    doc.ReleaseDispatch();
    rg.ReleaseDispatch();   
    WordApp.ReleaseDispatch();
    CoUninitialize();
}

和excel:

void ExcelToPic(CString szExcelName, CString szOutDir)
{
    _ApplicationExcel app;
    Workbooks books;
    _Workbook book;
    Worksheets sheets;
    _Worksheet sheet;
    RangeExcel range;
    RangeExcel iCell;
    LPDISPATCH lpDisp;   
    COleVariant vResult;
    COleVariant
        covTrue((short)TRUE),
        covFalse((short)FALSE),
        covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);          

    //*****
    if (CoInitialize(NULL)!=0) ;

    if(!app.CreateDispatch(_T("Excel.Application")))
    {
        AfxMessageBox(_T("-------------"));
        return ;
    }

    //app.SetVisible(TRUE); 
    app.SetUserControl(TRUE);     

    books.AttachDispatch(app.GetWorkbooks());
    lpDisp = books.Open((LPCTSTR)szExcelName,     
        covOptional, covOptional, covOptional, covOptional, covOptional,
        covOptional, covOptional, covOptional, covOptional, covOptional,
        covOptional, covOptional );     


    book.AttachDispatch(lpDisp);        


    sheets.AttachDispatch(book.GetWorksheets());

    long countPage = sheets.GetCount();


    RangeExcel usedRange;

    for(int i = 1; i < countPage+1; i++)
    {
        COleVariant vOpt((long)i);
        sheet = sheets.GetItem(vOpt);
        sheet.Activate();

        //*****

        usedRange.AttachDispatch(sheet.GetUsedRange());

        usedRange.Select();

        usedRange.CopyPicture(1,1);

        //SAVE AS IMAGE.
    }

    app.Quit();
    app.ReleaseDispatch();
    books.ReleaseDispatch();
    book.ReleaseDispatch();
    sheets.ReleaseDispatch();
    sheet.ReleaseDispatch();
    range.ReleaseDispatch();
    usedRange.ReleaseDispatch(); 

    CoUninitialize();
}

1 个答案:

答案 0 :(得分:1)

如果您可以处理磁盘上的图像,PowerPoint .Slide对象有一个.Export方法,它接受文件名,导出过滤器(在本例中为“BMP”),宽度,高度作为参数(宽度/高度以像素为单位)

我在VB / VBA工作,可能会误解你在这里做了什么,但看起来你正在将一个EMF格式放在剪贴板上,然后用BMP扩展名保存它。

有点像在盐瓶上放一个标有“糖”的标签,不是吗? ; - )