VSTO Outlook: How to uniquely identify custom task panes and remove the appropriate one from Globals.ThisAddIn.CustomTaskPanes collection - outlook

I have an VSTO Outlook Add-in. I have created a custom task pane that is always visible in all the windows at the top, explorer and inspector windows (compose window, etc.). This task pane is always the same, I mean, it has the same title/name, and also it embeds the exactly same user control.
Now I am facing a particular scenario and it is the following: When I open the inspector window (well the compose window), a new custom task pane which is always the same as the one in the explorer window, is added to the top of the compose window. Then when I close compose window I want to remove the custom task pane associated to this inspector (compose window), because otherwise where returning to the explorer window I get more than one custom task panes visible. So I am not able to detect which is the right task pane associated to the inspector opened in order to remove it from Globals.ThisAddIn.CustomTaskPanes using RemoveAt method. The problem I see is that it looks like every task pane added to the Globals.ThisAddIn.CustomTaskPanes collection is indentified through its name and the control that it embeds, but what happens when you have more than one task pane added to that collection with the same name/title and user control? There's no way to uniquely identify each of them.
I have a wrapper for inspector window, so I thought of handle the inspector open and close events and in the open event handler get the index of the custom task pane added to the Globals.ThisAddIn.CustomTaskPanes and then use that index to remove the correponding pane in the inspector close event.
Is this the correct way to do it? or is there any other better way to do it?

I ran into similar confusion while working on a Word addin. Office handles Word & Outlook customtaskpanes differently, so my solution won't map exactly to yours, but I do have a few suggestions:
Check out this section from official MS documentation:
To associate the task pane with a specific Explorer or Inspector, use the CustomTaskPaneCollection.Add method to create the task pane, and pass the Explorer or Inspector object to the window parameter.
I found the method signature you'll need here:
Add(UserControl, String, Object)
Creates a new CustomTaskPane and adds it to the current CustomTaskPaneCollection. The custom task pane is based on the specified UserControl, has the specified title, and is associated with the specified application window.
So to answer your question, MS seems to think this is the "correct" way to do it.
In my opinion, adding a field or property via a wrapper class makes perfect sense too. Especially if you already have it implemented & working properly.
Other suggestions based on my experience wrangling customtaskpanes:
Add an instance field/property to your usercontrol, obviating the need to wrap the customtaskpane class.
Create static class-level lists like List<< customtaskpane >> inspectorPanes in situations where you need to group or track them.
Hope this helps,

Related

Is it possible to modify the visual studio callstack window context menu in an extension?

I'm looking to write a plugin for Concord that would allow me to filter some frames on the callstack that are mostly just noise.
I am hoping it's possible to make it configurable by adding a checkable option to this context menu:
Is it possible to modify the visual studio callstack window context
menu in an extension?
I think you cannot get it so far.
If you want to add a button under menu of Call Stack Window, you should get its ID so that you can extend its menu and add any custom button.
But in Microsoft official document, Microsoft does not enumerate its GUID and ID value and they does not extend it to us.
However, Output window, Properties Window, Error List Window.....does.
So if you still want its value, you should suggest a feature request on User Voiceforum(suggest a feature) and they will consider your idea carefully and give you a satisfactory feedback.

events for right click detection in Outlook and Power point

In office applications i want to get the word on which the user right clicks.
i was able to get for Excel and Word. in outlook and PowerPoint i am not able detect the right click event.
In outlook i want to detect right click on a word in mail body.
In power point i want to detect right click in a slide content.
In outlook i have tried the events:
ItemContextMenuDisplay,
AttachmentContextMenuDisplay,
FolderContextMenuDisplay,
ContextMenuClose,
StoreContextMenuDisplay,
ViewContextMenuDisplay,
In power point i have tried:
WindowBeforeRightClick,
can somebody help me with the events to be used?
I will try to answer the Outlook part.
The Outlook object model doesn't provide any events for that. The only possible solution is to add your control to the context menu and handle the getVisible or getEnabled callbacks. Thus, you will be aware when the context menu is going to be displayed. But it seems MS doesn't provide the required IDs for that menu, see Extending the User Interface in Outlook 2010 for more information.
See Office 2013 Help Files: Office Fluent User Interface Control Identifiers
In the case of PowerPoint, WindowBeforeRightClick is the correct event.
You would find that setting Cancel = True in the handler for that event only works if the right-click is on the slide itself. On a shape or within a text range this fails to work as expected.
Workaround is the lock the screen and switch to a different view and back and then update the screen to prevent the contextual menu from appearing for the shape/text range.

How do I add a window from the resources as a child window?

I am creating a windows using win32:
HWND mainWnd = CreateWindow(...);
Now I can add gui elements as children of mainWnd. However this soon becomes a bit tedious and I want to use the designer built into Visual Studio to help me.
I noticed that under Add Resource there is a Dialog entry. Among the dialogs IDD_FORMVIEW seems the most general so I added one of these. Next I added gui elements to it using the designer.
Now I want to use this as a child of my mainWnd. How do I do this?
I found some examples using DialogBox, but I do not want a separate dialog, I want this window as a child of my mainWnd.
The designer in Visual Studio is appropriate for creating dialog boxes, not arbitrary windows.
That being said, there are a couple of approaches (in increasing order of difficulty):
Make your main window a dialog. Petzold's book has an example of using a dialog as the main window of the program. (If I recall correctly, it's the calculator example.)
Create the dialog and, before you show it, change its style to WS_CHILD, change its extended style to WS_EX_CONTROLPARENT, and parent it to your main window. For all the navigation stuff to work, you'll have to add IsDialogMessage calls in your message pump. This is do-able, but it's likely hard to get everything working well.
A mixture of 1 and 2 where you create one dialog for your main window, then create a second dialog for the content (with DS_CONTROL), and put the second dialog in the first. I've never tried this approach myself, but it seems like it should work.
Write your own code to parse the dialog resource and create the child windows, which is basically re-doing a lot of the work that CreateDialog does for you.
Given your desire to use the GUI to design the UI, I suspect only the first solution is simple enough that you would be interested.
Use the CreateDialog API to create the window from the resource. If you do not want it to look like a dialog then remove the titlebar style from the resource properties.
To use a dialog created from a dialog resource template you have to specify the DS_CONTROL window style in the template.
Read more about dialog boxes here.
Dialog resources are explained here

How to have a Word VSTO Custom Task Pane for more than one window?

I'm creating a Word Add-in which displays a custom task pane. This pane is then bound to the ribbon to be shown or hidden (simply by changing the visibile property).
After loading a first document, I can see the task pane. However, when I open a new document (which opens a new window), the visible toggle button keeps checking (and thus hiding/showing) the custom task panel associated with the first window.
How do i set the window property on the custom task pane to display it correctly. (Perhaps always show it in all windows?)
Apparantly I was doing it wrong, I expected to have one taskpane shared across all windows, but i needed a taskpane per window. So every document open/new I create one and associate it with the current window.

Is it wrong for a context (right click) menu be the only way a user can perform a certain task?

I'd like to know if it ever makes sense to provide some functionality in a piece of software that is only available to the user through a context (right click) menu. It seems that in most software I've worked with the right click menu is always used as a quick way to get to features that are otherwise available from other buttons or menus.
Below is a screen shot of the UI I'm developing. The tree view on the right shows the user's library of catalogs. Users can create new catalogs, or add and remove existing catalogs to and from their library. Catalogs in their library can then be opened or closed, or set to read-only.
The screen shot shows the context menu I've created for the browser. Some commands can be executed independently from any specific catalog (New, Add). Yet the other commands must be applied to a specifically selected catalog (Close, Open, Remove, ReadOnly, Refresh, Clean UP, Rename).
Currently the "Catalog" menu at the top of the window looks identical to this context menu. Yet I think this may be confusing to the users as the tree view which shows the currently selected catalog may not always be visible. The user may have switched to the Search or Filters tab, or the left pane may be hidden entirely.
However, I'm hesitant to change the UI so that the commands that depends on a specifically selected catalog are only available through the context menu.
The Windows User Experience Interaction Guidelines for Windows 7 and Windows Vista states (pg233):
“Don’t make commands only available through context menus. Like shortcut keys, context menus are alternative means of performing commands and choosing options.”
The Apple Human Interface Guidelines states (pg189):
“Always ensure that contextual menu items are also available as [pulldown] menu commands. A contextual menu is hidden by default and a user might not know it exists, so it should never be the only way to access a command.”
In your case, opening and closing the catalogue appears already available through the +/- buttons in the tree itself, so you’re already consistent with the Windows guidelines, if not the Apple guidelines. IMO, the only reason to put them on the context menu at all is if they're the default (double-click) action (which they're not right now). Rename may also already be available by directly selecting the name of a selected catalog, but you may want a pulldown menu item for that any way since that may be no more discoverable than the context menu. The rest of the commands probably belong on a pulldown menu in addition to the context menu.
As far as the Catalog pulldown menu being redundant with the Catalog context menu, you may want to consider organizing your pulldown menus by type of action, rather than class of object, in order to provide an alternative organization. As you’ve realized, context menus already organize commands by class of object. In addition to providing an alternative organization that some of you users may find more intuitive, this may simplify your menubar. For example, rather than a Catalog and Family menus, you can have a single Edit menu with Add, Delete, Rename, Copy, etc. where these commands apply to whatever is selected, whether it be a catalog, folder, or family. If they don't apply to the current selection, they're disabled, but if it makes any sense in your app, make them apply.
BTW, what’s the difference between Add Catalog and New Catalog?
In general, it's a bad idea to have menu items accessible only through a contextual menu. Many users may not think to right click on an item to find out what actions can be performed on an item.
From your description, it sounds like it would make sense to have a 'Catalog' menu that disables menu options that are not currently relevant. For example, if no catalog is open, the 'Close' menu item would be greyed out. Similarly, the 'Open', 'Remove', 'Refresh', etc. items would be greyed out if no catalog is selected.
I suppose this depends on your user base, and who you're targetting your software at. Personally I wouldn't expect the user to be able to deduce what functionality is available when it is essentially "hidden" until they right-click on the correct item.
If it were me, I'd have a toolbar shown with the functionality exposed on there. By default the buttons would be disabled, and clicking on a node would enable the appropriate buttons based on the context. You could have this in addition to your current right-click options.
As a rule, I've always treated right-click menus as a redundant (i.e not necessary for operation of the software) shortcut to functionality for "power users".
I would leave the menu item out because the user doesn't have a way to see what catalog they are modifying if the treeview is hidden which can create problems if they think a different one is being shown.
Though, the accessible solution would be to trigger it with the keyboard also.
Yes. One key feature of UI is "discoverability": can the user find the function?
If you think that having a top-level menu doesn't make sense, based on the context, then you could have a menu button (scroll down) labelled (e.g.) "Actions" at the top of the pane.

Resources