Command Bar - Open New Window

J

Jack

I am trying to add a command bar to a new explorer window that is opened by
right clicking on the folder and selecting open in new window. I've
declared: Private WithEvents colExpl As Outlook.Explorers and have the code
to create a new command bar in the colExpl_NewExplorer event using:


Set tExpl = Explorer
Set oCommandBar = tExpl.CommandBars.Add(Name:=ShortAppName,
Position:=msoBarTop, Temporary:=True)
Set CBLogo = LoadCommandButton(oCommandBar, HelpFileName & " Help", 285, 3,
ShortAppName & " tasks", False, msoControlButton)
....

However, the oCommandBar always return nothing when I try to set it, I
assume since the explorer is not yet fully initialized.

Is there another way to do this?

Jack
 
K

Ken Slovak - [MVP - Outlook]

Wait for the Explorer.Activate event and create your UI there.
 
J

Jack

Ken, thanks for th tip that did add the toolbar to the new window.

I do however, have another issue. When I create the toolbar in the other
window (the toolbar is the same as the toolbar in the first window) I create
a new commandbar and control (using the same objects) it the initial toolbar
does not fire the events. Is there a way to use the same toolbar object to
load onto other windows so they all fire the same events?

Jack
 
K

Ken Slovak - [MVP - Outlook]

You need to set a unique Tag property for anything you create and make sure
that each window (Explorer or Inspector) retains scope while it is needed.
Most of us use collections of some kind with wrapper classes. We wrap the
Explorer or Inspector object in a class and add it to a collection to keep
it alive as needed. Then on Inspector or Explorer.Close we remove the item
from the collection and let it go out of scope or get garbage collected.

www.outlookcode.com has samples for .NET code for Explorer and Inspector
collections and wrappers, ItemsCB at www.microeye.com has an Explorer
wrapper example for VB6 and my Web site has an Inspector wrapper in VB6.
 
J

Jack

I have the explorer command bars loading into new windows with one
exception. The base toolbar has one msoControlButton and several
msoControlPopups. When the toolbar loads it loads the button and the popups
but none of the children of the popups.

I know there is something simple that I am missing, I just cannot see what
it is....

Jack
 
K

Ken Slovak - [MVP - Outlook]

I bet you're using CommandBarPopup.Controls.Add?

Try CommandBarPopup.CommandBar.Controls.Add.

If that's not it then show the code you're using for addin buttons to the
popups.
 
J

Jack

Never mind, I had added some code to clear the old toolbar and it was
causing the problem.

One (hopefully) final question. Is it possible to use a this process with a
toolbar that has temporary set to true?

The reason I ask is we still support OL2000, which does not always close
completely when you exit, and I would rather in that situation have the
command bar not load vs load and not function.

Jack
 
P

Peter Huang [MSFT]

Hi Jack,

I understand your scenario that you would like to control if the commandbar
will be loaded when outlook started up.

1. Based on my research, the Outlook is an singleton modal. That is to say,
if the previous Outlook did not exit, the new start on Outlook.exe will
only use the previous one.
2. If the previous Outlook exited abnormal, e.g. kill process, so the
commandbar may not be deleted correctly.
If this case, we can use FindControl method in startupcomplete to check if
the commandbar we are trying to add is already there. If there, we just
need to add event handle for it, if no, process the normal add commandbar
code.

Here is the code snippet for your reference.
try
{
CommandBarButton tcbb =(CommandBarButton
)wdApp.CommandBars.FindControl(oMissing,oMissing,"Test",oMissing);
if (tcbb != null)//if it has been created, we just add the event
handler
{
Debug.WriteLine("Add handler");
tcbb.Click+=new
_CommandBarButtonEvents_ClickEventHandler(cbb_Click);
}
else //If the commandbutton is not created before, then we create
it.
{
cb =
wdApp.CommandBars.Add("TestToolbar",oMissing,oMissing,false);
cb.Visible = true;
cb.Position = MsoBarPosition.msoBarFloating;
cb.Left = 0;
cb.Top = 0;
cbb =
(CommandBarButton)cb.Controls.Add(MsoControlType.msoControlButton,oMissing,-
o
Missing,oMissing,false);
cbb.Caption = "Test";
Debug.WriteLine(cbb.Id);
cbb.Tag = "Test";
cbb.Click+=new
_CommandBarButtonEvents_ClickEventHandler(cbb_Click);
}
}
catch(Exception ex)
{
Debug.WriteLine(ex.ToString());
}


Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jack

Peter,

I am was using the find control to reconnect the event handler with the
commandbar, however, it was not finding the buttons that were associated
with the popup and the popup would continue to grow (if it has 2 buttons on
the popup it would be 4 the next time, then 6 then 8 ,etc). The code that I
was using to find the control was:

Set ctlBtnAddin = objCommandBar.FindControl(Tag:=strTag)
where objCommandBar is the popup and strTag is the tag that was assigned to
the button. So what would happen is the ctlBtnAddin would return nothing
and a new button would be added.

To get around this what I am doing is first look for the command bar with
"Set cbrNewToolbar = gobjOutlook.ActiveExplorer.CommandBars(ShortAppName)"
and if it finds it I delete it and then recreate it.

This appears to work with the exception of one problem. The first time I
open Outlook and right click on a folder to open in a new window it creates
the toolbar, however, the toolbar only has the first level buttons (in my
case there is a button and several popup, but the popups do not have the
items under them). If I then close the window and reopen it the entire
toolbar is then displayed.

Also, back to the Outlook not completely exiting. With the toolbar as
"temporary=False" when Outlook restarts the command bar is there, and it
fires the event handler; however, since it did not fire InitHandler I do not
have a reference to the Outlook object (I set a global Outlook Object var in
inithandler). Is there something that fires in this situation that I can
use to set my global Outlook object?

Jack
 
K

Ken Slovak - [MVP - Outlook]

You should use Temporary = True with all the things you create where that's
available. You should also explicitly delete all your created UI on the
Explorer.Close and Inspector.Close events as a belt and suspenders approach.
That in addition to finding and deleting any existing items when you come to
create your UI will solve most of the problems.

You can also write your OnConnection and OnDisconnection code to handle both
cases where Explorers.Count = 0 AND Inspectors.Count = 0 (shutdown) and
where you set up class level Outlook event handling objects for Application,
Explorers and Inspectors to handle cases such as when synch software is
running and keeps Outlook running even after the user closes Outlook.
 
J

Jack

Ken,

The problem that I have when I set the command bar to Temporary = True is
that it no longer loads in secondary windows (right click-open in new
window). Is this expected, I see in the microeye example it has it as
Temporary = False?

Also, I am still not clear if there is a solution for when Outlook does not
completely close. Is there a way to re-init the commandbar in that
situation or is the approach to just make sure the toolbar gets destroyed
and does not load partially functional?

Jack
 
J

Jack

Okay, I think I found the solution for the situation where Outlook closes
but not complete. In the colExpl_NewExplorer procedure I added:

If gobjOutlook Is Nothing Then
Set gobjOutlook = Application
End If

I still have two things that I cannot figure out.
1) If I set the command bar to temporary=true they do not load on secondary
windows. Is this normal?
2) The first time I open a new Outlook window after restarting Outlook the
toolbar may load but only the first level items are there. In other words
any popup does not load the children. However, after closing that window
and opening it again (and every subsequent opening) it loads the toolbar
correctly.

Any ideas/comments are most appreciated.

Jack
 
K

Ken Slovak - [MVP - Outlook]

If you are properly implementing an Explorer wrapper class and collection
then your toolbars should be there in any Explorer. You always should verify
creation of your UI in both SelectionChange, BeforeFolderSwitch and Activate
to ensure it's there and populated no matter how an Explorer is opened and
what version of Outlook is running.

I haven't really looked at the ItemsCB code in many years, but I definitely
use Temporary = True in all my addin code, for all my Explorers and
Inspectors. The replacement code for ItemsCB we use now does set Temporary =
True.

Parenthetically, different versions of Outlook instantiate the Explorer to
different degrees in NewExplorer and fire the events I mentioned (or don't
fire them) in different orders. So fail safe code handles all those events.

The workaround you're now using in NewExplorer is similar to the new
replacement code that Dave Kane of MicroEye and I have been implementing as
a substitute for both ItemsCB and AddInMon.
 
J

Jack

Okay I thought I had it 100%, then I noticed this.
On one set of my command bars (only under one pop-up) the event gets fired
twice when I click it.

Ideas?

Jack
 
K

Ken Slovak - [MVP - Outlook]

Lack of a unique Tag property. If you have more than 1 control with the same
Tag property value any click event will fire in all existing controls that
share that Tag.
 
J

Jack

I do not understand how that can be the case, clearly I am missing
something....

I realized that every control fires twice, for example I put debug in the
click even of a button on the toobar and it stops there twice, this is true
for every control. Then I disconnect the COM Addin (tools-options...COM
Addins and uncheck it then go back in and recheck it) and the event fires 3
times. And, yes if I do it again it fires 4 times.

If I disconnect it and go to OutlookSpy it shows the the commandbar as no
longer there.

Confused.....
 
J

Jack

Okay here is what I found, can someone explain why it does this.

In the InitHandler for the addin class I add and gcolExplWrap.Add
objExplWrap, CStr(nID) to the collection of explorers. However, when I
uncheck the Addin in the COM Addis it does not actually disconnect it, it
still fires events. So on explorer_activate I was checking for the toolbar,
if it was not there I was adding it (This is when the COM Addin is checked
and unchecked remind you). So what was happening is when the COM Addin was
unchecked it was adding back the toolbar and the counter for the explorer
collection was 0. When the addin was re-enabled it would add a new explorer
(not counter =1) and add the toolbar, re-initializing the buttons. The way
I go around this was adding the following code:
If nID = 1 And gcolExplWrap.Count = 0 Then
gcolExplWrap.Add objExplWrap, CStr(nID)
End If

Does this make sense, I assumed that when I uncheck the add-in it stopped
processing events.
 
K

Ken Slovak - [MVP - Outlook]

I'm not sure what you're asking. If you have 2 buttons that share the exact
same Tag property then when one is clicked both click events will fire. The
only way around that is to have a unique Tag property for every button or
command bar object you create.

When you disconnect an addin, whether by closing Outlook or by unchecking
the addin in the COM addins dialog you should be deleting all of your
existing UI. That's in addition to declaring it as temporary when the UI is
created. In the case of Outlook closing you will need to release your
Outlook objects and destroy the UI when Explorer.Close fires. You also want
to be checking for Inspector.Close. When there are no Explorers or
Inspectors in those event handlers you release everything.

If OnDisconnect fires due to the user disconnecting the addin you also have
to release your Outlook objects and destroy your UI. If you do that
correctly you will not see these things.
 
K

Ken Slovak - [MVP - Outlook]

The addin will stop processing events if you disconnect it correctly. If you
get OnDisconnect and RemoveMode equals ext_dm_UserClosed then you know the
user disconnected the addin and you must release all of your Outlook objects
and destroy your UI. If you fail to do either you will still get events. If
the addin is re-connected your code should re-initialize the addin as if it
was a clean restart of Outlook.

If you don't destroy your UI and you've added a value to the OnAction
property of your UI items then when the "disconnected, orphan" button is
clicked your addin will re-initialize and your click event handler will be
called. To avoid that you destroy your UI. Don't depend on setting temporary
in those cases.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top