Replace dial actions in Outlook 2016

Add-in Express™ Support Service
That's what is more important than anything else

Replace dial actions in Outlook 2016
 
Martin Schetat




Posts: 9
Joined: 2009-03-01
Hi,

I developed an add-in that replaces all dial actions in Outlook with our own actions since we don't have a TAPI Service Provider for our telephony solution.

The add-in uses a Ribbon command with idMso "Call" and two built-in controls with IDs 2501 and 32768. It works perfectly well with Outlook 2010 but now our customer is migrating to Outlook 2016 and only the Ribbon command keeps working as excepted.

User added an image

The direct phone number links have been ID 32768 while "New Call" had ID 2501.

Is there a way to replace these built-in commands in Outlook 2016?

Regards,

Martin Schetat
Posted 19 Dec, 2016 04:20:39 Top
Andrei Smolin


Add-in Express team


Posts: 14140
Joined: 2006-05-11
Hello Martin,

You have the issue because Outlook 2013-2016 (unlike Outlook 2010) doesn't support customizing context menus using CommandBar controls.

In the generic case, you can't replace controls existing on a Ribbon context menu; you can only disable them (but see below).

Here I describe my attempt to solve the task. Hopefully, it will give you some ideas on how to proceed.

Here's what I get:
1) hide the built-in Ribbon gallery IdMso="DialGallery"; this gallery lists Business, Mobile, etc. phone numbers - the gallery items stands for the command bar controls having Id=32768;
2) disable the built-in control IdMso="NewCall"; I suppose it stands for the Id=2501 in the command bar UI;
3) add a Ribbon split button IdMso="DialMenu" to the ContextMenuContactItem context menu and populate it with controls.

The controls I added to the split button's menu, they merge with the controls built in the Outlook UI as follows:
- in terms of the Ribbon XML, the built-in gallery "DialGallery" is disabled; in terms of visibility - it is hidden
- the built-in button "NewCall" is disabled; you can't hide it
- the controls I added are shown below the disabled button "NewCall"; I haven't tried to move the controls above (before) the button or the button below (after) the controls
- the buttons above the menu separator represent all potential phone numbers for a contact. This requires that you set these buttons' captions and visibility by handling the PropertyChanging event of the Ribbon split button IdMso="DialMenu", if this doesn't work, you would need to handle this property on the Ribbon Menu control that the split button contains. If this doesn't work as well, you would need to handle the PropertyChanging event of every button separately;
- the button below the menu separator represents the IdMso="NewCall" button. I assume that the functionality of the NewCall button isn't accessible through the Outlook object model. If so and if you need to invoke this functionality in your code, you would need to enable the button (set DXRibbonCommand.Enable=true on the corresponding Ribbon command component), wait for the Ribbon UI to reflect this change (see section Wait a little at https://www.add-in-express.com/docs/net-office-tips.php#wait-a-little), and call CommandBars.Execute("NewCall").

You will also need to use these ideas to customize the context menu "ContextMenuContactsMoreActions". It is displayed when you click the control "More" (see the Communicate group) in the Explorer and Inspector windows.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.adxRibbonCommand1 = new AddinExpress.MSO.ADXRibbonCommand(this.components);
            this.adxRibbonCommand2 = new AddinExpress.MSO.ADXRibbonCommand(this.components);
            this.adxRibbonContextMenu1 = new AddinExpress.MSO.ADXRibbonContextMenu(this.components);
            this.adxRibbonSplitButton1 = new AddinExpress.MSO.ADXRibbonSplitButton(this.components);
            this.adxRibbonMenu1 = new AddinExpress.MSO.ADXRibbonMenu(this.components);
            this.adxRibbonButton1 = new AddinExpress.MSO.ADXRibbonButton(this.components);
            this.adxRibbonMenuSeparator1 = new AddinExpress.MSO.ADXRibbonMenuSeparator(this.components);
            this.adxRibbonButton2 = new AddinExpress.MSO.ADXRibbonButton(this.components);
            this.adxRibbonButton3 = new AddinExpress.MSO.ADXRibbonButton(this.components);
            this.adxRibbonButton4 = new AddinExpress.MSO.ADXRibbonButton(this.components);
            this.adxRibbonButton5 = new AddinExpress.MSO.ADXRibbonButton(this.components);
            this.adxRibbonButton6 = new AddinExpress.MSO.ADXRibbonButton(this.components);
            this.adxRibbonButton7 = new AddinExpress.MSO.ADXRibbonButton(this.components);
            this.adxRibbonButton8 = new AddinExpress.MSO.ADXRibbonButton(this.components);
            this.adxRibbonButton9 = new AddinExpress.MSO.ADXRibbonButton(this.components);
            this.adxRibbonButton10 = new AddinExpress.MSO.ADXRibbonButton(this.components);
            // 
            // adxRibbonCommand1
            // 
            this.adxRibbonCommand1.ActionTarget = AddinExpress.MSO.ADXRibbonCommandTarget.NonActionControl;
            this.adxRibbonCommand1.Enabled = false;
            this.adxRibbonCommand1.Id = "adxRibbonCommand_ac06a8ecfb564c098f2f375571208082";
            this.adxRibbonCommand1.IdMso = "DialGallery";
            this.adxRibbonCommand1.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonCommand2
            // 
            this.adxRibbonCommand2.Enabled = false;
            this.adxRibbonCommand2.Id = "adxRibbonCommand_9a587e10d877477684fe4ba2f92bbf99";
            this.adxRibbonCommand2.IdMso = "NewCall";
            this.adxRibbonCommand2.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonContextMenu1
            // 
            this.adxRibbonContextMenu1.ContextMenuNames.AddRange(new string[] {
            "Outlook.Explorer.ContextMenuContactItem"});
            this.adxRibbonContextMenu1.Controls.Add(this.adxRibbonSplitButton1);
            this.adxRibbonContextMenu1.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonSplitButton1
            // 
            this.adxRibbonSplitButton1.Caption = "adxRibbonSplitButton1";
            this.adxRibbonSplitButton1.Controls.Add(this.adxRibbonMenu1);
            this.adxRibbonSplitButton1.Id = "adxRibbonSplitButton_ef9be1f50ef34941b02ce3b477321d9c";
            this.adxRibbonSplitButton1.IdMso = "DialMenu";
            this.adxRibbonSplitButton1.ImageMso = "Call";
            this.adxRibbonSplitButton1.ImageTransparentColor = System.Drawing.Color.Transparent;
            this.adxRibbonSplitButton1.InsertBeforeIdMso = "Call";
            this.adxRibbonSplitButton1.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonMenu1
            // 
            this.adxRibbonMenu1.Caption = "adxRibbonMenu1";
            this.adxRibbonMenu1.Controls.Add(this.adxRibbonButton1);
            this.adxRibbonMenu1.Controls.Add(this.adxRibbonButton2);
            this.adxRibbonMenu1.Controls.Add(this.adxRibbonButton3);
            this.adxRibbonMenu1.Controls.Add(this.adxRibbonButton4);
            this.adxRibbonMenu1.Controls.Add(this.adxRibbonButton5);
            this.adxRibbonMenu1.Controls.Add(this.adxRibbonButton6);
            this.adxRibbonMenu1.Controls.Add(this.adxRibbonButton7);
            this.adxRibbonMenu1.Controls.Add(this.adxRibbonButton8);
            this.adxRibbonMenu1.Controls.Add(this.adxRibbonButton9);
            this.adxRibbonMenu1.Controls.Add(this.adxRibbonMenuSeparator1);
            this.adxRibbonMenu1.Controls.Add(this.adxRibbonButton10);
            this.adxRibbonMenu1.Id = "adxRibbonMenu_541d0b1ce95d491aa74f0ec4d7320d32";
            this.adxRibbonMenu1.ImageTransparentColor = System.Drawing.Color.Transparent;
            this.adxRibbonMenu1.InsertBeforeIdMso = "NewCall";
            this.adxRibbonMenu1.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonButton1
            // 
            this.adxRibbonButton1.Caption = "adxRibbonButton1";
            this.adxRibbonButton1.Id = "adxRibbonButton_5776d02011ff4b759cc93633d54b4bbf";
            this.adxRibbonButton1.ImageTransparentColor = System.Drawing.Color.Transparent;
            this.adxRibbonButton1.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonMenuSeparator1
            // 
            this.adxRibbonMenuSeparator1.Id = "adxRibbonMenuSeparator_1ccd7422b19f4300a197be15fb896f42";
            this.adxRibbonMenuSeparator1.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonButton2
            // 
            this.adxRibbonButton2.Caption = "adxRibbonButton2";
            this.adxRibbonButton2.Id = "adxRibbonButton_fdf925ef51884fc0b0dc60b6c071c7d2";
            this.adxRibbonButton2.ImageTransparentColor = System.Drawing.Color.Transparent;
            this.adxRibbonButton2.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonButton3
            // 
            this.adxRibbonButton3.Caption = "adxRibbonButton3";
            this.adxRibbonButton3.Id = "adxRibbonButton_efd8ab44e549453b98fcc26e6dc4871c";
            this.adxRibbonButton3.ImageTransparentColor = System.Drawing.Color.Transparent;
            this.adxRibbonButton3.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonButton4
            // 
            this.adxRibbonButton4.Caption = "adxRibbonButton4";
            this.adxRibbonButton4.Id = "adxRibbonButton_d43021e469b64865b46835cd9f8da8d2";
            this.adxRibbonButton4.ImageTransparentColor = System.Drawing.Color.Transparent;
            this.adxRibbonButton4.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonButton5
            // 
            this.adxRibbonButton5.Caption = "adxRibbonButton5";
            this.adxRibbonButton5.Id = "adxRibbonButton_a0746b54f43845ad80d8cc806106e590";
            this.adxRibbonButton5.ImageTransparentColor = System.Drawing.Color.Transparent;
            this.adxRibbonButton5.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonButton6
            // 
            this.adxRibbonButton6.Caption = "adxRibbonButton6";
            this.adxRibbonButton6.Id = "adxRibbonButton_ac36f029e426480abf332a6152e8fd23";
            this.adxRibbonButton6.ImageTransparentColor = System.Drawing.Color.Transparent;
            this.adxRibbonButton6.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonButton7
            // 
            this.adxRibbonButton7.Caption = "adxRibbonButton7";
            this.adxRibbonButton7.Id = "adxRibbonButton_a6afac430f23418abb2c43bb497ba5ea";
            this.adxRibbonButton7.ImageTransparentColor = System.Drawing.Color.Transparent;
            this.adxRibbonButton7.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonButton8
            // 
            this.adxRibbonButton8.Caption = "adxRibbonButton8";
            this.adxRibbonButton8.Id = "adxRibbonButton_8e37d2331c194667b7215ccc21c0e785";
            this.adxRibbonButton8.ImageTransparentColor = System.Drawing.Color.Transparent;
            this.adxRibbonButton8.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonButton9
            // 
            this.adxRibbonButton9.Caption = "adxRibbonButton9";
            this.adxRibbonButton9.Id = "adxRibbonButton_c9fe14d59c884081a6c88e5f3687491d";
            this.adxRibbonButton9.ImageTransparentColor = System.Drawing.Color.Transparent;
            this.adxRibbonButton9.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // adxRibbonButton10
            // 
            this.adxRibbonButton10.Caption = "adxRibbonButton10";
            this.adxRibbonButton10.Id = "adxRibbonButton_dfab116ef5db418db86b0849958e3498";
            this.adxRibbonButton10.ImageMso = "NewCall";
            this.adxRibbonButton10.ImageTransparentColor = System.Drawing.Color.Transparent;
            this.adxRibbonButton10.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookExplorer;
            // 
            // AddinModule
            // 
            this.AddinName = "MyAddin217";
            this.SupportedApps = AddinExpress.MSO.ADXOfficeHostApp.ohaOutlook;

        }
...

        private AddinExpress.MSO.ADXRibbonCommand adxRibbonCommand1;
        private AddinExpress.MSO.ADXRibbonCommand adxRibbonCommand2;
        private AddinExpress.MSO.ADXRibbonContextMenu adxRibbonContextMenu1;
        private AddinExpress.MSO.ADXRibbonSplitButton adxRibbonSplitButton1;
        private AddinExpress.MSO.ADXRibbonMenu adxRibbonMenu1;
        private AddinExpress.MSO.ADXRibbonButton adxRibbonButton3;
        private AddinExpress.MSO.ADXRibbonButton adxRibbonButton1;
        private AddinExpress.MSO.ADXRibbonMenuSeparator adxRibbonMenuSeparator1;
        private AddinExpress.MSO.ADXRibbonButton adxRibbonButton2;
        private AddinExpress.MSO.ADXRibbonButton adxRibbonButton4;
        private AddinExpress.MSO.ADXRibbonButton adxRibbonButton5;
        private AddinExpress.MSO.ADXRibbonButton adxRibbonButton6;
        private AddinExpress.MSO.ADXRibbonButton adxRibbonButton7;
        private AddinExpress.MSO.ADXRibbonButton adxRibbonButton8;
        private AddinExpress.MSO.ADXRibbonButton adxRibbonButton9;
        private AddinExpress.MSO.ADXRibbonButton adxRibbonButton10;

Posted 19 Dec, 2016 07:43:04 Top
Martin Schetat




Posts: 9
Joined: 2009-03-01
Hi Andrei,

thank you for your quick response, I will try your solution and give you feedback.

So, if I understand correctly, the Delphi class TCustomBuiltInControl you sent me a few years ago is working under the hood with CommandBar controls, right?

Regards,

Martin Schetat
Posted 19 Dec, 2016 09:08:47 Top
Andrei Smolin


Add-in Express team


Posts: 14140
Joined: 2006-05-11
Oh, Martin, I've noticed that I published a .NET code to a Delphi forum. Please forgive me. If you wish I can create a Delphi variant of it.

Martin Schetat writes:
So, if I understand correctly, the Delphi class TCustomBuiltInControl you sent me a few years ago is working under the hood with CommandBar controls, right?


Exactly.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 19 Dec, 2016 10:08:32 Top
Martin Schetat




Posts: 9
Joined: 2009-03-01
Hi Andrei,

first of all, Happy New Year!

I integrated your code in my Delphi application, the built-in menus are hidden or disabled and I can add my own menus for the different phone numbers.

The main problem I have is when to populate the context menu, i.e. set the captions of the different ribbon buttons. I tried the PropertyChanging event of the split button but it is only fired once:

- Select a contact in the explorer
- Open the context menu -> The PropertyChanging event is fired.
- Select another contact
- Open the context menu -> The PropertyChaning event is not fired, the ribbon buttons still represent the phone numbers of the first selected contact.

I tried the PropertyChanging event of the context menu containing the split button, it is never fired. Any ideas?

Also, I tried to move the ribbon buttons in the context menu before "NewCall", doesn't seem to work.

Thank you and best regards,

Martin Schetat
Posted 04 Jan, 2017 07:32:32 Top
Dmitry Kostochko


Add-in Express team


Posts: 2731
Joined: 2004-04-05
Hi Martin,

Please try to use the OnOLExplorerSelectionChange event handler to populate/update your ribbon buttons.

Happy New Year!
Posted 04 Jan, 2017 08:40:03 Top
Martin Schetat




Posts: 9
Joined: 2009-03-01
Hi Dmitry,

thank you, works like a charm!

Now the last challenge is to place the ribbon buttons before the disabled "NewCall" command. Do you think this is possible?

Regards,

Martin
Posted 04 Jan, 2017 09:19:59 Top
Dmitry Kostochko


Add-in Express team


Posts: 2731
Joined: 2004-04-05
Hi Martin,

Thank you for the good news!

Now the last challenge is to place the ribbon buttons before the disabled "NewCall" command. Do you think this is possible?


Try to set the InsertBeforeIdMso property of your ribbon buttons to the 'NewCall' value.
Posted 04 Jan, 2017 10:42:38 Top
Martin Schetat




Posts: 9
Joined: 2009-03-01
Hi Dmitry,

that's what I already tried, doesn't work...

Regards,

Martin
Posted 04 Jan, 2017 11:16:15 Top
Dmitry Kostochko


Add-in Express team


Posts: 2731
Joined: 2004-04-05
Hi Martin,

Odd... As far as I can see, in the list of msoIds, 'NewCall' is the only one that can refer to that command.
Posted 05 Jan, 2017 06:08:50 Top