オフライン状態アドインを使用した接続状態の変更の監視
適用対象: Outlook 2013 | Outlook 2016
オフライン状態アドインを使用して接続状態の変更を監視する前に、アドインを設定して初期化する関数を実装する必要があります。 詳細については、「 オフライン状態アドインの設定」を参照してください。
オフライン状態アドインを設定した後、 HrOpenOfflineObj 関数を使用してオフライン オブジェクトを取得する必要があります。 このオフライン オブジェクトを使用すると、状態モニターを初期化し、現在の状態を取得して設定できます。
このトピックでは、サンプル オフライン状態アドインのコード例を使用して、これらの状態監視関数を示します。 サンプル オフライン状態アドインは、オフライン状態メニューを Outlook に追加し、 オフライン状態 API を利用する COM アドインです。 [オフライン状態] メニューを使用すると、状態の監視を有効または無効にしたり、現在の状態をチェックしたり、現在の状態を変更したりできます。 サンプルのオフライン状態アドインのダウンロードやインストールの詳細については、サンプルのオフライン状態アドインのインストールを参照してください。 オフライン状態 API の詳細については、オフライン状態 API についてを参照してください。
オフライン状態アドインが切断された場合は、アドインを適切に終了してクリーンアップするための関数を実装する必要があります。 詳細については、「 オフライン状態アドインの切断」を参照してください。
オフライン オブジェクト ルーチンを開く
接続状態の変更が発生したときにクライアントに通知するには、 HrOpenOfflineObj 関数を呼び出す必要があります。 この関数は、 IMAPIOfflineMgr をサポートするオフライン オブジェクトを開きます。 HrOpenOfflineObj 関数は、ConnectionState.h ヘッダー ファイルで定義されています。
注:
HrOpenOfflineObj 関数は、ImportProcs.h ヘッダー ファイルで 次のように宣言されます。 extern HROPENOFFLINEOBJ* pfnHrOpenOfflineObj;
HrOpenOfflineObj の例
typedef HRESULT (STDMETHODCALLTYPE HROPENOFFLINEOBJ)(
ULONG ulFlags,
LPCWSTR pwszProfileName,
const GUID* pGUID,
const GUID* pInstance,
IMAPIOfflineMgr** ppOffline
);
Monitor ルーチンを初期化する
関数は InitMonitor
HrOpenOfflineObj 関数を 呼び出します。 関数は InitMonitor
CMyOfflineNotify を呼び出して、Outlook がクライアントにコールバック通知を送信できるようにし、 MAPIOFFLINE_ADVISEINFO 変数 AdviseInfo
を介してコールバックを登録します。
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();
}
}
}
}
現在の状態ルーチンを取得する
関数は GetCurrentState
HrOpenOfflineObj 関数を呼び出し、オフライン オブジェクトを使用して現在の接続状態を取得します。 現在の状態は 変数で ulCurState
返されます。これは、関数で CButtonEventHandler::Click
現在の状態をユーザーに表示するために使用されます。
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;
}
現在の状態ルーチンを設定する
関数は SetCurrentState
HrOpenOfflineObj 関数を呼び出し、オフライン オブジェクトを使用して現在の接続状態を設定します。 関数は CButtonEventHandler::Click
関数を SetCurrentState
呼び出し、新しい状態は変数を ulState
介して渡されます。
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;
}
通知ルーチン
IMAPIOfflineNotify::Notify 関数は、接続状態に変更がある場合にクライアントに通知を送信するために Outlook によって使用されます。
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;
}