Come aggiungere una finestra accanto al riquadro di anteprima in Outlook

INTRODUZIONE

In questo articolo viene descritto come utilizzare un componente aggiuntivo per aggiungere una finestra accanto al riquadro di anteprima in Microsoft Outlook. Questo metodo è destinato all'utilizzo con Outlook 2003, Outlook 2007 e Outlook 2010. Dopo che il componente aggiuntivo crea la finestra, il componente aggiuntivo può chiamare le API di Windows nella finestra esattamente come qualsiasi altri handle di finestra (HWND).

Ulteriori informazioni

In questo articolo vengono forniti esempi di codice e la relativa documentazione. Per scaricare il contenuto, visitare il seguente sito Web MSDN:

Importante Integrazione di Windows API (HWND) in Outlook non è una tecnologia della piattaforma supportata.

Siamo consapevoli che i clienti utilizzano già l'approccio di API Windows per l'integrazione con Outlook e Outlook Social Connector sfrutta anche questo tipo di integrazione. Documentazione relativa a finestre adiacenti in Outlook fornisce linee guida "procedure consigliate" per evitare conflitti con altri programmi che utilizzano questo approccio, tra cui Outlook Social Connector.

Questo esempio di codice e la documentazione corrispondente non sono supportati da Microsoft. Il gruppo di prodotti Outlook non considera questo approccio generale alla parte dell'architettura di Outlook supportati in termini di sviluppo di soluzioni personalizzate con Outlook. Si consiglia invece di utilizzare altri approcci più completamente progettati, testati, e documentati per l'utilizzo con Outlook. A seconda della versione di Outlook, questi altri approcci includono moduli personalizzati di Outlook, le aree di modulo, home page delle cartelle, i riquadri attività personalizzati e l'architettura di estensibilità di Outlook Social Connector (Oschooser). Il vantaggio dell'utilizzo di questi approcci supportati è che gli sviluppatori saranno molto maggiori possibilità che essi non rileverà i problemi di compatibilità quando una versione più recente o di rilascio del Service pack di Outlook.

Se si verificano problemi quando si utilizzano le informazioni fornite nel codice di esempio, è possibile registrare i commenti della pagina MSDN Code Gallery per il download. Tuttavia, è possibile garantire che il supporto verrà fornito per il problema.

Definizioni

Finestra di primo livelloFinestra di pari livelloFinestra adiacenteExplorerFinestra di ispezioneOutlook legacy
Handle della finestra di Outlook associato al desktop. Questo è il frame che contiene la finestra di explorer o la finestra di controllo.Nella finestra Esplora, questo è il riquadro di anteprima. Nella finestra di controllo, si tratta della finestra che contiene l'area client delle finestre di ispezione (intestazione del messaggio, oltre al corpo). La finestra adiacente è posizionata accanto alla finestra di pari livello.La finestra che il componente aggiuntivo crea accanto al riquadro di anteprima o la finestra di controllo.Finestra principale di Outlook che contiene il riquadro di spostamento, l'elenco dei messaggi e il riquadro di anteprima, ad esempio.Una finestra di Outlook che consente di visualizzare uno specifico articolo, ad esempio posta elettronica o appuntamenti.Outlook 2003 e Outlook 2007. In questo articolo, queste versioni vengono chiamate legacy in quanto la relativa gerarchia HWND è diverso da quello di Outlook 2010.

Prerequisiti

Il componente aggiuntivo deve includere un meccanismo per eseguire attività all'inattività. Ad esempio, può farlo tramite la creazione di una finestra nascosta che riceve messaggi WM_TIMER. Questo procedimento funziona perché WM_TIMER è un messaggio a priorità bassa che viene eseguito quando non sono presenti messaggi di priorità più elevati per l'elaborazione. Vedere il file Idlecall.cpp nel download sul sito Web di MSDN fornito all'inizio della sezione "Informazioni".

Tutte le istanze di Outlook

La funzione FindTopLevelWindows Cerca tutte le finestre di primo livello (la rctrl_renwnd32 classe messaggio di Outlook). Questa funzione viene chiamata quando viene inizializzato il componente aggiuntivo.

Per trovare le cornici della finestra di Esplora risorse, la funzione attraversa la gerarchia delle finestre della finestra di primo livello per individuare il riquadro di visualizzazione e il riquadro di anteprima (questa funzionalità differisce leggermente tra le installazioni precedenti di Outlook e Outlook 2010). Vedere le funzioni FindExplorerWindowse FindExplorerWindowsLegacyOutlook nel download. In questo caso, se la funzione Trova i riquadri di anteprima e visualizzazione, il riquadro di anteprima è considerato la finestra di pari livello.

Se la funzione non viene trovato il riquadro di anteprima, tenta di trovare una finestra che utilizza la classe di messaggio AfxWndW . Si tratta della finestra di pari livello per una finestra di controllo.

Se la funzione rileva la finestra di pari livello in caso di explorer o inspector, chiama FCreateHookedAdjacentWindow. Questo crea la finestra adiacente. I FCreateHookedAdjacentWindow sono hWndSibling (la finestra di pari livello), hWndParent (padre a hWndSibling, che deve essere il padre della finestra adiacente) e hWndTopLevelWindow (finestra di primo livello). Oltre a creare una finestra, FCreateHookedAdjacentWindow viene installato anche un hook del messaggio (WndProcHookedWindow). È possibile utilizzare questo hook del messaggio per determinare quando il riquadro di anteprima o la finestra di controllo è stata ridimensionata e quando la finestra adiacente deve quindi anche essere regolata.

Se si trova un elenco di cartelle finestra ma non un riquadro di anteprima in Esplora risorse, ciò significa che l'utente ha scelto di non visualizzare il riquadro di anteprima. FindExplorerWindows e FindExplorerWindowsLegacyOutlook installa un hook del messaggio (WndProcUnhookedWindow) che è in attesa del messaggio di WM_PARENTNOTIFY che viene inviato quando viene creata una finestra figlio. Quando si riceve questo messaggio, è possibile chiamare FindTopLevelWindows per determinare se è stato creato il riquadro di anteprima.

È anche ascoltare i Application.NewInspector e Application.NewExplorer eventi modello oggetti di Outlook (vedere il file Connect. cpp nel download) e quindi chiamare nuovamente la funzione FindTopLevelWindows quando viene ricevuto un messaggio. Poiché Outlook invia questi eventi prima di explorer corrispondente e handle di finestra di ispezione effettivamente creato, è necessario attendere inattivo prima di chiamare FindTopLevelWindows utilizzando il meccanismo della funzione inattivo.

Creare la finestra adiacente e associare l'oggetto modello di oggetto corrispondente che utilizza questa finestra

La funzione FMatchWindowToOMObject accetta una finestra di primo livello e tenta di associare un oggetto nel modello a oggetti, un elenco di cartelle o un controllo, in questa finestra. La funzione a tale scopo l'iterazione attraverso tutte le finestre di esplorazione e tutti i controlli chiamando QueryInterface sull'oggetto IDispatch del modello a oggetti per l'interfaccia IOleWindow, chiamata IOleWindow::GetWindowe gestire confrontando quindi l'handle di finestra che viene restituito dalla funzione di finestra di primo livello. Vedere la funzione HwndFromIDispatch .

Messaggio di hook di gestione

Entrambi gli hook di messaggio che si installa (WndProcHookedWindow e WndProcUnhookedWindow) devono rispondere al messaggio WM_REMOVING_WNDPROC. Ad esempio, si consideri lo scenario seguente:

Un componente aggiuntivo viene installato un hook del messaggio chiamando SetWindowLong(GWLP_WNDPROC). In questo modo dal precedente wndproc. Componenti B installa un hook del messaggio e quindi salvato dal precedente wndproc (installato da un componente aggiuntivo). Nella tabella seguente è illustrato il risultato.

Wndproc installatiRisparmiato wndproc precedente
Un componente aggiuntivoWndProcAWndProcO (originale)
Componente BWndProcBWndProcA

In una situazione tipica in cui viene eseguito l'override di un hook del messaggio, quando un componente aggiuntivo viene scaricato, questo imposta il messaggio di hook di WndProcO. E quando B componente aggiuntivo viene scaricata, questo hook del messaggio su WndProcA. Entrambe le azioni non sono corrette, e la seconda azione attiva un arresto anomalo se viene scaricato il componente aggiuntivo contenente WndProcA.

Per risolvere questo problema, ogni WndProc descritto in questo articolo deve supportare il messaggio WM_REMOVING_WNDPROC. Quando un componente aggiuntivo in fase di scaricamento e si desidera ripristinare il vecchio WndProc, dapprima chiama GetWindowLongPtr(GWLP_WNDPROC) , quindi Confronta WndProc corrente con WndProc è installato. Se queste istanze WndProc sono uguali, il componente aggiuntivo chiama SetWindowLongPtr(GWLP_WNDPROC) tramite WndProc precedente salvata. Se non sono uguali, il componente aggiuntivo invia il messaggio WM_REMOVING_WNDPROC a HWND, i valori wParam = = la vecchia WndProc e lParam = = WndProc sono stati installati. (Vedere la funzione WndProcInfo::Destroy ). Il valore restituito di invio del messaggio WM_REMOVING_WNDPROC deve essere sempre 1 per segnalare che il messaggio viene gestito. Asserzioni vengono aggiunti nel codice per rilevare se fosse stato fatto, questa procedura per il debug (anche se non c'è niente il componente aggiuntivo è possibile effettuare se il messaggio non è stato gestito).

Non appena ricevuta la WM_REMOVING_WNDPROC messaggio (vedere la funzione FHandleRemovingWndProc nel download), se lParam = = il nostro vecchio WndProc, scambia il nostro vecchio WndProc con wParam. In caso di questa operazione, WndProc restituisce il valore 1. Se i due valori non corrispondono, il messaggio viene inoltrato al vecchio WndProc tramite CallWindowProc, come di consueto.

Per un esempio: se si esamina la stessa situazione come accennato in precedenza con componente aggiuntivo e componente aggiuntivo B, in caso di scaricare un componente aggiuntivo, dovrebbe inviare il messaggio WM_REMOVING_WNDPROC alla finestra con wParam = WndProcO e lParam = WndProcA. Poiché il gestore di finestra registrati WndProcB, WndProcB sarebbe innanzitutto elaborare il messaggio. Poiché lParam = WndProcA e il vecchio WndProc memorizzati dai componenti B è anche WndProcB, quindi impostare il vecchio WndProc WndProcO componenti B e restituirà 1. Un componente aggiuntivo non eseguirà alcuna azione aggiuntiva. A questo punto, si tratta di diagramma schematico della b-in:

Wndproc installatiWndproc precedente
Componente BWndProcBWndProcO

Panoramica dell'hosting di più finestre adiacenti

Quando si desidera posizionare accanto al riquadro di anteprima finestre più componenti aggiuntivi, devono collaborare in modo che tutte le finestre si verificano in modo ordinato e non si sovrappongono tra loro. Il resto di questo articolo viene descritto come posizionare in modo cooperativo windows in windows explorer e inspector.

Nell'esempio di codice viene introdotto il concetto di elenco a doppio collegamento di finestre adiacenti. L'elenco collegato non viene gestito da Outlook o da un singolo componente aggiuntivo. I collegamenti "Avanti" e "prev" vengono mantenuti individualmente per ogni finestra adiacente. Quando un componente aggiuntivo si propone di creare una finestra adiacente, esso viene aggiunto all'inizio della lista collegata (vale a dire prec = NULL). Il capo dell'elenco collegato è responsabile del trattamento; si tratta della finestra che indirizza tutte le finestre come posizionare se stessi. Il controller è anche responsabile per ascoltare il messaggio WM_WINDOWPOSCHANGING della finestra di pari livello (vedere la funzione WndProcHookedWindow ).

La gestione del messaggio WM_WINDOWPOSCHANGING

Nell'esempio di codice viene installato un hook del messaggio (WndProcHookedWindow) per la finestra di pari livello. Lo scopo di gestire il messaggio per la finestra di pari livello è per regolare la posizione e dimensioni quando viene ridimensionata la finestra affinché room viene effettuata per le finestre adiacenti. Quando gestisce questo messaggio, il controller richiede tutte le finestre adiacenti (tramite il messaggio GetReservedRect descritto di seguito) la quantità di spazio necessario in ogni finestra. Poi, il controller che lo spazio dal rettangolo della finestra di pari livello (attraverso la struttura WINDOWPOS dal messaggio di WM_WINDOWPOSCHANGING) e quindi indica tutte le finestre adiacenti per spostare e disporre gli stessi (tramite il messaggio PlaceWindowAdjacentToRect ). Vedere la funzione CAdjacentWindow::SiblingWindowPosChanging .

La gestione del messaggio WM_NEGOTIATE_WINDOW_PANE

Tutte le finestre adiacenti devono elaborare il messaggio. Per questo messaggio, il parametro wParam è impostato su un sottocodice che inoltre specifica il messaggio. Vedere la funzione CAdjacentWindow::OnNegotiateWindow . Questo messaggio viene inviato da finestre adiacenti per comunicare tra loro. Il set successivo di dettaglio nelle sezioni di sottocodici diversi e le relative operazioni.

AddCustomWindowToTop

Questo messaggio viene inviato da una nuova finestra adiacente per aggiungersi all'elenco collegato di windows. lParam contiene l'handle di finestra della nuova finestra adiacente. Vedere la funzione CAdjacentWindow::FindTopMostInjectedPane per il processo di invio del messaggio. I passaggi di funzione per tutte le finestre figlio dell'elemento padre della finestra di pari livello, quindi la funzione Invia il messaggio a ogni finestra, a sua volta, finché non viene ricevuto un risultato diverso da zero.

Windows-controller non rispondere a questo messaggio tramite la restituzione di 0. Il controller risponde al messaggio impostando la relativa finestra "prev" per lParam (rendendo quindi non è il controller) e restituendo l'handle di finestra. La nuova finestra adiacente deve utilizzare come finestra "Avanti" e la nuova finestra diventa il controller.

Se non esistono alcun controller di dominio windows esistenti, la nuova finestra adiacente diventa il controller.

ReplacePrevWindow

Questo messaggio viene inviato a sostituire il puntatore del mouse su "prev" con il valore di lParam. Viene utilizzato da windows adiacenti per mantenere l'elenco collegato di windows quando vengono scaricati (vedere la funzione CAdjacentWindow::OnDestroy ).

ReplaceNextWindow

Questo messaggio viene inviato a sostituire il puntatore alla finestra "Avanti" con il valore di lParam.

GetReservedRect

Questo messaggio viene inviato a una finestra per determinare la quantità di spazio da riservare per esso. Questo messaggio deve essere inoltrato alla finestra "successiva", se presente. lParam contiene una struttura RECT inizializzato su 0,0,0,0 dal primo chiamante. Ogni finestra adiacente aggiunge alla struttura del volume di spazio necessaria. Ad esempio, un'adiacente finestra viene posizionata sotto il riquadro utenti aggiungere l'altezza desiderata per il valore di fondo. I valori di sinistra, alto, destra e inferiore non sono le coordinate, ma lo spazio totale previsto (vale a dire nessuno di questi valori deve essere negativo).

PlaceWindowAdjacentToRect

Questo messaggio viene inviato a una finestra adiacente quando la finestra adiacente si intende posizionarsi. lParam contiene una struttura RECT che inizializza il chiamante originale al client RECT della finestra di pari livello. Ogni finestra si posizionerà (possibilmente mediante SetWindowPos), modifica la struttura RECT in modo che il Rettangolo include ora la finestra adiacente e quindi inoltra il messaggio della finestra "Avanti". Ad esempio, una finestra viene posizionata sotto il riquadro di anteprima con altezza CY adiacente sarebbe posizionerà (rc.left, rc.bottom, rc.right – rc.left, CY) e quindi modificare la struttura RECT (rc.left, rc.top, rc.right, rc.bottom + CY). Quando tutte le finestre adiacenti sono stati completati i layout, la struttura RECT deve essere identica al client RECT della finestra padre. L'ultima asserzione in CAdjacentWindow::SiblingWindowPosChanging la funzione verifica che questo sia il caso.

RecalcPaneLayout

Questo messaggio viene inviato a chiedere il controller per eseguire un passaggio completo del layout. Non-controller di dominio windows deve inoltrare questo messaggio verso l'alto l'elenco collegato di finestre adiacenti. Il controller (vedere la funzione CAdjacentWindow::RecalcPreviewPaneLayoutController ) determina lo spazio disponibile corrente (l'area client della finestra padre), lo spazio richiesto (inviando un messaggio di GetReservedRect), quindi ridimensiona la finestra di pari livello e quindi invia il messaggio PlaceWindowAdjacentToRect eseguire il layout di tutte le finestre adiacenti.
Proprietà

ID articolo: 982758 - Ultima revisione: 31 gen 2017 - Revisione: 1

Microsoft Outlook 2010, Microsoft Office Outlook 2007, Microsoft Office Outlook 2003

Feedback