オフライン状態アドインの設定
適用対象: Outlook 2013 | Outlook 2016
オフライン状態アドインを実装するには、接続、初期化、およびその他のセットアップ関数を実装する必要があります。 このトピックでは、サンプル オフライン状態アドインのコード例を使用して、これらの接続、初期化、およびセットアップ関数について説明します。 サンプルのオフライン状態アドインは、オフライン状態 API を使用して Outlook にオフライン状態メニューを追加する COM アドインです。 [オフライン状態] メニューを使用すると、状態の監視を有効または無効にしたり、現在の状態をチェックしたり、現在の状態を変更したりできます。 サンプルのオフライン状態アドインのダウンロードやインストールの詳細については、サンプルのオフライン状態アドインのインストールを参照してください。 オフライン状態 API の詳細については、オフライン状態 API についてを参照してください。
オフライン状態アドインを設定した後、接続状態の変更を監視および変更する関数を実装する必要があります。 詳細については、「 オフライン状態アドインを使用した接続状態の変更の監視」を参照してください。
接続ルーチン
IDTExtensibility2.OnConnection メソッドは、アドインが読み込まれるたびに呼び出されます。 これはアドインのエントリ ポイントであるため、関数に OnConnection
配置したコードはアドインの起動時に呼び出されます。 次の例では、 関数は OnConnection
関数を HrInitAddin
呼び出します。
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;
}
アドイン ルーチンを初期化する
関数はHrInitAddin
、、HrCacheProfileName
、および HrAddMenuItems
関数をLoadLibraries
呼び出して、オフライン状態アドインの設定を完了します。
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;
}
ライブラリの読み込みルーチン
関数は LoadLibraries
、アドインに必要なダイナミック リンク ライブラリ (DLL) ファイルを読み込みます。
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");
}
}
}
}
キャッシュ プロファイル名ルーチン
関数は HrCacheProfileName
IMAPISupport::OpenProfileSection 関数を呼び出して現在のセッションのプロファイル セクションを開き、ボタン ハンドラーのプロファイルを設定します。
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;
}
メニュー項目の追加ルーチン
関数は HrAddMenuItems
、アドインが Outlook に読み込まれたときに作成される [オフライン状態 ] メニューの下に表示されるメニュー オプションを定義し、メニュー項目ごとにを呼び出 DispEventAdvise
します。
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;
}