一、需求背景
如何让一个窗口嵌入到桌面窗口中?如何同时隐藏/显示扩展屏下任务栏窗口?
二、问题点分析
- 窗口与窗口之间的关系;
- 扩展屏下任务栏窗口的窗口类是什么?超过一个扩展屏的任务栏窗口类又是什么?
三、窗口与窗口之间的关系
窗口类型主要分为:重叠窗口、弹出窗口、子窗口、分层窗口,只接受消息的窗口;
窗口之间的关系主要分为:前台窗口和后台窗口、所有者窗口和拥有者窗口、父窗口和子窗口;
通过窗口之间的关系可知,当前工作线程窗口为前台窗口,非前台窗口的为后台窗口;重叠窗口或弹出窗口可以被其他重叠窗口或弹出窗口所拥有,子窗口不存在所有者和拥有者窗口关系,一般拥有者窗口显示在所有者窗口z序列前。
子窗口显示在父窗口的客户区内,父窗口隐藏,子窗口也隐藏,父窗口销毁前,子窗口先销毁;子窗口显示前,父窗口先显示。微软为我们提供了一个API函数改变窗口的父子关系。
HWND SetParent( HWND hWndChild, //子窗口句柄 HWND hWndNewParent //新的父窗口句柄 如果为NULL,父窗口为桌面窗口 );
通过这个函数,我们可以更改制定窗口的父窗口为桌面窗口,就可以实现嵌入到桌面窗口内部,但是需要注意的是,如果桌面窗口销毁,嵌入到桌面的窗口会先被销毁掉,除非等到捉桌面窗口显示的时候再次嵌入,就可以保证同桌面窗口显示同步。
四、扩展屏下的任务栏窗口类名称
对于只有一台显示器的桌面窗口,任务栏窗口的类名称为:Shell_TrayWnd,通过::FindWindowW函数获取到该任务窗口的句柄,然后对其进程操作,但是如果有一个扩展屏,且需要同时操作两个任务栏呢?其实系统为扩展屏窗口的任务栏创建了一个新窗口,类名为:Shell_SecondaryTrayWnd,那么再新增一个扩展屏,系统会再创建一个任务栏窗口,类名为:Shell_ThirdTrayWnd吗?
理论认为是的,实际通过抓取两个扩展屏下任务栏窗口都是相同的,为:Shell_SecondaryTrayWnd。所以,我们在处理扩展屏任务栏时,不需要先判断是否存在扩展屏,直接通过FindWindowW函数获取任务栏窗口是否存在,如果Shell_SecondaryTrayWnd不存在,则可以认为只有主屏下的任务栏。然后对扩展屏下的任务同时进行显示/隐藏操作。
参考:https://docs.microsoft.com/zh-cn/windows/win32/winmsg/about-windows