如何使用COM / ATL打开现有文件(无MFC)

时间:2008-10-02 13:21:58

标签: c++ excel com

我有一个链接到ATL的现有Windows C ++应用程序。我需要打开现有的Excel文件并访问一些属性。我需要做的一件事是确定用户当前是否正在查看Excel文件。

我们可以假设用户安装了Excel,但不确定是哪个版本。

要附加到现有Excel文件的C ++ / COM代码是什么?如何确定文件当前是否由Excel实例打开?假设我知道文件名。我用Google搜索了15分钟但没有找到如何在没有MFC的情况下做到这一点。

1 个答案:

答案 0 :(得分:3)

很好的挑战。因为挑战不能被拒绝,所以我坐在Visual Studio前面,这是一个可能的解决方案。

#include <windows.h>
#include <iostream>

using namespace std;

#import "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE11\\MSO.DLL" \
    rename("RGB", "MSORGB") \
    rename("DocumentProperties", "MSDocumentProperties")

using namespace Office;

#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB"

using namespace VBIDE;

#import "C:\\Program Files\\Microsoft Office\\OFFICE11\\EXCEL.EXE" \
    rename("DialogBox", "ExcelDialogBox" ) \
    rename("RGB", "ExcelRGB") \
    rename("CopyFile", "ExcelCopyFile") \
    rename("ReplaceText", "ExcelReplaceText")

void DumpCOMError(_com_error& e) {
    wcout << L"Error:" << endl;
    wcout << L"  Code = " << hex << e.Error() << endl;
    wcout << L"  Code meaning = " << e.ErrorMessage() << endl;
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());
    wcout << L"  Source = " << bstrSource << endl;
    wcout << L"  Description = " << bstrDescription << endl;
}

HRESULT IsXlsFileOpen(LPWSTR FileName, BOOL& file_open) {
    Excel::_ApplicationPtr pApplication;
    HRESULT hr = E_FAIL;
    if (FAILED(hr = pApplication.CreateInstance(L"Excel.Application"))) {
        file_open = FALSE;
        return hr;
    }

    _variant_t  varOption(static_cast<long>(DISP_E_PARAMNOTFOUND), VT_ERROR);
    Excel::_WorkbookPtr pBook;

    try {
        pBook = pApplication->Workbooks->Open(
                        FileName, 
                        varOption,
                        varOption,
                        varOption,
                        varOption,
                        varOption,
                        varOption,
                        varOption,
                        varOption,
                        varOption,
                        varOption,
                        varOption,
                        varOption);

        file_open = pBook->ReadOnly == VARIANT_TRUE;
        pBook->Close(VARIANT_FALSE);

        hr = S_OK;
    } catch (_com_error& e) {
        file_open = FALSE;
        DumpCOMError(e);
        hr = e.Error();
    }

    pApplication->Quit();
    return hr;
}

int main(int argc, wchar_t* argv[])
{
    CoInitialize(NULL);
    {
        BOOL fileOpen;
        HRESULT hr = IsXlsFileOpen(L"f:\\temp\\treta.xls", fileOpen);
        if (SUCCEEDED(hr)) {
            cout << "File is " << (fileOpen ? "open" : "not open") << "." << endl;
        }
        cout << "IsXlsFileOpen returned: 0x" << hex << hr << endl;
    }
    CoUninitialize();

    return 0;
}

一些应得的信用是有序的:

http://www.vbaexpress.com/kb/getarticle.php?kb_id=625

http://www.codeproject.com/KB/wtl/WTLExcel.aspx

http://www.codeguru.com/forum/printthread.php?s=26acdf89a1a6b79b7aa6a52e11b8d832&threadid=61997