我已经看到 RocketDock 在 Vista 中重定向最小化动画,因此窗口最小化到 Dock,我只是好奇这是如何完成的。实际的最小化动画是重定向到 Dock,还是类似于阻止 Windows 最小化窗口的钩子,并且 RocketDock 在窗口最小化时有自定义动画?
3 回答
我正在开发一个名为“OpenMMT”的开源多显示器任务栏项目。我最近发现(通过许多头痛)如何做到这一点。
以下说明假设您知道如何使用 RegisterShellHookWindow。
在将接收 shell 挂钩的窗口过程中,查找 HSHELL_GETMINRECT。
现在,从这里开始就是我遇到问题的地方。根据 MSDN,传递的 lparam 成员包含一个指向“SHELLHOOK”对象的指针。这是真的,但是,我无法让它工作,因为该结构的“rc”成员是一个与 Windows 头文件中的实际 RECT 结构不同的 RECT。头文件中的 RECT 使用 LONG 作为其成员,就像这里一样,我们想要 SHORT。
无论如何,这是我如何完成此任务的片段。
要定义的结构:
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;
然后在窗口程序上:
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;
}
当从我的应用程序中最小化程序时,我遇到了一些动画默认恢复为原始动画的情况。我通过像这样最小化它们来解决这个问题:
void MinimizeApp(HWND hWnd) {
SetForegroundWindow(hWnd);
ShowWindowAsync(hWnd, SW_MINIMIZE);
}
如果您想了解有关我的项目的更多信息,或者只想查看源代码,请随时访问https://github.com/Fafson/OpenMMT
该结构的ptMinPosition
成员WINDOWPLACEMENT
指定窗口最小化时的坐标,因此SetWindowPlacement
可以使用函数来实现该效果。但是一些测试表明窗口不应该有一个任务栏按钮来工作(即没有WS_EX_APPWINDOW
)。
我不知道 RocketDock 是如何工作的,但我想这可以通过安装全局WH_CBT
钩子并根据(设置 ex_style 然后设置最小化坐标)HCBT_MINMAX
通知来实现。
您可以使用 AnimateWindow API 函数,并将其传递给例如 AW_HOR_POSITIVE | AW_VER_POSITIVE 获得对角线动画。
我将从捕获 WM_SYSCOMMAND/SC_MINIMIZE 的全局钩子开始,然后使用 AnimateWindow 定位右上角。
如果这不能提供所需的效果,下一步是使用 WM_PRINT/WM_PRINTCLIENT 将窗口的副本复制到位图中(我相信这是 AnimateWindow 内部所做的),然后隐藏窗口并制作我自己的动画.