2 Stimmen

Wie man eine vorhandene Datei mit COM/ATL (ohne MFC) öffnet

Ich habe eine bestehende Windows C++ Anwendung, die mit ATL verknüpft ist. Ich muss eine vorhandene Excel-Datei öffnen und auf einige Eigenschaften zugreifen. Eines der Dinge, die ich tun muss, ist festzustellen, ob der Benutzer die Excel-Datei derzeit ansieht.

Wir können davon ausgehen, dass der Benutzer Excel installiert hat, obwohl ich nicht sicher bin, welche Version.

Was ist der C++ / COM-Code, um sich an eine vorhandene Excel-Datei anzuhängen? Wie kann ich feststellen, ob die Datei derzeit von einer Instanz von Excel geöffnet ist? Gehen Sie davon aus, dass ich den Dateinamen kenne. Ich habe 15 Minuten lang im Internet gesucht, aber noch nicht herausgefunden, wie man dies ohne MFC macht.

3voto

Jorge Ferreira Punkte 92489

Schöne Herausforderung. Und weil eine Herausforderung nicht abgelehnt werden kann, setzte ich mich vor Visual Studio und hier ist eine mögliche Lösung.

#include 
#include 

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"Fehler:" << endl;
    wcout << L"  Code = " << hex << e.Error() << endl;
    wcout << L"  Code-Bedeutung = " << e.ErrorMessage() << endl;
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());
    wcout << L"  Quelle = " << bstrSource << endl;
    wcout << L"  Beschreibung = " << 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(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 << "Datei ist " << (fileOpen ? "geöffnet" : "nicht geöffnet") << "." << endl;
        }
        cout << "IsXlsFileOpen zurückgegeben: 0x" << hex << hr << endl;
    }
    CoUninitialize();

    return 0;
}

Einige verdiente Credits sind angebracht:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X