command bars in new explorer

  • Thread starter Thread starter Mark Smith
  • Start date Start date
M

Mark Smith

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
 
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
 
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)>::DispEventAdvise(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
 
Looking at my own code, I usually try to handle the toolbars in the
NewExplorer event. If that fails, I also use Explorer::Active event - by
that time the explorer is fully initialized and visible.

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool

Mark Smith said:
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)>::DispEventAdvise(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
 
That did the trick. Thanks for your help!

Mark

Dmitry Streblechenko said:
Looking at my own code, I usually try to handle the toolbars in the
NewExplorer event. If that fails, I also use Explorer::Active event - by
that time the explorer is fully initialized and visible.

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool

Mark Smith said:
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)>::DispEventAdvise(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
 
Back
Top