开发者

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

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 mod开发者_如何学Pythonification.) 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.


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.


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;
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜