Configuración de un complemento de estado sin conexión
Hace referencia a: Outlook 2013 | Outlook 2016
Para implementar un complemento de estado sin conexión, debe implementar la conexión, la inicialización y otras funciones de instalación. En este tema, estas funciones de conexión, inicialización y configuración se muestran mediante ejemplos de código del complemento de estado sin conexión de ejemplo. El complemento estado sin conexión de muestra es un complemento COM que agrega un menú Estado sin conexión a Outlook y usa la API de estado sin conexión. A través del menú Estado sin conexión , puede habilitar o deshabilitar la supervisión de estado, comprobar el estado actual y cambiar el estado actual. Para obtener más información sobre cómo descargar e instalar el complemento estado sin conexión de muestra, vea Instalar el complemento de estado sin conexión de muestra. Para obtener más información acerca de la API de estado sin conexión, vea Información sobre la API de estado sin conexión.
Después de configurar un complemento de estado sin conexión, debe implementar funciones para supervisar y modificar los cambios de estado de conexión. Para obtener más información, vea Supervisión de cambios de estado de conexión mediante un complemento de estado sin conexión.
En la rutina de conexión
Se llama al método IDTExtensibility2.OnConnection cada vez que se carga un complemento. Es el punto de entrada del complemento, por lo que se llamará al código que coloque en la OnConnection
función cuando se inicie el complemento. En el ejemplo siguiente, la OnConnection
función llama a la HrInitAddin
función .
Ejemplo de CMyAddin::OnConnection()
STDMETHODIMP CMyAddin::OnConnection(
IDispatch * Application,
ext_ConnectMode ConnectMode,
IDispatch * /*AddInInst*/,
SAFEARRAY * * /*custom*/)
{
Log(true,"OnConnection\n");
HRESULT hRes = S_OK;
m_spApp = Application;
m_ConnectMode = ConnectMode;
if (ConnectMode == ext_cm_AfterStartup)
hRes = HrInitAddin();
return hRes;
}
Inicializar la rutina del complemento
La HrInitAddin
función llama a las LoadLibraries
funciones , HrCacheProfileName
y HrAddMenuItems
para finalizar la configuración del complemento de estado sin conexión.
Ejemplo de CMyAddin::HrInitAddin()
HRESULT CMyAddin::HrInitAddin()
{
HRESULT hRes = S_OK;
LoadLibraries();
hRes = HrCacheProfileName();
Log(true,_T("HrCacheProfileName returned 0x%08X\n"),hRes);
hRes = HrAddMenuItems();
Log(true,_T("HrAddMenuItems returned 0x%08X\n"),hRes);
return hRes;
}
Rutina de bibliotecas de carga
La LoadLibraries
función carga los archivos de biblioteca de vínculos dinámicos (DLL) que requiere el complemento.
Ejemplo de LoadLibraries()
void LoadLibraries()
{
Log(true,_T("LoadLibraries - loading exports from DLLs\n"));
HRESULT hRes = S_OK;
UINT uiRet = 0;
LONG lRet = 0;
BOOL bRet = true;
CHAR szSystemDir[MAX_PATH+1] = {0};
// Get the system directory path
// (mapistub.dll and mapi32.dll reside here)
uiRet = GetSystemDirectoryA(szSystemDir, MAX_PATH);
if (uiRet > 0)
{
CHAR szDLLPath[MAX_PATH+1] = {0};
hRes = StringCchPrintfA(szDLLPath, MAX_PATH+1, "%s\\%s",
szSystemDir, "mapistub.dll");
if (SUCCEEDED(hRes))
{
LPFGETCOMPONENTPATH pfnFGetComponentPath = NULL;
// Load mapistub.dll
hModMAPIStub = LoadLibraryA(szDLLPath);
if (hModMAPIStub)
{
// Get the address of FGetComponentPath from the mapistub
pfnFGetComponentPath = (LPFGETCOMPONENTPATH)GetProcAddress(
hModMAPIStub, "FGetComponentPath");
}
// If there is no address for FGetComponentPath yet
// try getting it from mapi32.dll
if (!pfnFGetComponentPath)
{
hRes = StringCchPrintfA(szDLLPath, MAX_PATH+1, "%s\\%s",
szSystemDir, "mapi32.dll");
if (SUCCEEDED(hRes))
{
// Load mapi32.dll
hModMAPI = LoadLibraryA(szDLLPath);
if (hModMAPI)
{
// Get the address of FGetComponentPath from mapi32
pfnFGetComponentPath = (LPFGETCOMPONENTPATH)GetProcAddress(
hModMAPI, "FGetComponentPath");
}
}
}
if (pfnFGetComponentPath)
{
LPSTR szAppLCID = NULL;
LPSTR szOfficeLCID = NULL;
HKEY hMicrosoftOutlook = NULL;
lRet = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
_T("Software\\Clients\\Mail\\Microsoft Outlook"),
NULL,
KEY_READ,
&hMicrosoftOutlook);
if (ERROR_SUCCESS == lRet && hMicrosoftOutlook)
{
HrGetRegMultiSZValueA(hMicrosoftOutlook, "MSIApplicationLCID", (LPVOID*) &szAppLCID);
HrGetRegMultiSZValueA(hMicrosoftOutlook, "MSIOfficeLCID", (LPVOID*) &szOfficeLCID);
}
if (szAppLCID)
{
bRet = pfnFGetComponentPath(
"{FF1D0740-D227-11D1-A4B0-006008AF820E}", szAppLCID, szDLLPath, MAX_PATH, true);
}
if ((!bRet || szDLLPath[0] == _T('\0')) && szOfficeLCID)
{
bRet = pfnFGetComponentPath(
"{FF1D0740-D227-11D1-A4B0-006008AF820E}", szOfficeLCID, szDLLPath, MAX_PATH, true);
}
if (!bRet || szDLLPath[0] == _T('\0'))
{
bRet = pfnFGetComponentPath(
"{FF1D0740-D227-11D1-A4B0-006008AF820E}", NULL, szDLLPath, MAX_PATH, true);
}
delete[] szOfficeLCID;
delete[] szAppLCID;
if (hMicrosoftOutlook) RegCloseKey(hMicrosoftOutlook);
}
hModMSMAPI = LoadLibrary(szDLLPath);
if (hModMSMAPI)
{
pfnHrOpenOfflineObj = (HROPENOFFLINEOBJ*) GetProcAddress(
hModMSMAPI,
"HrOpenOfflineObj@20");
pfnMAPIFreeBuffer = (LPMAPIFREEBUFFER) GetProcAddress(
hModMSMAPI,
"MAPIFreeBuffer");
}
}
}
}
Rutina nombre del perfil de caché
La HrCacheProfileName
función llama a la función IMAPISupport::OpenProfileSection para abrir una sección de perfil para la sesión actual y, a continuación, establece el perfil para los controladores de botones.
Ejemplo de CMyAddin::HrCacheProfileName()
HRESULT CMyAddin::HrCacheProfileName()
{
HRESULT hRes = S_OK;
_NameSpacePtr spSession = m_spApp->GetNamespace("MAPI");
IUnknown* lpMAPIObject = NULL;
LPMAPISESSION lpMAPISession = NULL;
// use the raw accessor
hRes = spSession->get_MAPIOBJECT(&lpMAPIObject);
if (SUCCEEDED(hRes) && lpMAPIObject)
{
hRes = lpMAPIObject->QueryInterface(IID_IMAPISession,(LPVOID*)&lpMAPISession);
}
if (SUCCEEDED(hRes) && lpMAPISession)
{
LPPROFSECT lpPSGlobal = NULL;
hRes = lpMAPISession->OpenProfileSection((LPMAPIUID)pbGlobalProfileSectionGuid, NULL, 0, &lpPSGlobal);
if (SUCCEEDED(hRes) && lpPSGlobal)
{
LPSPropValue lpProfileName = NULL;
// Asking for PR_PROFILE_NAME_W here - this might not work with earlier versions of Outlook
SPropTagArray staga = {1,PR_PROFILE_NAME_W};
ULONG cVal = 0;
hRes = lpPSGlobal->GetProps(&staga,0,&cVal,&lpProfileName);
if (SUCCEEDED(hRes) && 1 == cVal && lpProfileName && PR_PROFILE_NAME_W == lpProfileName->ulPropTag)
{
m_InitButtonHandler.SetProfile(lpProfileName->Value.lpszW);
m_GetStateButtonHandler.SetProfile(lpProfileName->Value.lpszW);
m_SetStateButtonHandler.SetProfile(lpProfileName->Value.lpszW);
}
if (pfnMAPIFreeBuffer) pfnMAPIFreeBuffer(lpProfileName);
}
if (lpPSGlobal) lpPSGlobal->Release();
}
if (lpMAPISession) lpMAPISession->Release();
return hRes;
}
Agregar rutina de elementos de menú
La HrAddMenuItems
función define las opciones de menú que aparecen en el menú Estado sin conexión que se crea cuando se carga el complemento en Outlook y, a continuación, llama a DispEventAdvise
para cada elemento de menú.
Ejemplo de CMyAddin::HrAddMenuItems()
HRESULT CMyAddin::HrAddMenuItems()
{
Log(true,"HrAddMenuItems\n");
HRESULT hRes = S_OK;
if (!m_fMenuItemsAdded)
{
try
{
_ExplorerPtr spExplorer = m_spApp->ActiveExplorer();
_CommandBarsPtr spCmdBars = spExplorer->__CommandBars;
CommandBarPtr spMainBar = spCmdBars->ActiveMenuBar;
CommandBarControlsPtr spMainCtrls = spMainBar->Controls;
try { m_spMyMenu = spMainCtrls->GetItem("Offline State"); } catch (_com_error) {}
if (m_spMyMenu == NULL)
{
m_spMyMenu = spMainCtrls->Add((long)msoControlPopup,vtMissing,vtMissing,vtMissing, true);
m_spMyMenu->Caption = "Offline State";
}
CommandBarControlsPtr spMyMenuCtrls = m_spMyMenu->Controls;
try { m_spInitButton = spMyMenuCtrls->GetItem("&Init Monitor"); } catch (_com_error) {}
if (m_spInitButton == NULL)
{
m_spInitButton = spMyMenuCtrls->Add((long)msoControlButton, vtMissing, vtMissing, vtMissing, true);
m_spInitButton->Caption = "&Init Monitor";
m_spInitButton->FaceId = MY_INIT_BUTTON;
}
try { m_spDeinitButton = spMyMenuCtrls->GetItem("&Deinit Monitor"); } catch (_com_error) {}
if (m_spDeinitButton == NULL)
{
m_spDeinitButton = spMyMenuCtrls->Add((long)msoControlButton, vtMissing, vtMissing, vtMissing, true);
m_spDeinitButton->Caption = "&Deinit Monitor";
m_spDeinitButton->FaceId = MY_DEINIT_BUTTON;
}
try { m_spGetStateButton = spMyMenuCtrls->GetItem("&GetCurrentState"); } catch (_com_error) {}
if (m_spGetStateButton == NULL)
{
m_spGetStateButton = spMyMenuCtrls->Add((long)msoControlButton, vtMissing, vtMissing, vtMissing, true);
m_spGetStateButton->Caption = "&GetCurrentState";
m_spGetStateButton->FaceId = MY_GETSTATE_BUTTON;
}
try { m_spSetStateButton = spMyMenuCtrls->GetItem("&SetCurrentState"); } catch (_com_error) {}
if (m_spSetStateButton == NULL)
{
m_spSetStateButton = spMyMenuCtrls->Add((long)msoControlButton, vtMissing, vtMissing, vtMissing, true);
m_spSetStateButton->Caption = "&SetCurrentState";
m_spSetStateButton->FaceId = MY_SETSTATE_BUTTON;
}
// Set up advise
_com_util::CheckError(m_InitButtonHandler.DispEventAdvise(m_spInitButton));
_com_util::CheckError(m_DeinitButtonHandler.DispEventAdvise(m_spDeinitButton));
_com_util::CheckError(m_GetStateButtonHandler.DispEventAdvise(m_spGetStateButton));
_com_util::CheckError(m_SetStateButtonHandler.DispEventAdvise(m_spSetStateButton));
}
catch (_com_error)
{
hRes = E_FAIL;
}
if (SUCCEEDED(hRes))
{
m_fMenuItemsAdded = true;
}
}
return hRes;
}
Vea también
- Información sobre la API de estado sin conexión
- Instalar el complemento de estado sin conexión de muestra
- Información sobre el complemento de estado sin conexión de muestra
- Supervisar los cambios de estado de conexión con un complemento de estado sin conexión
- Desconectar un complemento de estado sin conexión