Custom Task Pane Visible attribute never changes

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

Custom Task Pane Visible attribute never changes
 
nwein




Posts: 577
Joined: 2011-03-28
(This is about custom task pane, not ADX advanced task panes)

I'd like to verify that my findings are correct, as if they are it seems rather counter-intuitive.
following this http://www.add-in-express.com/creating-addins-blog/2012/03/06/custom-office-task-panes/#taskpane-adx to add a custom task pane; I'll use the variable names found in that guide.

I was trying to identify when the latter task pane (i.e. adxTaskPane1 User added an image) is being closed.
Hooking to the VisibleStateChange event of the task pane gets called when clicking the 'x' or Close button from the menu; however the Visible property of the task pane remains as True even when the task pane is closed (i.e. adxTaskPane1.Visible = true)
Based on http://msdn.microsoft.com/en-us/library/vstudio/bb608590(v=vs.100).aspx it seems like something is not working properly in ADX.
The only way to figure out if the task pane is visible or not is by casting the taskPaneInst object in the VisibleStateChange event to Microsoft.Office.Core.CustomTaskPane (as I've learnt http://www.add-in-express.com/forum/read.php?FID=5&TID=2812).
Why wouldn't adxTaskPane1 change its property as well? I understand adxTaskPane1 is an ADXTaskPane and not a Microsoft.Office.Core.CustomTaskPane but this is very confusing as it would seem that the VisibleStateChange will indicate the change in visibility to the actual ADXTaskPane...
Posted 17 Jul, 2013 14:46:09 Top
Andrei Smolin


Add-in Express team


Posts: 18830
Joined: 2006-05-11
Hello Nir,

Here's a citation from the manual:

From http://www.add-in-express.com/docs/net-office-custom-task-panes.php
In Add-in Express, you work with the task pane component and task pane instances. The TaskPanes collection of the add-in module contains task pane components of the AddinExpress.MSO.ADXTaskPane type. When you set, say, the height or dock position of the component, these properties apply to every task pane instance that the host application shows. To modify a property of a task pane instance, you should get the instance itself. This can be done through the Item property of the component (in C#, this property is the indexer for the ADXTaskPane class); the property accepts a window object (such as Outlook.Explorer, Outlook.Inspector, Word.Window, etc.) as a parameter and returns an AddinExpress.MSO.ADXTaskPane.ADXCustomTaskPaneInstance representing a task pane instance.


That is, the component is used to store "default" property values for task panes instances that Office creates. And it doesn't have to reflect the property value(s) of the task pane instance(s).

Hope this makes sense.


Andrei Smolin
Add-in Express Team Leader
Posted 18 Jul, 2013 11:28:33 Top
nwein




Posts: 577
Joined: 2011-03-28
Thanks for the reply Andrei, it doesn't seem, however, that ADX exposes the task pane instance anywhere, we have to get it from event arguments and such.
Another interesting phenomenas I've encountered are the following:

1. Setting the DockPositionRestrict doesn't prevent the custom task pane from docking into the restricted position unlike what's written in http://msdn.microsoft.com/en-us/library/microsoft.office.tools.customtaskpane.dockpositionrestrict(v=vs.100).aspx.
the description ADX provides for this property is:
Returns the initial dock restriction of a custom task pane (as set at design-time) or sets the dock position restriction of all task pane instances at run-time.


2. I'd like the custom task pane to be invisible initially (i.e. when opening a new Excel instance), setting the visible = false on the adxTaskPane1 (from the above sample) works fine.
However, if I subscribe to any of the ADXAddinModule OnTaskPaneXXX events the task pane will pop up every time Excel instance is loaded.
e.g.

this.OnTaskPaneBeforeCreate += new AddinExpress.MSO.ADXTaskPaneBeforeCreate_EventHandler(this.AddinModule_OnTaskPaneBeforeCreate);

private void AddinModule_OnTaskPaneBeforeCreate(object sender, ADXTaskPaneCreateEventArgs e)
{
      // we can leave this empty (or not) and it will still pop up everytime
}

Why just by subscribing to an event it changes the behaviour of the ADXTaskPane?
Posted 18 Jul, 2013 11:43:31 Top
Andrei Smolin


Add-in Express team


Posts: 18830
Joined: 2006-05-11
Hello Nir,

nwein writes:
it doesn't seem, however, that ADX exposes the task pane instance anywhere, we have to get it from event arguments and such.


Below is a code fragment from http://www.add-in-express.com/docs/net-office-custom-task-panes.php:

Private Sub RefreshTaskPane(ByVal ExplorerOrInspector As Object)   
   If Me.HostMajorVersion >= 12 Then  
      Dim TaskPaneInstance As _   
         AddinExpress.MSO.ADXTaskPane.ADXCustomTaskPaneInstance = _   
            AdxTaskPane1.Item(ExplorerOrInspector)   
      If Not TaskPaneInstance Is Nothing _   
         And TaskPaneInstance.Visible Then  
         Dim uc As UserControl1 = TaskPaneInstance.Control   
         If Not uc Is Nothing Then _   
           uc.InfoString = GetSubject(ExplorerOrInspector)   
      End If  
   End If  
End Sub 


In this method, you get the task pane instance which is shown in the specified Outlook window.

nwein writes:
1. Setting the DockPositionRestrict doesn't prevent the custom task pane from docking into the restricted position unlike what's written in MSDN.


I can't reproduce this in PowerPoint 2010 SP1 32 bit and PowerPoint 2013 32bit: I cannot dock my pane to the top/botton sides if I set this.adxTaskPane1.DockPositionRestrict = AddinExpress.MSO.ADXCTPDockPositionRestrict.ctpDockPositionRestrictNoHorizontal.

What Add-in Express build are you using?

nwein writes:
2. I'd like the custom task pane to be invisible initially


bool preventFromShowing = true;

private void AddinModule_OnTaskPaneBeforeShow(object sender, ADXTaskPaneShowEventArgs e) {
    AddinExpress.MSO.ADXTaskPane.ADXCustomTaskPaneInstance instance = e.Instance as AddinExpress.MSO.ADXTaskPane.ADXCustomTaskPaneInstance;
    PowerPoint.DocumentWindow window = instance.Window as PowerPoint.DocumentWindow;
    if (window.Caption.Contains("Presentation2") && preventFromShowing)
        e.Cancel = true;            
}

private void adxRibbonButton1_OnClick(object sender, IRibbonControl control, bool pressed) {
    preventFromShowing = !preventFromShowing;
    MessageBox.Show("preventFromShowing = " + preventFromShowing.ToString());
}

private void adxRibbonButton2_OnClick(object sender, IRibbonControl control, bool pressed) {
    PowerPoint.DocumentWindow window = PowerPointApp.ActiveWindow;
    if (window != null) {
        AddinExpress.MSO.ADXTaskPane.ADXCustomTaskPaneInstance instance = adxTaskPane1[window];
        if (instance != null) {
            instance.Visible = !instance.Visible;
            MessageBox.Show(instance.Visible.ToString());
        }
        Marshal.ReleaseComObject(window); window = null;
    }
}



Andrei Smolin
Add-in Express Team Leader
Posted 19 Jul, 2013 03:10:25 Top
nwein




Posts: 577
Joined: 2011-03-28
Andrei Smolin writes:
I can't reproduce this in PowerPoint 2010 SP1 32 bit and PowerPoint 2013 32bit: I cannot dock my pane to the top/botton sides if I set this.adxTaskPane1.DockPositionRestrict = AddinExpress.MSO.ADXCTPDockPositionRestrict.ctpDockPositionRestrictNoHorizontal.

What Add-in Express build are you using?

I'm using it in Excel 2010 32 bit with ADX 7.2.4055

As for point 2, I can see what you did there, that's adequate, however, I still don't understand why by just registering an event some functionality immediately changes...

Also, if I'm on the topic, it seems like Add-in Express's implementation of ctp is somewhat flawed and does not correlate to MSDN's guidelines (given that CTPs are Microsoft's technology I thought your implementation won't mess with it)
For example, http://msdn.microsoft.com/en-us/library/microsoft.office.tools.customtaskpane(v=vs.100).aspx gives this example for setting different width and height for the CTP when it's docked and when it floats (I have to admit I find it weird that their implementation uses the following lines:

myCustomTaskPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionFloating;
myCustomTaskPane.Height = 500;
myCustomTaskPane.Width = 500;

myCustomTaskPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
myCustomTaskPane.Width = 300;

Note that we can't change the height and width in the DockPositionChanged event).
I've also reviewed this detailed http://social.msdn.microsoft.com/Forums/vstudio/en-US/59771d12-dbe3-4315-8f58-babc3c91af87/cant-change-customtaskpane-width touching these issues, nothing seems to work on ADX though, that is I can't get this to work no matter what using ADX.
Posted 19 Jul, 2013 10:23:03 Top
Andrei Smolin


Add-in Express team


Posts: 18830
Joined: 2006-05-11
Hello Nir,

nwein writes:
As for point 2, I can see what you did there, that's adequate, however, I still don't understand why by just registering an event some functionality immediately changes...


The event handler actually prevents the pane from showing. Note however that Excel 2010 is an ADI application while PP2010-2013 and Excel 2013 are SDI applications.

A bit more code:

private void adxRibbonButton1_OnClick(object sender, IRibbonControl control, bool pressed) {
    adxTaskPane1.Width += (int)(adxTaskPane1.Width * 0.15);
}

private void adxRibbonButton2_OnClick(object sender, IRibbonControl control, bool pressed) {
    Excel.Window activeWindow = ExcelApp.ActiveWindow;
    if (activeWindow != null) {
        ADXTaskPane.ADXCustomTaskPaneInstance instance = adxTaskPane1[activeWindow];
        if (instance != null) {
            instance.Width += (int)(instance.Width * 0.15);
        }
    }
}

private void adxTaskPane1_DockPositionStateChange(object sender, object taskPaneInst) {
    Office._CustomTaskPane instance = taskPaneInst as Office._CustomTaskPane;                
    if (instance != null) {
        Office.MsoCTPDockPosition position = instance.DockPosition;
        System.Diagnostics.Debug.WriteLine("!!! instance.DockPosition=" + position.ToString());
    }
}



nwein writes:
Note that we can't change the height and width in the DockPositionChanged event).


I understand this so, that you need to change the height and width in this event. If so, you can do the following:

In the event handler for the DockPositionChanged event:
- do nothing for Excel 2007-2010) and get instance.Window.Hwnd in Excel 2013; a cast is required to get the Hwnd property or you can use late binding; store the hwnd;
- use ADXAddinModule.SendMessage() to send a custom message to the internal window which Add-in Express supports internally
- quit the event handler;

In the ADXAddinModule.OnSendMessage event, do the following:
a) in Excel 2007-2010: just modify ADXTaskPane.Width/ADXTaskPane.Height
b) in Excel 2013:
- get the Excel.Window object having the hwnd previously stored,
- get the task pane instance (ADXTaskPane.ADXCustomTaskPaneInstance) using the ADXTaskPane[Window] indexer,
- set ADXTaskPane.ADXCustomTaskPaneInstance.Width as required.


Andrei Smolin
Add-in Express Team Leader
Posted 22 Jul, 2013 09:31:02 Top