Help and Support

Identificativo articolo: 180625 - Ultima modifica: venerdì 29 giugno 2007 - Revisione: 5.1

How to Utilizzare l'automazione per modificare il menu di Office

In questa pagina

Espandi tutto | Chiudi tutto

Sommario

In questo articolo viene trattato un approccio all'utilizzo della libreria MFC (Microsoft Foundation Class) installata in Microsoft Visual C++ versioni 5.0 e 6.0 per gestire e modificare la barra dei menu delle applicazioni che fanno parte di Microsoft Office.

Tali applicazioni condividono un sistema di menu comune. Le applicazioni di Office comprendono Microsoft Word, Microsoft Excel, Microsoft Access, Microsoft PowerPoint e Microsoft Outlook. Ogni applicazione necessita di un menu personalizzato appropriato per le relative funzionalità e caratteristiche e carica il proprio menu dai componenti che sono disponibili nella raccolta di barre dei comandi di Office.

In questo articolo vengono presentati molti elementi del modello di oggetti CommandBars di Office, vengono discusse le proprietà e i metodi di tale oggetto e vengono illustrate modifiche di esempio. Questa dimostrazione specifica utilizza Microsoft Excel.

Informazioni

È possibile modificare il menu per un'applicazione di Office attraverso l'automazione, in modo permanente o temporaneo, caso in cui le modifiche di ciascuna sezione vengono reimpostate al termine della sessione. Alcune possono essere reimpostate automaticamente dal sistema, mentre altre devono essere reimpostate dal codice nel programma di automazione.

Con qualche adattamento il codice Visual C++ contenuto in questo articolo può essere utilizzato, ma lo scopo è quello di consentire l'apprendimento, sia esaminando il codice che eseguendo il programma.

Procedura per creare il progetto

  1. Eseguire i passaggi da 1 a 12 descritti nell'articolo della Microsoft Knowledge Base riportato di seguito per creare un progetto di esempio che utilizzi le interfacce IDispatch e le funzioni membro definite nella libreria dei tipi di Excel:
    178749  (http://support.microsoft.com/kb/178749/IT/ ) How to Create an Automation Project Using MFC and a Type Library
  2. Ripetere i passaggi 8, 9 e 10 dell'articolo appena citato per aggiungere al progetto la libreria dei tipi per Microsoft Office. La libreria Microsoft Office 97 si trova nel file Mso97.dll, mentre quella per Microsoft Office 2000 si trova nel file Mso9.dll. Il percorso predefinito è C:\Programmi\Microsoft Office\mso.dll. La libreria dei tipi per Microsoft Office 2002 si trova nel file Mso.dll. Il percorso predefinito è C:\Programmi\File comuni\Microsoft Shared\Office10.

    NOTA: selezionare tutti i componenti di tale libreria dei tipi. Verranno generati i file Mso.h e Mso.cpp che verranno aggiunti al progetto.

    Quando si esegue tale operazione si ottengono molti duplicati nelle classi del wrapper COleDispatchDriver, che derivano dalla duplicazione dei nomi IDispatch in Microsoft Excel 2000 o 2002 e Microsoft Office 2000 o Microsoft Office XP. Ad esempio, entrambi hanno un IDispatch denominato _Application.
  3. Per risolvere tali duplicazioni, nel caso di questo esercizio, utilizzare la funzionalità dello spazio dei nomi fornita da Visual C++. Nella parte superiore del file di intestazione Excel.h, inserire la riga:
          namespace XL {  // that's an opening brace.
    
    Nella parte inferiore di tale file aggiungere una riga che contenga solo le parentesi di chiusura e un punto e virgola ("};", senza virgolette).

  4. All'inizio del file Excel.cpp, in una nuova riga dopo la direttiva del compilatore "#endif", aggiungere la riga riportata di seguito:
          using namespace XL;
    
  5. Aggiungere le righe riportate di seguito alle istruzioni #include nella parte superiore del file di programma AutoProjectDlg.cpp:
          #include "excel9.h" // for Excel 2002, include excel.h
          #include "mso.h"
    
  6. Aggiungere il codice riportato di seguito al gestore dell'evento CAutoProjectDlg::OnRun() nel file AutoProjectDlg.cpp:

    Codice di esempio

           // Common OLE-variants. Easy variants to use for calling arguments.
          COleVariant
             covTrue((short)TRUE),
             covFalse((short)FALSE),
             covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
    
          HRESULT hr;
          DISPID dispID = 0;
          LPDISPATCH lpDisp = 0;
          VARIANT vResult;  // A Struct with a pdispVal member
          long cCount = 0;
          char buf[2048];   // General purpose message buffers
          OLECHAR *strCBs = L"CommandBars";
          // Object declarations.
          XL::_Application app;  // The XL prefix specifies the namerange.
          XL::Workbooks oWorkbooks;
          XL::_Workbook oBook;
          XL::Worksheets oWorksheets;
          XL::_Worksheet oSheet;
          XL::Shapes oShapes;
          XL::Shape oShape;
          // More objects will be declared throughout the program.
    
          // Create and show instance of Excel.
          if(!app.CreateDispatch("Excel.Application"))
          {
             AfxMessageBox("Failed to create Excel.Application");
             return;
          }
    
          // Excel visibility makes Office Menu Bar visible.
          app.SetVisible(TRUE);
          oWorkbooks  = app.GetWorkbooks();
          oBook       = oWorkbooks.Add(covOptional);
          oWorksheets = oBook.GetWorksheets();
          oSheet      = oWorksheets.GetItem(COleVariant((short)3));
          oSheet.Activate();  // Make the sheet selection work
    
          // Find &strCBs, i.e. L"CommandBars" and put it in dispID.
          hr = app.m_lpDispatch->GetIDsOfNames(IID_NULL, &strCBs, 1,
                                             LOCALE_SYSTEM_DEFAULT,
                                             &dispID);
          if(FAILED(hr))
          {
             sprintf(buf,"Failed to GetIDsOfNames() :(... Error = %08lx",
                (long)hr);
             AfxMessageBox(buf,MB_SETFOREGROUND);
          }
    
    
          // Get a dispatch pointer to CommandBars! Use that of running
          //  application's (Excel) existing menu configuration.
          // "vResult" is a VARIANT. It's declared above.
          app.InvokeHelper(dispID, DISPATCH_METHOD | DISPATCH_PROPERTYGET,
                         VT_VARIANT, (void*)&vResult, NULL);
    
          sprintf(buf,
             "CommandBars dispID = %ld \n"
             "CommandBars IDispatch pointer is %08lx",
             (long) dispID, (long)vResult.pdispVal);
          AfxMessageBox(buf, MB_SETFOREGROUND);
    
          CommandBars cbs(vResult.pdispVal);   // Pre Office XP
          _CommandBars cbs(vResult.pdispVal);  // Construct the CommandBars
                                               // object and attach the
                                               // IDispatch pointer to it.
    
          cCount = cbs.GetCount();   // 114 for Excel, Word has more!!??
                                    //  MSOffice reconfigures for each
                                    //  user-application.
    
          sprintf(buf, "Count of CommandBars is %d", cCount);
          AfxMessageBox(buf, MB_SETFOREGROUND);
    
          vResult.pdispVal = cbs.GetActiveMenuBar();  // Returns a LPDISPATCH
                                //  pointer of the CommandBar object that
                                //  represents the active menu bar in the
                                //  container application; that is, MS Office's
                                //  Excel Menu Bar Configuration.
          sprintf( buf, "dispatch pointer to the ActiveMenuBar is %08lx",
                 (long)vResult.pdispVal);
          AfxMessageBox(buf, MB_SETFOREGROUND);
    
          CommandBar oBar(vResult.pdispVal);  // Construct a CommandBar object
                                              // & attach the LPDispatch
                                              // of the active menu bar.
    
          CString cBarName = oBar.GetName();  // "Worksheet Menu Bar"
          sprintf(buf, "Name of the menu bar is %s", (LPCTSTR)cBarName);
          AfxMessageBox(buf, MB_SETFOREGROUND);
    
          CString cBarNameLocal = oBar.GetNameLocal();  // "Worksheet Menu Bar"
          sprintf(buf, "Local language's name of the menu bar is %s",
                 (LPCTSTR)cBarNameLocal);
          AfxMessageBox(buf, MB_SETFOREGROUND);
    
          long iMenuBarType = oBar.GetType();  // 1
          sprintf(buf, "Type of Menu Bar is %d,", (long)iMenuBarType);
          AfxMessageBox(buf, MB_SETFOREGROUND);
    
          vResult.pdispVal = oBar.GetControls();  // CommandBarControls
                                                  //  IDispatch pointer
    
    
          // Construct a CommandBarControls object, and attach the IDispatch
          //  pointer for CommandBarControls to that oBarcontrols object.
          CommandBarControls oBarcontrols(vResult.pdispVal);
    
          // Construct a CommandBarControl for the 6th item in the
          // ComandBarControls collection,
          // and attach a IDispatch pointer to it.
          CommandBarControl cbCtl=oBarcontrols.GetItem(COleVariant((short)6)
                                                     );
    
          CString ccCaption = cbCtl.GetCaption();   // "&Tools"
          long iiType       = cbCtl.GetType();      // = 10
          long iiIndex      = cbCtl.GetIndex();     // 10
          long iiId         = cbCtl.GetId();        // 30007
          CString ccTag     = cbCtl.GetTag();       // blank
    
          sprintf(buf,
             "Caption of Control # 6 is %s\n"
             "'Type' property of Control # 6 is %d\n"
             "'Index' property of Control # 6 is %d\n"
             "'Id' property of Control # 6 is %d\n",
             (LPCTSTR)ccCaption, iiType, iiIndex, iiId);
    
          if("" == ccTag)
             strcat(buf, "Control #6 has noTag property");
          else
             sprintf(buf + strlen(buf), "Tag of Control #6 is %s",
                (LPCTSTR)ccTag);
    
          AfxMessageBox(buf, MB_SETFOREGROUND);
    
          // Get a pointer for CommandBarPopup object with the ID of 30005.
          vResult.pdispVal = oBar.FindControl(
             COleVariant((short)10),
             // msoControlPopup type
             COleVariant((long)30005),
             covOptional,
             covOptional,
             covOptional);
    
          sprintf(buf, "IDispatch pointer of the msoControlPopup is %08lx",
               (long)vResult.pdispVal);
          AfxMessageBox(buf,MB_SETFOREGROUND);
    
          // Construct a Popup Control object and
          // Attach the IDispatch pointer of CommandBarPopup
          // to that new control object.
          CommandBarControl cbPop(vResult.pdispVal);
          ccCaption   = cbPop.GetCaption();
          iiType      = cbPop.GetType();
          iiIndex     = cbPop.GetIndex();
          iiId        = cbPop.GetId();
    
          sprintf(buf,
             "Caption of ControlPopup is %s\n"
             "'Type' property of ControlPopup is %d\n"
             "'Index' property of ControlPopup is %d\n"
             "'Id' property of ControlPopup is %d\n",
             (LPCTSTR)ccCaption, iiType, iiIndex, iiId);
          AfxMessageBox(buf,MB_SETFOREGROUND);
    
          sprintf(buf, "Watch the %s menu pad disappear.",
                (LPCTSTR)ccCaption);
          AfxMessageBox(buf, MB_SETFOREGROUND);
    
    
          cbPop.Delete(covTrue);
    
          oShapes =  oSheet.GetShapes();  // Shapes collection,
                                        // is empty at first.
          AfxMessageBox("Adding a SmileyFace  to be used in testing");
    
          // It's a msoShapesSmileyFace AutoShape
          oShape = oShapes.AddShape( 17, 10.0, 10.0, 40.0, 40.0);
    
          CommandBar iBar;
          // Use the count of commandbars in the CommandBars object.
          for (int i = 1; i <= cCount; i++)
          {
             iBar = cbs.GetItem(COleVariant((short)i));
             // To see the names of all the command bars,
             //  uncomment the next 2 lines:
             // sprintf(buf, "Name of  CommandBar is %s", iBar.GetName());
             // AfxMessageBox(buf, MB_SETFOREGROUND);
             if( "Shapes" == iBar.GetName())
             {
                iBar.SetEnabled(TRUE);
                long lType = iBar.GetType();
                sprintf(buf,
                   "For CommandBars(%d), the 'Shapes' shortcut, "
                   "Type property is %d",
                   i, lType);
                AfxMessageBox(buf, MB_SETFOREGROUND);
                break;
             }
          }  // End of For loop.
    
          // Construct and attach IDispatch pointer to
          // CommandBarControls object.
          CommandBarControls oCBCs = iBar.GetControls();
          CommandBarControl oCBC = oCBCs.Add(
             COleVariant((short)1),
             //  msoControlButton const
             //   VARIANT& Type,
             covOptional, //const VARIANT& Id,
             covOptional, //const VARIANT&
             //  Parameter, to pass with OnAction
             covOptional, //const VARIANT&
             //  Before,
             //  Location on popup before item #
             covTrue  //const VARIANT& Temporary,
             //  (delete when app quits).
          );
    
          oCBC.SetCaption("Run Macro #1");
          oCBC.SetVisible(TRUE);
          oCBC.SetEnabled(TRUE);
          // oCBC.SetOnAction("Macro1");
            // You'd uncomment the line above and substitute
            // the correct name of the desired Excel macro.
    
          sprintf(buf,
             "You've just added a CommandBarButtonControl "
             "to the shortcut menu for SmileyFace.\n"
             "Right-click on a handle of the SmileyFace to see the new "
             "line at the bottom of the context menu.\n\n"
             "     -     it says 'Run Macro #1'.\n\n"
             "Save the worksheet and close Excel when "
             "you're through examining the change.\n\n"
             "Then, reload Excel and open the worksheet "
             "from the MRU list. \n"
             "The new CommandBarButtonControl was "
             "temporary, so it's gone.");
          AfxMessageBox(buf, MB_SETFOREGROUND);
          return;

Riferimenti

Per ulteriori informazioni sull'automazione delle applicazioni di Office, fare clic sul numero dell'articolo della Microsoft Knowledge Base riportato di seguito:
222101  (http://support.microsoft.com/kb/222101/IT/ ) How to Find and Use Office Object Model Documentation
Oppure visitare il seguente sito Web Microsoft (informazioni in lingua inglese):
http://msdn2.microsoft.com/en-us/library/aa188489(office.10).aspx (http://msdn2.microsoft.com/en-us/library/aa188489(office.10).aspx)

Le informazioni in questo articolo si applicano a
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 6.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Visual C++ 6.0 Professional Edition
  • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • Microsoft Foundation Class Library 4.2
  • Microsoft Office XP Developer Edition
  • Microsoft Office 2000 Developer Edition
  • Microsoft Office 97 Standard Edition
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 97 Standard Edition
Chiavi: 
kbhowto kbinterop kbautomation KB180625
LE INFORMAZIONI CONTENUTE NELLA MICROSOFT KNOWLEDGE BASE SONO FORNITE SENZA GARANZIA DI ALCUN TIPO, IMPLICITA OD ESPLICITA, COMPRESA QUELLA RIGUARDO ALLA COMMERCIALIZZAZIONE E/O COMPATIBILITA' IN IMPIEGHI PARTICOLARI. L'UTENTE SI ASSUME L'INTERA RESPONSABILITA' PER L'UTILIZZO DI QUESTE INFORMAZIONI. IN NESSUN CASO MICROSOFT CORPORATION E I SUOI FORNITORI SI RENDONO RESPONSABILI PER DANNI DIRETTI, INDIRETTI O ACCIDENTALI CHE POSSANO PROVOCARE PERDITA DI DENARO O DI DATI, ANCHE SE MICROSOFT O I SUOI FORNITORI FOSSERO STATI AVVISATI. IL DOCUMENTO PUO' ESSERE COPIATO E DISTRIBUITO ALLE SEGUENTI CONDIZIONI: 1) IL TESTO DEVE ESSERE COPIATO INTEGRALMENTE E TUTTE LE PAGINE DEVONO ESSERE INCLUSE. 2) I PROGRAMMI SE PRESENTI, DEVONO ESSERE COPIATI SENZA MODIFICHE, 3) IL DOCUMENTO DEVE ESSERE DISTRIBUITO INTERAMENTE IN OGNI SUA PARTE. 4) IL DOCUMENTO NON PUO' ESSERE DISTRIBUITO A SCOPO DI LUCRO.

Traduzione articoli