Well, in OnStartupComplete I set up the NewExplorer event:
STDMETHODIMP CAddin::OnStartupComplete(LPSAFEARRAY* custom)
{
// Check internal state
if (m_pApplication == NULL)
return E_FAIL;
. . .
hr = m_pApplication->get_Explorers(&m_pExplorers);
if (FAILED(hr) || m_pExplorers == NULL) {
char pBuf[256];
sprintf(pBuf, "Unable to add tool bar to window\n HRESULT %d\n
Location: 4", hr);
errorBox(pBuf);
}
else {
hr = IDispEventSimpleImpl<4, CAddin,
&__uuidof(Outlook::ExplorersEvents)>:
ispEventAdvise(static_cast<IDispatch*>(m_pExplorers),
&DIID_ExplorersEvents);
if (FAILED(hr)) {
char pBuf[256];
sprintf(pBuf, "Unable to add tool bar to window\n HRESULT %d\n
Location: 5", hr);
errorBox(pBuf);
}
else {
m_bReleaseExplorersEvents = true;
}
}
return S_OK;
}
The NewExplorer event creates a newToolBar, which wraps up the command
bar and event handling code:
void __stdcall CAddin::NewExplorer(IDispatch* _pdispExplorer)
{
// Add tool bar
addToolBar(new ToolBar(CComQIPtr<Outlook::_Explorer>(_pdispExplorer),
this));
}
The addToolBar function adds to thw list of toolbars:
HRESULT CAddin::addToolBar(ToolBar* _pToolBar)
{
// Check input
if (_pToolBar == NULL) {
errorBox("Unable to add tool bar to window\n Cause: Out of
memory\n Location: 1");
return E_FAIL;
}
const HRESULT hr = _pToolBar->getResult();
if (FAILED(hr)) {
delete _pToolBar;
return hr;
}
// Allocate list memory
void* const pBuffer = realloc(m_ppToolBars, (m_NumToolBars + 1) *
sizeof(ToolBar*));
if (pBuffer == NULL) {
delete _pToolBar;
errorBox("Unable to add tool bar to window\n Cause: Out of
memory\n Location: 2");
return E_FAIL;
}
// Add tool bar
m_ppToolBars = static_cast<ToolBar**>(pBuffer);
m_ppToolBars[m_NumToolBars++] = _pToolBar;
return S_OK;
}
Then the ToolBar constructor calls addToolBar to actually create the new
toolbar and button:
ToolBar::ToolBar(Outlook::_Explorer* _pExplorer, CAddin* _pParent)
{
if (_pExplorer == NULL) {
ATLASSERT(_pExplorer);
return;
}
m_Result = _pExplorer->get_CommandBars(&m_pCommandBars);
if (FAILED(m_Result) || m_pCommandBars == NULL) {
char pBuf[256];
sprintf(pBuf, "Unable to add tool bar to window\n HRESULT: %d\n
Location: 1", m_Result);
errorBox(pBuf);
return;
}
m_Result = addToolBar();
if (FAILED(m_Result) || m_pCommandBar == NULL) {
char pBuf[256];
sprintf(pBuf, "Unable to add tool bar to window\n HRESULT: %d\n
Location: 2", m_Result);
errorBox(pBuf);
return;
}
}
addToolBar is not important for this case, since it is failing at
get_CommandBars, before addToolBar even gets called.
Mark
Dmitry Streblechenko said:
So what is your code?
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
Well, here are a few of the HRESULTs that I have
gotten: -1733279739, -1594867707, -1456455675, -1318043643.
I'm not sure what you mean by checking if the toolbar already exists.
get_CommandBars is failing, so I can't check anything about the command
bars. The original toolbar was removed when the Explorer OnClose event
was received as Outlook was "closing".
Mark
What is the exact failing code? Do you check that the toolbar already
exists?
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
If Outlook doesn't close down completely (in my case, another add-in
is running that apparently doesn't release all of its resources
properly) and I "start" Outlook again, I get a NewExplorer event when
the main window pops up again. When I call Explorer::get_CommandBars
so I can add my command bar, it fails, with an HRESULT that appears
to be garbage, since it is different every time.
I haven't tested this behavior with a NewExplorer event under normal
circumstances, because I don't know how to make one happen under
normal circumstances.
The odd thing is that the add-in that is causing this problem doesn't
have any problem creating its own toolbar in this case.
Can anybody help with this?
Mark