VSTO add-in: Find Monitor where Outlook is displayed - c#

Good day everyone.
All my users have 2 monitors. I have a VSTO Outlook add-in which is basically a ribbon button and a form. If my ribbon button is clicked, I create and display a new form. I don't want my form to be displayed on the same monitor where outlook is displayed. I want to open it on the other monitor. This what I usually do in normal winforms apps:
Screen[] allScreens = Screen.AllScreens;
int i = allScreens.Count<Screen>();
if (i > 1)
{
foreach (Screen s in allScreens)
{
if (s.DeviceName != Screen.FromControl(this).DeviceName)
{
myForm.Location = s.WorkingArea.Location;
myForm.maximise = true;
myForm.Show();
}
}
}
else
{
this._outlookAuths.Show(this);
}
But there is no 'this' pointer when working in the Ribbon class. I tried to get the monitor in which the Ribbon button is shown, but it is not part of the normal winforms button class. Tried to get my form's parent, which should be MS Outlook but that returns null. Just as a sidenote, CentreParent property on my form is also not working, but CentreParent is kind of the opposite of what I want. Thanks in advance.

Use Screen.FromHandle instead. You can retrieve HWND of the Outlook windows by casting Explorer or Inspector OOM objects to the IOleWindow interface and calling IOleWindow.GetWindow.
Use Application.ActiveWindow / ActiveExplorer / ActiveInspector depending on your definition of "where Outlook is displayed".

Related

Is this a way to show a modeless dialog from a dockable pane using WPF?

I'm building a Revit plugin. It consists of a dockable pane that (among other elements) has a button. I want to open a new, separate window when a user clicks this button.
At the moment, i create a new Window, but i don't know if that's the right way to go, because now i see two Revit icons on a task bar. I do not have experience as Revit user, i'm new to Revit development, so i'm not sure if this should be the case (two icons) and as silly as it sounds, i do not have admin rights to install random addins and get a feeling of expected user experience.
I create a Window using the following code:
ParametersMissingValueWindow parametersMissingValueWindow = new ParametersMissingValueWindow();
parametersMissingValueWindow.Show();
Based on the understanding of a dockable pane that i have, i think i do not want to create another dockable pane, but just a simple modeless dialog. I wasn't able to find any examples using WPF. Hence, any information whether this is the way to go or help on how to achieve this is highly appreciated.
The Show method takes an optional parent window argument. Specify the Revit main window as the parent window, and your modeless dialogue will be recognised as belonging to the running Revit process. It is accessible from the MainWindowHandle property.
var MyWindow = new MyWindow();
HwndSource hwndSource = HwndSource.FromHwnd(UIApplication.MainWindowHandle);
Window wnd = hwndSource.RootVisual as Window;
if (wnd != null)
{
MyWindow.Owner = wnd;
//MyWindow.ShowInTaskbar = false;
MyWindow.Show();
}
It's not necessary to assign a value to ShowInTaskbar property, but it actually achieves what i wanted to do from the beginning (have only one program open in taskbar), so i left it as part of the solution, but commentted out.
Big thanks to Jeremy Tammik for pointing out the parent property.
You can use WPF to setup a window to use in revit.
MyWPF menu = new menu();
System.Windows.Window wind = new System.Windows.Window();
wind.ShowDialog(); //--> the window shows up and make stuff for revit
if you need the menu to be a dockable one check this source.
Perhaps is not up to date and you will need to adapt the code to the new api.

PowerPoint 2010 Custom TaskPane in multple windows

I am developing a custom task pane for Microsoft PowerPoint 2010. I need the task pane to be synchronized between multiple application windows/presentations. The task panes are displayed using a toggle button on the ribbon.
Since PowerPoint 2010 displays each presentation in a different document window (which is different from 2007), I need to create a task pane separately for each window and synchronize them. I have followed the Microsoft tutorial on how to create task panes for multiple application windows, and I am using the CustomTaskPaneCollection.Add(UserControl, String, Object) method to specify which application window the task pane should be associated with. In this case the Object is the PowerPoint.DocumentWindow that the task pane should be associated with.
For some reason all of my task panes are created in the active window and not the window that I assign. For example, if I open 3 PowerPoint presentations and then toggle the task pane, all three task panes will be added to the active window.
This is the code I am using to add the task panes when the toggle is pressed:
public void AddAllTaskPanes()
{
PowerPoint.DocumentWindows windows = Globals.ThisAddIn.Application.Windows;
if(windows.Count > 0)
{
for (int i=1; i<=windows.Count; i++){
PowerPoint.DocumentWindow window = windows[i];
customTaskPane = this.CustomTaskPanes.Add(new UserControl1(), "My User Control", window);
customTaskPane.Visible = true;
}
}
}
It seems that this should successfully add each task pane to its specified window, and I cannot figure out why all of the task panes are being associate with the active window instead. I have done a lot of research into this issue and have not been able to find a solution. The closest I have found was this question, however the answer corresponds to PowerPoint 2007 and not 2010 like the question references.
Any insight into why PowerPoint may be behaving this way would be greatly appreciated.
I went the way of creating the TaskPanes from the PresentationAfterOpen and PresentationAfterNew Events which produces the same behaviour.
A note about the PresentationAfterOpen event, if the document selected by the user is already open, the event is still fired so you need to check if the CustomTaskPane has already been created for that document before creating a new one.
A way to overcome this problem is to create a pointer to the associated DocumentWindow in your CustomPane and enumerate through the CustomTaskPaneCollection checking for the associated one.

C# & XAML Popup doesn't show in screenshot

I have many popups in a custom GUI application. These popups are window objects, not popup objects. The popups do not show up in a screenshot when using the Print Screen button on the keyboard. Instead, the disabled mainwindow below is all that shows in the screenshot. The popup never flickers or disappears, it just doesn't show in the screenshot.
WindowInstance.IsEnabled = true;
WindowInstance.Refresh();
DisplayPopUpWindow(WindowInstance);
The code in DisplayPopupWindow:
private void DisplayPopUpWindow(Window theWindow)
{
if (theWindow != null)
{
if (theWindow is MessagePopup)
{
// Only show one popup at a time (queue is handled elsewhere)
RemovePopUpsCommand.Execute(true, null);
}
ActiveWindow.IsEnabled = false; // main screen disabled
foreach (KeyValuePair<Window, int> aPopup in popUpWindows)
{
if ((aPopup.Key.IsVisible) && (aPopup.Key.Opacity == 1) && (aPopup.Key != theWindow))
{
// if window is a lower priority then disable it
if (aPopup.Value > displayPriority)
aPopup.Key.IsEnabled = false;
}
}
theWindow.Show();
theWindow.Opacity = 1;
}
}
Is there some property in the XAML that affects whether the window is visible for screenshots? This is a large issue as this also affects some remoting software we use in that popups do not display on the shared screen. Also affects our combobox implementation.
The "popups" are actually their own standalone windows. Some have instances created once during application startup and simply shown/hidden when needed, however, most are created on demand to be displayed. This problem affects both types.
The remoting software used is axeda access remote.
If I remember correctly I had the same problem and I think it was related to setting the popup windows parent to the main window that fixed it, I'd have to look at my code at home to confirm.
So make sure this is correctly set.
EDIT:
Try using this code when you create the Window object:
MainWindowVariable.Owner = Window.GetWindow(this)
You can read more here:
http://msdn.microsoft.com/en-us/library/system.windows.window.owner(v=vs.110).aspx

c# Excel - Display ribbon on exit

I'm using VSTO to design an application with an Excel interface. I want to hide the ribbon on startup (shouldn't be needed in the application) and re-display it on exit (if the user had it originally displayed), to avoid irritating people who use the application and want a ribbon the next time they open Excel.
I can hide the ribbon using essentially the following code in ThisWorkbook_Startup (from this question Excel 2007 Minimize the Ribbon programatically but Not the menu bar):
Office.CommandBars cbs = null;
cbs = Application.CommandBars;
foreach (Office.CommandBar commandBar in cbs)
{
if (commandBar.Name == "Ribbon")
{
this.Application.ActiveWindow.Activate();
Application.SendKeys("^{F1}", true);
}
}
However, the same code or similar variations from the previously referenced question do not seem to work when placed in either the ThisWorkbook_Shutdown or ThisWorkbook_BeforeClose methods. The code is hit but never seems to execute - the ribbon is never restored.
Is there another way to restore the ribbon on exit?
Thanks,
Andrew

Adding panel to Appointment/calendar item window in outlook

OBJECTIVE:
C# .Net VSTO2010
i need to add a panel to appointment/calendar item window in outlook.
AppointmentItem window means window which opens when we click an appointment or create new appointment in outlook.
I need to display to some details(appoitnmentitem related) in appointmentItem Window (i prefer to use panel).
Actually i am displaying some details (addin related details) in separate tab as form in appointment item window, i want to display those details in single window(appointmentitem window) of appointmentItem
Inspector :Represents the window in which an Outlook item is displayed.
but in Inspector there is no support for adding panel
I am able to add panel or custom task pane in outlook main window .but i am not able to do in appointmentitem window.
I am using .Net 4 framework ,visual studio 2010. This has to be done in a outlook Addin, addin is target for MS office outlook 2003,2007,2010(atleast it should support 2007and 2010).
adding panel to outlook main window can be done using window handle and window class , then using function in User32.dll. but same technique i am not able to use on appointmentitem window.( i am not able to get handle of appointment item window)
adding custom task pane to outlook main window can be done using some code but i didnt find functionality to do it on appointment item window.
looking for good help or suggestions
You Can Add the side panel through the Custom Task panes and New Inspector Event Handler.
Step 1:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
inspectors = this.Application.Inspectors;
inspectors.NewInspector +=
new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(NewInspectorHandler);
}
Step 2:
public void Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
{
Microsoft.Office.Tools.CustomTaskPane myCustomTaskPane;
if(Inspector.CurrentItem is Microsoft.Office.Interop.Outlook.AppointmentItem ) {
UserControl uc1 = MyUserControl();
myCustomTaskPane = getAddIn().CustomTaskPanes.Add(uc1, "MyPanel",Inspector);
myCustomTaskPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
myCustomTaskPane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
myCustomTaskPane.Visible = true;
}
//Additionally You can add a property change listener to the current Item here
}
This will show the Custom side panel in Appointment Item

Categories