Changing a window's restore position using SetWindowPlacement doesn't work on every window

断了今生、忘了曾经 提交于 2019-12-02 01:35:03

问题


I'm using the SetWindowPlacement function to (1) maximize and (2) change the restore position of external windows on the desktop. But when I use this command on WinForm windows, it doesn't seem to set the restore location correctly. (The WinForm window I'm testing with is just a VS2008 WinForms application run without modification.) So, for example, if the window is in a restored state located at (0, 0) and I use SetWindowPlacement to maximize it and set its restore position to (100,100), then click the window's restore button, it will restore not to (100,100) but to (0,0). It actually seems like the window first restores to the location I set, THEN moves back to its last restore location prior to being manipulated programmatically. I'm confused as to why this would happen only on WinForm windows - every non-WinForm window I try this on restores correctly to the position I indicated with SetWindowPlacement.

I know that's not much to go on, but I was wondering if anyone here had any ideas about why this is happening. Thanks.


回答1:


Yes, this is by design. The Form class keeps track of the restore bounds itself, necessary so it can properly reposition the window after it was re-created. Windows Forms often recreates the window on-the-fly to implement property setters for properties that can only be specified by CreateWindowEx(). Like ShowInTaskbar.

The private RestoreWindowBoundsIfNecessary() method puts the window back, it will run when the window is restored. From what I can tell, the restore bounds are latched just before the window is minimized or maximized. If you want to modify the restore position while the window is min/maximized then you'll have to use MoveWindow to move it where you want it to go after restoring the window. Ought to produce some flicker.




回答2:


I was able to avoid any flicker just by setting the window's size and location in a later spin of the dispatcher. Then, as Hans so helpfully pointed out, RestoreWindowBoundsIfNecessary will use that size and location when restoring the window.

Form window = ...
window.StartPosition = FormStartPosition.Manual
window.WindowState = savedState;
if (window.WindowState == FormWindowState.Normal)
{
    window.Location = savedLocation;
    window.Size = savedSize;
}
else
{
    window.BeginInvoke((MethodInvoker)delegate 
    {
        window.Location = savedLocation;
        window.Size = savedSize;
});


来源:https://stackoverflow.com/questions/3126041/changing-a-windows-restore-position-using-setwindowplacement-doesnt-work-on-ev

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!