I have seen RocketDock redirect the minimize animation in Vista so windows minimize to the dock, and am just curious how this was done. Is the actual minimize animation redirected to the dock, or is something like a hook to stop Windows from minimizing the window and RocketDock has a custom animation when the window is minimized?
I am working on an open source multi-monitor taskbar project called "OpenMMT." I've recently discovered (through many headaches) how to accomplish this.
The following explanation assumes that you know how to go about using RegisterShellHookWindow.
On the window procedure that will receive the shell hooks, look for HSHELL_GETMINRECT.
Now, from here on out is where I had problems. According to MSDN, the lparam member passed contains a pointer to a "SHELLHOOK" object. Which is true, however, I could not get it to work for the simple fact that the "rc" member of that structure, is a RECT that differs from the actual RECT structure in the Windows header files. The RECT in the header files uses LONG for its members, were as on here, we want SHORT.
Anyways, here's a snippet on how I accomplished this.
Structures to define:
typedef struct {
SHORT left;
SHORT top;
SHORT right;
SHORT bottom;
} REALRECT, *LPREALRECT;
typedef struct {
HWND hWnd;
REALRECT rc;
} DOCUMENT_ME_RIGHT_MICROSOFT, *LPDOCUMENT_ME_RIGHT_MICROSOFT;
Then on the Window Procedure:
case HSHELL_GETMINRECT:
{
LPDOCUMENT_ME_RIGHT_MICROSOFT lpShellHook = (LPDOCUMENT_ME_RIGHT_MICROSOFT)lParam;
// lpShellHook now contains all the info. If you want to change the location
// of the animation, simply change the lpShellHook->rc members to point
// to the right coordinates and then return TRUE;
return TRUE;
}
When minimizing programs from my application I encountered some instances where the animation would default back to the original one. I resolved this by minimizing them like so:
void MinimizeApp(HWND hWnd) {
SetForegroundWindow(hWnd);
ShowWindowAsync(hWnd, SW_MINIMIZE);
}
If you want more info regarding my project or you just want to peek at the source, feel free to do so at https://github.com/Fafson/OpenMMT
The ptMinPosition
member of the WINDOWPLACEMENT
structure specifies the coordinates of the window when it is minimized, so SetWindowPlacement
function can be used to that effect. But some testing shows the window should not have a task bar button for that to work (i.e. no WS_EX_APPWINDOW
).
I don't know how RocketDock works, but I guess this could be achieved by installing a global WH_CBT
hook, and acting upon (setting the ex_style and then setting minimized coordinates) HCBT_MINMAX
notification.
You can use the AnimateWindow API function, and pass it e.g. AW_HOR_POSITIVE | AW_VER_POSITIVE to get a diagonal animation.
I'd start with a global hook catching WM_SYSCOMMAND/SC_MINIMIZE, and use AnimateWindow to target the top right corner.
If this doesn't provide the desired effect, the next step would be to use WM_PRINT/WM_PRINTCLIENT to get a copy of the window into a bitmap (I believe this is what AnimateWindow does internally), then hiding the window and doing my own animation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With