Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Window placement

Posted on 2016-08-08
17
Medium Priority
?
141 Views
Last Modified: 2016-08-15
I would like to use GetWindowPlacement and SetWindowPlacement to remember the last location of a window, and then always open it at that location when the app runs.   I can't seem to get it to work. Anyone ever done this?  

I want to use it to remember that an app was last opened maximized on the extended desktop monitor.
0
Comment
Question by:HLRosenberger
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 8
17 Comments
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 41747323
0
 
LVL 1

Author Comment

by:HLRosenberger
ID: 41747402
There seems to be an issue with any method if the window was maximized on the extended desktop when it was closed.   If it's not maximized, windows seems to remember it's position.
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 41747421
0
Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  

 
LVL 1

Author Comment

by:HLRosenberger
ID: 41749433
I have it working using GetWindowPlacement and SetWindowPlacement - almost.  It works under all conditions except - if the window is maximized on the extended desktop when I close it, the next time I run it starts maximized on the main desktop.    I've seen article about this maximized case, but I do not know how to solve it.   I have a simple single form app that I use the same code GetWindowPlacement/SetWindowPlacement code, and it works for the maximized case.  But my app has many forms - don't know why that would matter.
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 41749616
can you show your code? have you tried to use SetWindowPlacement before setting the WindowState to maximized just to ensure it is located on the correct monitor?
0
 
LVL 1

Author Comment

by:HLRosenberger
ID: 41750253
Not sure what you mean -   "Have you tried to use SetWindowPlacement before setting the WindowState to maximized just to ensure it is located on the correct monitor?"     I'm not setting the window to maximized in code.  

Here's code. I called SetWindowLocation in Form.Load, and SaveWindowLocation in form Closing

 Public Sub SaveWindowLocation()

        Dim wp As WINDOWPLACEMENT
        wp.length = Len(wp)

        GetWindowPlacement(_HWND, wp)

        My.Settings.Flags = wp.flags
        My.Settings.ShowCommand = wp.showCmd

        My.Settings.Top = wp.rcNormalPosition.Top_Renamed
        My.Settings.Bottom = wp.rcNormalPosition.Bottom_Renamed
        My.Settings.Left = wp.rcNormalPosition.Left_Renamed
        My.Settings.Right = wp.rcNormalPosition.Right_Renamed

        My.Settings.MinX = wp.ptMinPosition.X
        My.Settings.MinY = wp.ptMinPosition.Y

        My.Settings.MaxX = wp.ptMaxPosition.X
        My.Settings.MaxY = wp.ptMaxPosition.Y


        My.Settings.Initialized = True

        My.Settings.Save()

    End Sub


 Public Sub SetWindowLocation()

        Dim wp As WINDOWPLACEMENT

        wp.length = Len(wp)

        My.Settings.Reload()

        wp.flags = My.Settings.Flags
        wp.showCmd = My.Settings.ShowCommand

        wp.rcNormalPosition.Top_Renamed = My.Settings.Top
        wp.rcNormalPosition.Bottom_Renamed = My.Settings.Bottom
        wp.rcNormalPosition.Left_Renamed = My.Settings.Left
        wp.rcNormalPosition.Right_Renamed = My.Settings.Right

        wp.ptMinPosition.X = My.Settings.MinX
        wp.ptMinPosition.Y = My.Settings.MinY

        wp.ptMaxPosition.X = My.Settings.MaxX
        wp.ptMaxPosition.Y = My.Settings.MaxY


        SetWindowPlacement(_HWND, wp)

    End Sub
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 41750257
>> I'm not setting the window to maximized in code.

You need to persist the WindowState and when you load a form, if the persisted state is Maximized or Minimized, you need to set the WindowState to that value
0
 
LVL 1

Author Comment

by:HLRosenberger
ID: 41750319
ok, but the Window does open up maximized if I closed it when it was maximized.  The issue is that if the window maximized on the extended desktop monitor, then I close it (X-box), when I run again it starts on the main desktop monitor, not the extended.
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 41750325
>>when I run again it starts on the main desktop monitor, not the extended.

Have you set the position of your form to the second screen before setting it to Maximized?
0
 
LVL 1

Author Comment

by:HLRosenberger
ID: 41750385
I think we are talking apples and oranges.   I'm not setting the location of the window in code, except upon form load.    I save the  location in form closing.  

So, as a user I move the window to the extended monitor.  I then maximize it, and then I close it.  When I run again, I expect it to open maximized on the extended monitor. but it doesn't - instead it opens maximized on the standard desktop monitor.
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 41750418
I just think you understand my point. Before maximizing the form, ensure it is located with a normal state on the second monitor and then maximize it. If you just maximize (without placing it first on the second screen), it will, as you have experienced, maximize on the default/current screen.
0
 
LVL 1

Author Comment

by:HLRosenberger
ID: 41750465
But I am doing that - I move the window in a normal state, to the second monitor.  Then I maximize it.  Then I close it.   Then when I run again, it starts maximized on the first monitor.
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 41750491
>>Then when I run again, it starts maximized on the first monitor.

when you run it again, your code needs to move the form to the screen and then maximize it. I suspect that your code just maximize without moving the form first.

can you show your code?
0
 
LVL 1

Author Comment

by:HLRosenberger
ID: 41752175
How do I move it to the extended desktop?

I did come up with a work around - If the window is maximized, I trap the form closing, cancel it, make the window normal, then close.   I save a Boolean that indicates this situation.  Now when I start up, I maximize if necessary based on the save Boolean value.
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 41752253
>>How do I move it to the extended desktop?

By settings the Bounds or (top, left, ...) properties.

You just gave the idea for my monthly article (to be published on emoreau.com hopefully over the weekend)! The article will contain both VB and C#.

One important thing to notice on the closing event is that if the window state is not normal, it is the restore bounds that are persisted.

Here are the 2 important parts:

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);

            if (DesignMode) return;

            try
            {
                //Persist form's position and size
                if (WindowState == FormWindowState.Maximized || WindowState == FormWindowState.Minimized)
                {
                    cApp.Properties[FormSpecialName + ".WindowState"] = WindowState.ToString();
                    cApp.Properties[FormSpecialName + ".Bounds"] = RestoreBounds.ToString().Replace(",", ";");
                }
                else if (WindowState == FormWindowState.Normal)
                {
                    cApp.Properties[FormSpecialName + ".WindowState"] = WindowState.ToString();
                    cApp.Properties[FormSpecialName + ".Bounds"] = Bounds.ToString().Replace(",", ";");
                }
            }
            catch (Exception ex)
            {
                if (Debugger.IsAttached) Debugger.Break();
                cApp.LogError(ex);
                throw;
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (DesignMode) return;

            AutoScaleMode = AutoScaleMode.None;

            //Retreive form's position and size
            if (cSettings.GetProperty(FormSpecialName + ".WindowState").Trim().ToUpper() == "MAXIMIZED")
            {
                Bounds = cSettings.GetProperty(FormSpecialName + ".Bounds", new Rectangle(0, 0, Width, Height));
                WindowState = FormWindowState.Maximized;
            }
            else if (cSettings.GetProperty(FormSpecialName + ".WindowState").Trim().ToUpper() == "MINIMIZED")
            {
                if (FormSpecialName.Trim().ToUpper() != "FMAINMENU") WindowState = FormWindowState.Minimized;
            }
            else
                Bounds = cSettings.GetProperty(FormSpecialName + ".Bounds", new Rectangle(0, 0, Width, Height));

            EnsureFormIsVisible();
        }

Open in new window

0
 
LVL 70

Accepted Solution

by:
Éric Moreau earned 2000 total points
ID: 41755464
0
 
LVL 1

Author Closing Comment

by:HLRosenberger
ID: 41756240
Thanks for all your help!
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses

596 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question