none
Is there any way to determine which of multiple screens Outlook is displayed on? RRS feed

  • Question

  • I am working on an Outlook Add-In and I have multiple display monitors. Sometimes I have Outlook displayed on display 1, sometimes on display 2. When I open a form from my Add-In, I want to be able to detect which display monitor Outlook is currently displayed on. This way, I can make sure that I am opening the form on the same screen as the one that Outlook is on.

    I am building this Add-In for Outlook 2010 using Visual Studio 2012.

    Wednesday, April 24, 2013 8:55 PM

Answers

  • Cast Outlook Explorer (or Inspector) to IOleWindow and call IOleWindow.GetWindows to get its HWND.

    You can then use Windows API (GetWindowRect etc.) to figure out the window position.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.4 is now available!



    Wednesday, April 24, 2013 9:05 PM
  • Hello again DamianD,

    I did finally settle on a solution that is similar to what you mentioned here. I basically placed my form in a location relative to the "ActiveExplorer" in Outlook. By doing this, I was able to calculate the location to open the form based on it's screen location and the ActiveExplorer location, and the save the resulting value for later recall. This forces the form to open where it was the last time it was opened, but always relative to the origin of the ActiveExplorer. This seems to have resolved my concerns about "losing" the form when a screen (monitor) is disconnected.

    The code is in Visual Basic and looks like this:

        Private Sub frmItemsForm_Load(sender As Object, e As System.EventArgs) Handles Me.Load
            Dim appLocation As New Drawing.Point(0, 0)
            appLocation.X = Globals.ThisAddIn.Application.ActiveExplorer.Left + My.Settings.FormItemsLocation.X
            appLocation.Y = Globals.ThisAddIn.Application.ActiveExplorer.Top + My.Settings.FormItemsLocation.Y
            Me.Location = appLocation
            UpdateItemList(lstView)
            UpdateDisplay(Me, lstView)
        End Sub
    
        Private Sub frmItemsForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
            Dim appLocation As New Drawing.Point(0, 0)
            appLocation.X = Me.Location.X - Globals.ThisAddIn.Application.ActiveExplorer.Left
            appLocation.Y = Me.Location.Y - Globals.ThisAddIn.Application.ActiveExplorer.Top
            My.Settings.FormItemsLocation = appLocation
            My.Settings.Save()
        End Sub

    FormItemsLocation.X and FormItemsLocation.Y are from a drawing point value I placed in the project's application settings named FormItemsLocation.

    UpdateItemList(lstView) and UpdateDisplay(Me, lstView) are methods in another class I wrote that simply recalculates and updates a list view in the form.

    Thank you all for your help.

    Now I have to figure it out all over again for re-writing the application using C# instead of Visual Basic.

    Friday, April 26, 2013 5:05 PM

All replies

  • Cast Outlook Explorer (or Inspector) to IOleWindow and call IOleWindow.GetWindows to get its HWND.

    You can then use Windows API (GetWindowRect etc.) to figure out the window position.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.4 is now available!



    Wednesday, April 24, 2013 9:05 PM
  • windows api is not needed, .net has support for this, http://msdn.microsoft.com/pl-pl/library/system.windows.forms.screen.aspx

    FromControl, FromPoint, etc.

    Thursday, April 25, 2013 4:08 AM
  • DamianD,

    Thank you for your response. It was helpful to some degree (as far as accessing the screen properties). However, what I'm struggling with is finding a way to identify the location (Top/Left) of the Outlook application program. I can then compare this information with the screen properties to position my form on the appropriate screen in the appropriate location. So basically, what I need it to identify the location of the overall Outlook application window relative to the screen.

    Thanks,

    Thursday, April 25, 2013 2:59 PM
  • So have you tried IOleWindow?

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.4 is now available!

    Thursday, April 25, 2013 3:10 PM
  • Hello Dmitry,

    Thank you for your responses. I did look into the IOleWindow::GetWindow() technique that you mentioned, but I was hoping to find an easier, more direct way without having to deal with interface classes, or adding additional complexity beyond my current level of knowledge. Perhaps as I become more familiar with Outlook and other Office customizations, I will be more comfortable with deeper techniques.

    Thanks again for your suggestion, but at this time, without specific examples and descriptions of the techniques, I am not comfortable with manipulating Windows Interface classes.

    Thursday, April 25, 2013 3:46 PM
  • IOleWindow is as easy as it gets.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.4 is now available!

    Thursday, April 25, 2013 4:35 PM
  • What exactly are you trying to accomplish? Winforms and WFE both have priperties to determine window location relative it its parent. Maybe use this appropach instead of manually counting pixels?
    Friday, April 26, 2013 4:11 AM
  • Hello again DamianD,

    I did finally settle on a solution that is similar to what you mentioned here. I basically placed my form in a location relative to the "ActiveExplorer" in Outlook. By doing this, I was able to calculate the location to open the form based on it's screen location and the ActiveExplorer location, and the save the resulting value for later recall. This forces the form to open where it was the last time it was opened, but always relative to the origin of the ActiveExplorer. This seems to have resolved my concerns about "losing" the form when a screen (monitor) is disconnected.

    The code is in Visual Basic and looks like this:

        Private Sub frmItemsForm_Load(sender As Object, e As System.EventArgs) Handles Me.Load
            Dim appLocation As New Drawing.Point(0, 0)
            appLocation.X = Globals.ThisAddIn.Application.ActiveExplorer.Left + My.Settings.FormItemsLocation.X
            appLocation.Y = Globals.ThisAddIn.Application.ActiveExplorer.Top + My.Settings.FormItemsLocation.Y
            Me.Location = appLocation
            UpdateItemList(lstView)
            UpdateDisplay(Me, lstView)
        End Sub
    
        Private Sub frmItemsForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
            Dim appLocation As New Drawing.Point(0, 0)
            appLocation.X = Me.Location.X - Globals.ThisAddIn.Application.ActiveExplorer.Left
            appLocation.Y = Me.Location.Y - Globals.ThisAddIn.Application.ActiveExplorer.Top
            My.Settings.FormItemsLocation = appLocation
            My.Settings.Save()
        End Sub

    FormItemsLocation.X and FormItemsLocation.Y are from a drawing point value I placed in the project's application settings named FormItemsLocation.

    UpdateItemList(lstView) and UpdateDisplay(Me, lstView) are methods in another class I wrote that simply recalculates and updates a list view in the form.

    Thank you all for your help.

    Now I have to figure it out all over again for re-writing the application using C# instead of Visual Basic.

    Friday, April 26, 2013 5:05 PM