DetailPage-MSS-KB

Knowledge Base

Artikel ID: 216686 - Laatste beoordeling: donderdag 6 oktober 2011 - Wijziging: 3.0

 

Samenvatting

Er zijn diverse voordelen op het schrijven van de automatisering in rechte C++ code. Eerst en vooral, kunt u precies wat u wilt doen. De code wordt vervolgens worden kleiner, sneller en gemakkelijker fouten opsporen. En ten slotte niet alle bibliotheken afhankelijk zijn. Zelfs als u speciaal voor het gebruik van MFC wrapperklassen of Visual C++ eigen COM-ondersteuning (# import), kan u nog steeds moeten dieper ingaan op de ingewanden van IDispatch- en COM-automatisering om te werken rond bugs en beperkingen met deze kaders.

Meer informatie

Volg onderstaande stappen voor het bouwen van een eenvoudige Visual C++ 6. 0 console toepassing waarmee u Microsoft Office Excel met alleen C++:
  1. Start Visual C++ 6. 0 en maak een nieuwe Win32-Console Toepassing met de naam XlCpp. Kies een toepassing "Hello, World!" basis en opVoltooien.
  2. Open het gegenereerde XlCpp.cpp en voeg de volgende code voordat u de functie Main ().
    #include <ole2.h> // OLE2 Definitions
    
    // AutoWrap() - Automation helper function...
    HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) {
        // Begin variable-argument list...
        va_list marker;
        va_start(marker, cArgs);
    
        if(!pDisp) {
            MessageBox(NULL, "NULL IDispatch passed to AutoWrap()", "Error", 0x10010);
            _exit(0);
        }
    
        // Variables used...
        DISPPARAMS dp = { NULL, NULL, 0, 0 };
        DISPID dispidNamed = DISPID_PROPERTYPUT;
        DISPID dispID;
        HRESULT hr;
        char buf[200];
        char szName[200];
    
        
        // Convert down to ANSI
        WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
        
        // Get DISPID for name passed...
        hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
        if(FAILED(hr)) {
            sprintf(buf, "IDispatch::GetIDsOfNames(\"%s\") failed w/err 0x%08lx", szName, hr);
            MessageBox(NULL, buf, "AutoWrap()", 0x10010);
            _exit(0);
            return hr;
        }
        
        // Allocate memory for arguments...
        VARIANT *pArgs = new VARIANT[cArgs+1];
        // Extract arguments...
        for(int i=0; i<cArgs; i++) {
            pArgs[i] = va_arg(marker, VARIANT);
        }
        
        // Build DISPPARAMS
        dp.cArgs = cArgs;
        dp.rgvarg = pArgs;
        
        // Handle special-case for property-puts!
        if(autoType & DISPATCH_PROPERTYPUT) {
            dp.cNamedArgs = 1;
            dp.rgdispidNamedArgs = &dispidNamed;
        }
        
        // Make the call!
        hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);
        if(FAILED(hr)) {
            sprintf(buf, "IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr);
            MessageBox(NULL, buf, "AutoWrap()", 0x10010);
            _exit(0);
            return hr;
        }
        // End variable-argument section...
        va_end(marker);
        
        delete [] pArgs;
        
        return hr;
    }
    						
  3. Vervang de regel printf() binnen de functie Main) de volgende code.
       // Initialize COM for this thread...
       CoInitialize(NULL);
    
       // Get CLSID for our server...
       CLSID clsid;
       HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid);
    
       if(FAILED(hr)) {
    
          ::MessageBox(NULL, "CLSIDFromProgID() failed", "Error", 0x10010);
          return -1;
       }
    
       // Start server and get IDispatch...
       IDispatch *pXlApp;
       hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&pXlApp);
       if(FAILED(hr)) {
          ::MessageBox(NULL, "Excel not registered properly", "Error", 0x10010);
          return -2;
       }
    
       // Make it visible (i.e. app.visible = 1)
       {
    
          VARIANT x;
          x.vt = VT_I4;
          x.lVal = 1;
          AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlApp, L"Visible", 1, x);
       }
    
       // Get Workbooks collection
       IDispatch *pXlBooks;
       {
          VARIANT result;
          VariantInit(&result);
          AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"Workbooks", 0);
          pXlBooks = result.pdispVal;
       }
    
       // Call Workbooks.Add() to get a new workbook...
       IDispatch *pXlBook;
       {
          VARIANT result;
          VariantInit(&result);
          AutoWrap(DISPATCH_PROPERTYGET, &result, pXlBooks, L"Add", 0);
          pXlBook = result.pdispVal;
       }
    
       // Create a 15x15 safearray of variants...
       VARIANT arr;
       arr.vt = VT_ARRAY | VT_VARIANT;
       {
          SAFEARRAYBOUND sab[2];
          sab[0].lLbound = 1; sab[0].cElements = 15;
          sab[1].lLbound = 1; sab[1].cElements = 15;
          arr.parray = SafeArrayCreate(VT_VARIANT, 2, sab);
       }
    
       // Fill safearray with some values...
       for(int i=1; i<=15; i++) {
          for(int j=1; j<=15; j++) {
             // Create entry value for (i,j)
             VARIANT tmp;
             tmp.vt = VT_I4;
             tmp.lVal = i*j;
             // Add to safearray...
             long indices[] = {i,j};
             SafeArrayPutElement(arr.parray, indices, (void *)&tmp);
          }
       }
    
       // Get ActiveSheet object
       IDispatch *pXlSheet;
       {
          VARIANT result;
          VariantInit(&result);
          AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"ActiveSheet", 0);
          pXlSheet = result.pdispVal;
       }
    
       // Get Range object for the Range A1:O15...
       IDispatch *pXlRange;
       {
          VARIANT parm;
          parm.vt = VT_BSTR;
          parm.bstrVal = ::SysAllocString(L"A1:O15");
    
          VARIANT result;
          VariantInit(&result);
          AutoWrap(DISPATCH_PROPERTYGET, &result, pXlSheet, L"Range", 1, parm);
          VariantClear(&parm);
    
          pXlRange = result.pdispVal;
       }
    
       // Set range with our safearray...
       AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlRange, L"Value", 1, arr);
    
       // Wait for user...
       ::MessageBox(NULL, "All done.", "Notice", 0x10000);
    
       // Set .Saved property of workbook to TRUE so we aren't prompted
       // to save when we tell Excel to quit...
       {
          VARIANT x;
          x.vt = VT_I4;
          x.lVal = 1;
          AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlBook, L"Saved", 1, x);
       }
    
       // Tell Excel to quit (i.e. App.Quit)
       AutoWrap(DISPATCH_METHOD, NULL, pXlApp, L"Quit", 0);
    
       // Release references...
       pXlRange->Release();
       pXlSheet->Release();
       pXlBook->Release();
       pXlBooks->Release();
       pXlApp->Release();
       VariantClear(&arr);
    
       // Uninitialize COM for this thread...
       CoUninitialize();
    						
  4. Compileren en uitvoeren.
De AutoWrap() functie vereenvoudigt de meeste van de low-level betrokken zijn bij de IDispatch rechtstreeks met details. Voel vrij om te gebruiken in uw eigen implementaties. Een voorbehoud is dat als u meerdere parameters doorgeven, ze moeten in omgekeerde volg orde worden doorgegeven. Bijvoorbeeld:
    VARIANT parm[3];
    parm[0].vt = VT_I4; parm[0].lVal = 1;
    parm[1].vt = VT_I4; parm[1].lVal = 2;
    parm[2].vt = VT_I4; parm[2].lVal = 3;
    AutoWrap(DISPATCH_METHOD, NULL, pDisp, L"call", 3, parm[2], parm[1], parm[0]);
				

Referenties

Klik op de volgende artikel nummers in de Microsoft Knowledge Base voor meer informatie over Office automatiseren met Visual C++:
196776  (http://support.microsoft.com/kb/196776/ ) Office automatisering met Visual C++
216388  (http://support.microsoft.com/kb/216388/ ) B2CSE.exe converteert Visual Basic Auto mat ion code naar Visual C++
(c) 1999 Microsoft Corporation, alle rechten voorbehouden. Bijdragen Joe Crump, Microsoft Corporation.


De informatie in dit artikel is van toepassing op:
  • Microsoft Office Excel 2007
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 97 Standard Edition
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
Trefwoorden: 
kbautomation kbhowto kbmt KB216686 KbMtnl
Machine-translated ArticleMachine-translated Article
BELANGRIJK: Dit artikel is vertaald door de vertaalmachine software van Microsoft in plaats van door een professionele vertaler. Microsoft biedt u professioneel vertaalde artikelen en artikelen vertaald door de vertaalmachine, zodat u toegang heeft tot al onze knowledge base artikelen in uw eigen taal. Artikelen vertaald door de vertaalmachine zijn niet altijd perfect vertaald. Deze artikelen kunnen fouten bevatten in de vocabulaire, zinsopbouw en grammatica en kunnen lijken op hoe een anderstalige de taal spreekt en schrijft. Microsoft is niet verantwoordelijk voor onnauwkeurigheden, fouten en schade ontstaan door een incorrecte vertaling van de content of het gebruik ervan door onze klanten. Microsoft past continue de kwaliteit van de vertaalmachine software aan door deze te updaten.
De Engelstalige versie van dit artikel is de volgende:216686  (http://support.microsoft.com/kb/216686/en-us/ )
Delen
Extra ondersteuningsopties
Microsoft Community Support-forums
Neem rechtstreeks contact met ons op
Een door Microsoft gecertificeerde partner zoeken
Microsoft Store