Chris,
You should have no problem using ATL to display a dialog in Outlook. You
must be doing something wrong (feel free to post code). I build my addins
using ATL; but, love MFC for the dialogs (other than the options page site
where it is 100% easier to use ATL).
On another note, when using modal dialogs from the addin you WILL want to
make the parent window to the dialog the Outlook application itself or else
they can be hidden behind the Outlook application! To do this you want to
get the Outlook window:
try
{
CComQIPtr<Outlook::_Application> pOutlookApp(pApplication);
IDispatch* pDispatch = NULL;
if (pOutlookApp)
{
pOutlookApp->ActiveWindow(&pDispatch);
if (pDispatch)
{
IOleWindow* pOleWindow;
pDispatch->QueryInterface(IID_IOleWindow, (void **) &pOleWindow)
;
if (pOleWindow)
{
pOleWindow->GetWindow(&hwndParent);
pOleWindow->Release();
}
}
}
}
catch(...)
{
hwndParent = NULL;
}
if (!hwndParent)
hwndParent = ::GetDesktopWindow();
Now you can temporarialy attatch this to a CWnd (MFC) or CWindow (ATL)
object so it can be passed to you dialog constructor. Don't forget to
detatch it when you destruct. You could also use FromHandle instead.
Now what gets really complicated is if you want these dialogs to have the
XP Theme (if activated) you need to use an activation context since this is
actually an inprocess DLL. The manifest file in the resource will not work
(although the manifest file in the application root will; but, this is a
bad practice since it will effect all addins). I'll throw this in as a
bonus becuase I am sure there are many developers pulling their hair out
trying to get themeing working for the dialogs.
CActivationContext g_ActivationContext;
CActivationContext::CActivationContext()
{
m_hModule = NULL;
m_hActCtx = INVALID_HANDLE_VALUE;
m_ulActivationCookie = 0;
}
CActivationContext::~CActivationContext()
{
Close();
}
typedef HANDLE (WINAPI* CREATEACTCTX_PROC)(PCACTCTXA);
void CActivationContext::Open()
{
Close();
m_hModule = LoadLibrary("kernel32.dll");
char szPath[MAX_PATH] = "";
GetModuleFileName(NULL, szPath, MAX_PATH);
ACTCTX act = {0};
act.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
act.lpResourceName = MAKEINTRESOURCE(2);
if (INVALID_HANDLE_VALUE == m_hActCtx)
{
act.cbSize = sizeof(act);
act.lpSource = szPath;
CREATEACTCTX_PROC pProc = (CREATEACTCTX_PROC) GetProcAddress
(m_hModule, "CreateActCtxA");
if (pProc)
m_hActCtx = pProc(&act);
}
}
typedef VOID (WINAPI* RELEASEACTCTX_PROC)(HANDLE);
void CActivationContext::Close()
{
if (!m_hModule)
return;
Deactivate();
if (INVALID_HANDLE_VALUE != m_hActCtx)
{
RELEASEACTCTX_PROC pProc = (RELEASEACTCTX_PROC) GetProcAddress
(m_hModule, "ReleaseActCtx");
if (pProc)
pProc(m_hActCtx);
m_hActCtx = INVALID_HANDLE_VALUE;
}
FreeLibrary(m_hModule);
m_hModule = NULL;
}
typedef BOOL (WINAPI* ACTIVATEACTCTX_PROC)(HANDLE, ULONG_PTR*);
void CActivationContext::Activate()
{
if (0 == m_ulActivationCookie)
{
ACTIVATEACTCTX_PROC pProc = (ACTIVATEACTCTX_PROC) GetProcAddress
(m_hModule, "ActivateActCtx");
if (pProc)
pProc(m_hActCtx, &m_ulActivationCookie);
}
}
typedef BOOL (WINAPI* DEACTIVATEACTCTX_PROC)(DWORD, ULONG_PTR);
void CActivationContext:
eactivate()
{
if (0 != m_ulActivationCookie)
{
DEACTIVATEACTCTX_PROC pProc = (DEACTIVATEACTCTX_PROC) GetProcAddress
(m_hModule, "DeactivateActCtx");
if (pProc)
pProc(0, m_ulActivationCookie);
}
m_ulActivationCookie = 0;
}
Mark