Supervisión de los cambios de estado de conexión mediante un complemento de estado sin conexión
Hace referencia a: Outlook 2013 | Outlook 2016
Para poder usar un complemento de estado sin conexión para supervisar los cambios de estado de conexión, debe implementar funciones para configurar e inicializar el complemento. Para obtener más información, vea Configurar un complemento de estado sin conexión.
Después de configurar el complemento de estado sin conexión, debe usar la función HrOpenOfflineObj para obtener un objeto sin conexión. Con este objeto sin conexión, puede inicializar el monitor de estado y, a continuación, obtener y establecer el estado actual.
En este tema, estas funciones de supervisión de estado se muestran mediante ejemplos de código del complemento de estado sin conexión de ejemplo. El complemento de estado sin conexión de ejemplo 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.
Cuando el complemento de estado sin conexión está desconectado, deberá implementar funciones para finalizar correctamente y limpiar el complemento. Para obtener más información, vea Desconectar un complemento de estado sin conexión.
Abrir rutina de objetos sin conexión
Para que el cliente reciba una notificación cuando se produzca un cambio de estado de conexión, debe llamar a la función HrOpenOfflineObj . Esta función abre un objeto sin conexión que admite IMAPIOfflineMgr. La función HrOpenOfflineObj se define en el archivo de encabezado ConnectionState.h.
Nota:
La función HrOpenOfflineObj se declara en el archivo de encabezado ImportProcs.h como se indica a continuación: extern HROPENOFFLINEOBJ* pfnHrOpenOfflineObj;
.
Ejemplo de HrOpenOfflineObj
typedef HRESULT (STDMETHODCALLTYPE HROPENOFFLINEOBJ)(
ULONG ulFlags,
LPCWSTR pwszProfileName,
const GUID* pGUID,
const GUID* pInstance,
IMAPIOfflineMgr** ppOffline
);
Inicializar la rutina de monitor
La InitMonitor
función llama a la función HrOpenOfflineObj . La InitMonitor
función llama a CMyOfflineNotify para que Outlook pueda enviar notificaciones de devolución de llamada al cliente y registre la devolución de llamada a través de la variable AdviseInfo
MAPIOFFLINE_ADVISEINFO .
Ejemplo de InitMonitor()
void InitMonitor(LPCWSTR szProfile)
{
if (!szProfile) return;
Log(true,_T("Initializing Outlook Offline State Monitor\n"));
HRESULT hRes = S_OK;
if (g_lpOfflineMgr)
{
Log(true,_T("Already initialized\n"));
return;
}
if (pfnHrOpenOfflineObj)
{
if (g_lpOfflineMgr) DeInitMonitor();
Log(true,_T("Calling HrOpenOfflineObj for \"%ws\"\n"),szProfile);
hRes = pfnHrOpenOfflineObj(
NULL,
szProfile,
&GUID_GlobalState,
NULL,
&g_lpOfflineMgr);
if (FAILED(hRes))
{
Log(true,_T("HrOpenOfflineObj failed: 0x%08X\n"),hRes);
}
if (g_lpOfflineMgr)
{
IMAPIOffline* lpOffline = NULL;
hRes = g_lpOfflineMgr->QueryInterface(IID_IMAPIOffline,(LPVOID*)&lpOffline);
if (lpOffline)
{
ULONG ulCap = NULL;
hRes = lpOffline->GetCapabilities(&ulCap);
if (ulCap & MAPIOFFLINE_CAPABILITY_OFFLINE) Log(true,_T("MAPIOFFLINE_CAPABILITY_OFFLINE supported\n"));
if (ulCap & MAPIOFFLINE_CAPABILITY_ONLINE) Log(true,_T("MAPIOFFLINE_CAPABILITY_ONLINE supported\n"));
if (ulCap & (MAPIOFFLINE_CAPABILITY_OFFLINE | MAPIOFFLINE_CAPABILITY_ONLINE))
{
CMyOfflineNotify* lpImplNotify = new CMyOfflineNotify();
if (lpImplNotify)
{
MAPIOFFLINE_ADVISEINFO AdviseInfo = {0};
AdviseInfo.ulSize = sizeof(MAPIOFFLINE_ADVISEINFO);
AdviseInfo.ulClientToken = 0;// something you want to get handed back when you get the notification
AdviseInfo.CallbackType = MAPIOFFLINE_CALLBACK_TYPE_NOTIFY;
AdviseInfo.pCallback = lpImplNotify;
AdviseInfo.ulAdviseTypes = MAPIOFFLINE_ADVISE_TYPE_STATECHANGE;
AdviseInfo.ulStateMask = MAPIOFFLINE_STATE_ALL;
hRes = g_lpOfflineMgr->Advise(MAPIOFFLINE_ADVISE_DEFAULT, &AdviseInfo, &g_ulAdviseToken);
Log(true,"ulAdviseToken = 0x%08X\n",g_ulAdviseToken);
}
}
lpOffline->Release();
}
}
}
}
Obtener rutina de estado actual
La GetCurrentState
función llama a la función HrOpenOfflineObj y, a continuación, usa el objeto sin conexión para obtener el estado de conexión actual. El estado actual se devuelve en la ulCurState
variable , que se usa en la CButtonEventHandler::Click
función para mostrar el estado actual al usuario.
Ejemplo de GetCurrentState()
ULONG (LPCWSTR szProfile)
{
if (!szProfile) return 0;
Log(true,_T("Getting Current Offline State\n"));
HRESULT hRes = S_OK;
ULONG ulCurState = NULL;
if (pfnHrOpenOfflineObj)
{
if (g_lpOfflineMgr) DeInitMonitor();
Log(true,_T("Calling HrOpenOfflineObj for \"%ws\"\n"),szProfile);
hRes = pfnHrOpenOfflineObj(
NULL,
szProfile,
&GUID_GlobalState,
NULL,
&g_lpOfflineMgr);
if (FAILED(hRes))
{
Log(true,_T("HrOpenOfflineObj failed: 0x%08X\n"),hRes);
}
if (g_lpOfflineMgr)
{
IMAPIOffline* lpOffline = NULL;
hRes = g_lpOfflineMgr->QueryInterface(IID_IMAPIOffline,(LPVOID*)&lpOffline);
if (lpOffline)
{
hRes = lpOffline->GetCurrentState(&ulCurState);
Log(true,_T("GetCurrentState returned 0x%08X\n"),hRes);
switch(ulCurState)
{
case MAPIOFFLINE_STATE_ONLINE:
Log(true,_T("Current state is MAPIOFFLINE_STATE_ONLINE\n"));
break;
case MAPIOFFLINE_STATE_OFFLINE:
Log(true,_T("Current state is MAPIOFFLINE_STATE_OFFLINE\n"));
break;
default:
Log(true,_T("Current state is 0x%0X\n"),ulCurState);
}
lpOffline->Release();
}
}
}
return ulCurState;
}
Establecer la rutina de estado actual
La SetCurrentState
función llama a la función HrOpenOfflineObj y, a continuación, usa el objeto sin conexión para establecer el estado de conexión actual. La CButtonEventHandler::Click
función llama a la SetCurrentState
función y el nuevo estado se pasa a través de la ulState
variable .
Ejemplo de SetCurrentState()
HRESULT SetCurrentState(LPCWSTR szProfile, ULONG ulFlags, ULONG ulState)
{
if (!szProfile) return 0;
Log(true,_T("Setting Current Offline State\n"));
HRESULT hRes = S_OK;
if (pfnHrOpenOfflineObj)
{
if (g_lpOfflineMgr) DeInitMonitor();
Log(true,_T("Calling HrOpenOfflineObj for \"%ws\"\n"),szProfile);
hRes = pfnHrOpenOfflineObj(
NULL,
szProfile,
&GUID_GlobalState,
NULL,
&g_lpOfflineMgr);
if (FAILED(hRes))
{
Log(true,_T("HrOpenOfflineObj failed: 0x%08X\n"),hRes);
}
if (g_lpOfflineMgr)
{
IMAPIOffline* lpOffline = NULL;
hRes = g_lpOfflineMgr->QueryInterface(IID_IMAPIOffline,(LPVOID*)&lpOffline);
if (lpOffline)
{
switch(ulFlags)
{
case MAPIOFFLINE_FLAG_BLOCK:
Log(true,_T("Flag used: MAPIOFFLINE_FLAG_BLOCK\n"));
break;
case MAPIOFFLINE_FLAG_DEFAULT:
Log(true,_T("Flag used: MAPIOFFLINE_FLAG_DEFAULT\n"));
break;
default:
Log(true,_T("Flag used: 0x%0X\n"),ulFlags);
}
switch(ulState)
{
case MAPIOFFLINE_STATE_ONLINE:
Log(true,_T("New state will be MAPIOFFLINE_STATE_ONLINE\n"));
break;
case MAPIOFFLINE_STATE_OFFLINE:
Log(true,_T("New state will be MAPIOFFLINE_STATE_OFFLINE\n"));
break;
default:
Log(true,_T("New state will be 0x%0X\n"),ulState);
}
hRes = lpOffline->SetCurrentState(ulFlags, MAPIOFFLINE_STATE_OFFLINE_MASK,ulState,NULL);
Log(true,_T("SetCurrentState returned 0x%08X\n"),hRes);
lpOffline->Release();
}
}
}
return hRes;
}
Rutina de notificación
Outlook usa la función IMAPIOfflineNotify::Notify para enviar notificaciones a un cliente cuando hay cambios en el estado de conexión.
Ejemplo de CMyOfflineNotify::Notify()
void CMyOfflineNotify::Notify(const MAPIOFFLINE_NOTIFY *pNotifyInfo)
{
Log(true,_T("CMyOfflineNotify::Notify\n"));
if (pNotifyInfo == NULL)
{
Log(true,_T("pNotifyInfo is NULL\n"));
}
else
{
Log(true,_T("pNotifyInfo->ulSize == 0x%0X\n"),pNotifyInfo->ulSize);
switch(pNotifyInfo->NotifyType)
{
case MAPIOFFLINE_NOTIFY_TYPE_STATECHANGE:
Log(true,_T("pNotifyInfo->NotifyType == MAPIOFFLINE_NOTIFY_TYPE_STATECHANGE\n"));
break;
case MAPIOFFLINE_NOTIFY_TYPE_STATECHANGE_START:
Log(true,_T("pNotifyInfo->NotifyType == MAPIOFFLINE_NOTIFY_TYPE_STATECHANGE_START\n"));
break;
case MAPIOFFLINE_NOTIFY_TYPE_STATECHANGE_DONE:
Log(true,_T("pNotifyInfo->NotifyType == MAPIOFFLINE_NOTIFY_TYPE_STATECHANGE_DONE\n"));
break;
default:
Log(true,_T("pNotifyInfo->NotifyType == 0x%08X\n"),pNotifyInfo->NotifyType);
}
Log(true,_T("pNotifyInfo->ulClientToken == 0x%0X\n"),pNotifyInfo->ulClientToken);
switch(pNotifyInfo->Info.StateChange.ulMask)
{
case MAPIOFFLINE_STATE_OFFLINE_MASK:
Log(true,_T("pNotifyInfo->Info.StateChange.ulMask == MAPIOFFLINE_STATE_OFFLINE_MASK\n"));
break;
default:
Log(true,_T("pNotifyInfo->Info.StateChange.ulMask == 0x%0X\n"),pNotifyInfo->Info.StateChange.ulMask);
}
switch(pNotifyInfo->Info.StateChange.ulStateOld)
{
case MAPIOFFLINE_STATE_ONLINE:
Log(true,_T("pNotifyInfo->Info.StateChange.ulStateOld == MAPIOFFLINE_STATE_ONLINE\n"));
break;
case MAPIOFFLINE_STATE_OFFLINE:
Log(true,_T("pNotifyInfo->Info.StateChange.ulStateOld == MAPIOFFLINE_STATE_OFFLINE\n"));
break;
default:
Log(true,_T("pNotifyInfo->Info.StateChange.ulStateOld == 0x%0X\n"),pNotifyInfo->Info.StateChange.ulStateOld);
}
switch(pNotifyInfo->Info.StateChange.ulStateNew)
{
case MAPIOFFLINE_STATE_ONLINE:
Log(true,_T("pNotifyInfo->Info.StateChange.ulStateNew == MAPIOFFLINE_STATE_ONLINE\n"));
break;
case MAPIOFFLINE_STATE_OFFLINE:
Log(true,_T("pNotifyInfo->Info.StateChange.ulStateNew == MAPIOFFLINE_STATE_OFFLINE\n"));
break;
default:
Log(true,_T("pNotifyInfo->Info.StateChange.ulStateNew == 0x%0X\n"),pNotifyInfo->Info.StateChange.ulStateNew);
}
}
return;
}