TN071: implementazione di IOleCommandTarget MFC
Nota
La seguente nota tecnica non è stata aggiornata da quando è stata inclusa per la prima volta nella documentazione online. Di conseguenza, alcune procedure e argomenti potrebbero essere non aggiornati o errati. Per le informazioni più recenti, è consigliabile cercare l'argomento di interesse nell'indice della documentazione online.
L'interfaccia IOleCommandTarget
consente agli oggetti e ai relativi contenitori di inviare comandi l'uno all'altro. Ad esempio, le barre degli strumenti di un oggetto possono contenere pulsanti per comandi come Print
, Print Preview
Save
, New
, e Zoom
. Se un oggetto di questo tipo è stato incorporato in un contenitore che supporta IOleCommandTarget
, l'oggetto potrebbe abilitare i pulsanti e inoltrare i comandi al contenitore per l'elaborazione quando l'utente ne ha fatto clic. Se un contenitore desidera che l'oggetto incorporato stampasse se stesso, potrebbe effettuare questa richiesta inviando un comando tramite l'interfaccia IOleCommandTarget
dell'oggetto incorporato.
IOleCommandTarget
è un'interfaccia simile all'automazione in quanto viene usata da un client per richiamare i metodi in un server. Tuttavia, l'uso IOleCommandTarget
di consente di risparmiare il sovraccarico di effettuare chiamate tramite interfacce di automazione perché i programmatori non devono usare il metodo in genere costoso Invoke
di IDispatch
.
In MFC l'interfaccia IOleCommandTarget
viene utilizzata dai server documenti attivi per consentire ai contenitori di documenti attivi di inviare comandi al server. La classe server di documenti active, CDocObjectServerItem
, usa le mappe dell'interfaccia MFC (vedere TN038: MFC/OLE IUnknown Implementation) per implementare l'interfaccia IOleCommandTarget
.
IOleCommandTarget
viene implementato anche nella COleFrameHook
classe . COleFrameHook
è una classe MFC non documentata che implementa la funzionalità della finestra cornice dei contenitori di modifica sul posto. COleFrameHook
usa anche mappe dell'interfaccia MFC per implementare l'interfaccia IOleCommandTarget
. COleFrameHook
L'implementazione di IOleCommandTarget
inoltra i comandi OLE ai COleDocObjectItem
contenitori di documenti attivi derivati da . Ciò consente a qualsiasi contenitore di documenti attivo MFC di ricevere messaggi da server documenti attivi contenuti.
Mappe dei comandi OLE MFC
Gli sviluppatori MFC possono sfruttare i vantaggi usando le mappe dei IOleCommandTarget
comandi OLE MFC. Le mappe dei comandi OLE sono simili alle mappe messaggi perché possono essere usate per eseguire il mapping dei comandi OLE alle funzioni membro della classe che contiene la mappa dei comandi. Per eseguire questa operazione, posizionare le macro nella mappa dei comandi per specificare il gruppo di comandi OLE del comando che si desidera gestire, il comando OLE e l'ID comando del messaggio WM_COMMAND che verrà inviato quando viene ricevuto il comando OLE. MFC fornisce anche una serie di macro predefinite per i comandi OLE standard. Per un elenco dei comandi OLE standard originariamente progettati per l'uso con Microsoft app Office lications, vedere l'enumerazione OLECMDID, definita in docobj.h.
Quando un comando OLE viene ricevuto da un'applicazione MFC che contiene una mappa dei comandi OLE, MFC tenta di trovare l'ID comando e il gruppo di comandi per il comando richiesto nella mappa dei comandi OLE dell'applicazione. Se viene trovata una corrispondenza, viene inviato un messaggio di WM_COMMAND all'applicazione contenente la mappa dei comandi con l'ID del comando richiesto. Vedere la descrizione di ON_OLECMD
seguito. In questo modo, i comandi OLE inviati a un'applicazione vengono trasformati in messaggi WM_COMMAND da MFC. I messaggi WM_COMMAND vengono quindi instradati attraverso le mappe messaggi dell'applicazione usando l'architettura di routing dei comandi standard MFC.
A differenza delle mappe messaggi, le mappe dei comandi OLE MFC non sono supportate da ClassWizard. Gli sviluppatori MFC devono aggiungere a mano il supporto della mappa dei comandi OLE e le voci della mappa dei comandi OLE. Le mappe dei comandi OLE possono essere aggiunte ai server documenti attivi MFC in qualsiasi classe presente nella catena di routing dei messaggi WM_COMMAND al momento in cui il documento attivo è attivo in un contenitore. Queste classi includono le classi dell'applicazione derivate da CWinApp, CView, CDocument e COleIPFrameWnd. Nei contenitori di documenti attivi le mappe dei comandi OLE possono essere aggiunte solo alla classe derivata da COleDocObjectItem. Inoltre, nei contenitori di documenti attivi, i messaggi WM_COMMAND verranno inviati solo alla mappa dei messaggi nella COleDocObjectItem
classe derivata da .
Macro della mappa dei comandi OLE
Usare le macro seguenti per aggiungere la funzionalità della mappa dei comandi alla classe :
DECLARE_OLECMD_MAP ()
Questa macro viene inserita nella dichiarazione di classe (in genere nel file di intestazione) della classe che contiene la mappa dei comandi.
BEGIN_OLECMD_MAP(theClass, baseClass)
theClass
Nome della classe che contiene la mappa dei comandi.
Baseclass
Nome della classe base della classe che contiene la mappa dei comandi.
Questa macro contrassegna l'inizio della mappa dei comandi. Utilizzare questa macro nel file di implementazione per la classe che contiene la mappa dei comandi.
END_OLECMD_MAP()
Questa macro contrassegna la fine della mappa dei comandi. Utilizzare questa macro nel file di implementazione per la classe che contiene la mappa dei comandi. Questa macro deve sempre seguire la macro BEGIN_OLECMD_MAP.
ON_OLECMD(pguid, olecmdid, id)
pguid
Puntatore al GUID del gruppo di comandi del comando OLE. Questo parametro è NULL per il gruppo di comandi OLE standard.
olecmdid
ID comando OLE del comando da richiamare.
id
ID del messaggio di WM_COMMAND da inviare all'applicazione contenente la mappa dei comandi quando viene richiamato questo comando OLE.
Utilizzare la macro ON_OLECMD nella mappa dei comandi per aggiungere voci per i comandi OLE da gestire. Quando vengono ricevuti i comandi OLE, questi verranno convertiti nel messaggio di WM_COMMAND specificato e instradati tramite la mappa messaggi dell'applicazione usando l'architettura di routing dei comandi MFC standard.
Esempio
Nell'esempio seguente viene illustrato come aggiungere la funzionalità di gestione dei comandi OLE a un server di documenti attivo MFC per gestire il comando OLE OLECMDID_PRINT . In questo esempio si presuppone che sia stato usato AppWizard per generare un'applicazione MFC che è un server documenti attivo.
CView
Nel file di intestazione della classe derivata da , aggiungere la macro DECLARE_OLECMD_MAP alla dichiarazione di classe.Nota
Utilizzare la
CView
classe derivata da perché è una delle classi nel server di documenti attivo presente nella catena di routing dei messaggi WM_COMMAND.class CMyServerView : public CView { protected: // create from serialization only CMyServerView(); DECLARE_DYNCREATE(CMyServerView) DECLARE_OLECMD_MAP() // . . . };
Nel file di implementazione per la
CView
classe derivata da aggiungere le macro BEGIN_OLECMD_MAP e END_OLECMD_MAP:BEGIN_OLECMD_MAP(CMyServerView, CView) END_OLECMD_MAP()
Per gestire il comando di stampa OLE standard, aggiungere una macro ON_OLECMD alla mappa dei comandi specificando l'ID comando OLE per il comando di stampa standard e ID_FILE_PRINT per l'ID WM_COMMAND. ID_FILE_PRINT è l'ID comando di stampa standard usato dalle applicazioni MFC generate da AppWizard:
BEGIN_OLECMD_MAP(CMyServerView, CView) ON_OLECMD(NULL, OLECMDID_PRINT, ID_FILE_PRINT) END_OLECMD_MAP()
Si noti che una delle macro dei comandi OLE standard, definita in afxdocob.h, può essere usata al posto della macro ON_OLECMD perché OLECMDID_PRINT è un ID comando OLE standard. La macro ON_OLECMD_PRINT eseguirà la stessa attività della macro ON_OLECMD illustrata in precedenza.
Quando un'applicazione contenitore invia questo server un comando OLECMDID_PRINT tramite l'interfaccia del IOleCommandTarget
server, il gestore dei comandi di stampa MFC verrà richiamato nel server, causando la stampa dell'applicazione da parte del server. Il codice del contenitore di documenti attivi per richiamare il comando di stampa aggiunto nei passaggi precedenti sarà simile al seguente:
void CContainerCntrItem::DoOleCmd()
{
IOleCommandTarget *pCmd = NULL;
HRESULT hr = E_FAIL;
OLECMD ocm={OLECMDID_PRINT, 0};
hr = m_lpObject->QueryInterface(
IID_IOleCommandTarget,reinterpret_cast<void**>(&pCmd));
if (FAILED(hr))
return;
hr = pCmd->QueryStatus(NULL, 1, &ocm, NULL);
if (SUCCEEDED(hr) && (ocm.cmdf& OLECMDF_ENABLED))
{
//Command is available and enabled so call it
COleVariant vIn;
COleVariant vOut;
hr = pCmd->Exec(NULL, OLECMDID_PRINT,
OLECMDEXECOPT_DODEFAULT, &vIn, &vOut);
ASSERT(SUCCEEDED(hr));
}
pCmd->Release();
}