2

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

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

附加到现有 Excel 文件的 C++/COM 代码是什么?如何确定文件当前是否由 Excel 实例打开?假设我知道文件名。我用谷歌搜索了 15 分钟,但没有找到没有 MFC 的方法。

4

1 回答 1

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

于 2008-10-02T15:58:03.857 回答