7

I need to perform several operations on a list of windows (minimize some of them, restore others) in order to switch between two or more set of windows at once.

The problem with this are those animations you can see when minimizing and restoring a window. The whole process look terrible with all those animations going in and out, up and down.
I cannot, however, disable those animations because this is for other computers and i dont want to change other people's settings, plus those animations are actually useful when you minimize/restore one window only (i.e. when YOU do it manually) because you can see what is happening, but for doing it programmatically on several windows at a time, it's not nice.

I'm currenlty using the SendMessage function to send the WM_SYSCOMMAND message with params SC_MINIMIZE/SC_RESTORE. I dont know whether there is another way.

So, the question:
How can I minimize/restore a window programatically without the animation effect??

PS: The programming language is not important. I can use any language that's nessesary for accomplishing this.

GetFree
  • 40,278
  • 18
  • 77
  • 104

3 Answers3

7

SetWindowPlacement with SW_SHOWMINIMIZED or SW_RESTORE as appropriate for showCmd in WINDOWPLACEMENT seems to bypass window animation. I'd keep an eye on the functionality for future versions of the OS though since documentation does not mention anything about animation.

TLama
  • 75,147
  • 17
  • 214
  • 392
Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
2

How about Hide > Minimize > Show ?

NGLN
  • 43,011
  • 8
  • 105
  • 200
  • 3
    I thought of that. Unfortunatelly that presents a different problem. When you hide a window, its taskbar button is removed from the taskbar. And then when you unhide it, its taskbar button is put back as the rightmost button in the taskbar. That means you leave a complete mess in the order of the taskbar buttons. – GetFree May 21 '11 at 14:13
2

You could temporarily disable the animations and then restore the user's original setting.

class WindowsAnimationSuppressor {
  public:
    WindowsAnimationSuppressor() : m_suppressed(false) {
      m_original_settings.cbSize = sizeof(m_original_settings);
      if (::SystemParametersInfo(SPI_GETANIMATION,
                                 sizeof(m_original_settings),
                                 &m_original_settings, 0)) {
        ANIMATIONINFO no_animation = { sizeof(no_animation), 0 };
        ::SystemParametersInfo(SPI_SETANIMATION,
                               sizeof(no_animation), &no_animation,
                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
        m_suppressed = true;
      }
    }

    ~WindowsAnimationSuppressor() {
      if (m_suppressed) {
        ::SystemParametersInfo(SPI_SETANIMATION,
                               sizeof(m_original_settings),
                               &m_original_settings,
                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
      }
    }

  private:
    bool m_suppressed;
    ANIMATIONINFO m_original_settings;
};

void RearrangeWindows() {
  WindowsAnimationSuppressor suppressor;

  // Rearrange the windows here ...
}

When the suppressor is constructed, it remembers the user's original setting and turns off the animation. The destructor restores the original settings. By using a c'tor/d'tor, you ensure that the user's settings are restored if your rearranging code throws an exception.

There is a small window of vulnerability here. In theory, the user could change the setting during the operation, and then you'll slam the original setting back. That's extremely rare and not really that bad.

Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175
  • Thanks for this. There are a couple of fixed I had to make, though. I tried to submit [an edit](http://stackoverflow.com/review/suggested-edits/7456370), but it was rejected (WTF?!). – Paul Mar 24 '15 at 20:51
  • @Paul: Your edits looked mostly fine to me. I'm not sure why they were rejected. I've gone ahead and redone them (in a slightly different style). – Adrian McCarthy Mar 24 '15 at 22:58
  • Cool, but you didn't fix the destructor. – Paul Mar 25 '15 at 17:22
  • [Don't use global state to manage a local problem](https://devblogs.microsoft.com/oldnewthing/20081211-00/?p=19873) (when possible) – user253751 Jul 15 '20 at 10:06
  • @user253751: I agree. You also shouldn't override user settings. This was intended as a hacky workaround. I used RAII to ensure the change is temporary and acknowledged the window of vulnerability. – Adrian McCarthy Jul 16 '20 at 14:48