Excel是如何实现让子窗口显示在任务栏上的?
Excel在打开多个文件的时候,每一个MDIChildWnd都会有一个对应的任务栏按钮。刚开始我以为是SDI形式的程序,但是Excel上都有重新排列的选项,这样就可以让多个MDIChildWnd在同一个MainFrame中显示出来了。
这个问题困扰我很久,而且我也Google过多次但是都不能找到一个答案。
根据MSDN的说明:一个子窗口是不可能在任务栏上显示一个按钮的,但是为什么Excel就能做到这点呢?
在搜索的过程中我也想到了几种方案:
方案1:网上有一个例子MSDI,但是它的效果仅仅类似于MTI的效果,并不能把多个子窗口显示在同一个MainFrame中。
方案2:利用ITaskbarList。这个COM接口很是怪异,因为在一个程序中我只能用AddTab增加一个任务按钮,然后无论再怎么调用AddTab都不能多增加一个了。而且,我的试验机器的操作系统是Vista的,在Vista上面的表现就更怪异了。调用AddTab是完全没有任何反应的,只能调用ActivateTab才能将一个任务按钮显示出来。
方案3:利用Shell Hook,原理就是通过截获HSHELL_XXX来获取窗口建立、激活和销毁的消息,这主要是为了能防止一个窗口在任务栏上显示按钮的。但问题是,即使我拦截了这些消息MainFrame的任务按钮还是显示出来的。而ShellProc中完全获取不到子窗口创建和销毁的消息。
方案4:利用SendMessage想任务栏发送消息或者直接获取到任务栏(ToolBarWindow32)的句柄把它转换成指针直接增加一个按钮,但是前者会报告内存不能读的消息然后Explorer进程挂掉,而后者更甚直接把Explorer弄挂掉然后把我任务栏上的图标大小都改变了完全无法恢复。
方案5:利用SetParent或SetWindowLong方法设置子窗口的父窗口指针为空,这样子窗口就不算是一个子窗口了,然后也能在任务栏上显示出任务按钮来了。但是问题是,如果一个子窗口的父亲指针被设为空,整个程序基本都无法运行了,尤其是在MDI程序中基本上已启动就挂掉了。而且我也用Spy++检查过,Excel中的子窗口是有父亲指针的,不是一个独立的窗口。
经过反复的实验这几种方案都不能达到Excel的效果,当然关于Hook方面的东西我不大熟悉,也不敢下断言Hook这种方法一定不行。
所以今天想问问各位大虾,Excel到底是通过什么方法做到这点的?