技法(但请少用):为非活动窗口绘制活动的标题栏

技法(但请少用):为非活动窗口绘制活动的标题栏

作者:BlogUpdater |  时间:2020-06-27 |  浏览:314 |  评论已关闭 条评论

你可能会问:“为什么会有人想这样做呢?”
这个绘制需求通常用于浮动式工具栏。(除此之外,我想不到还有任何其他理由会将一个非活动窗口的标题栏绘制成活动式的)

幸运的是,这个功能很容易实现。只需要在我们的WndProc窗口过程中添加如下的一行代码即可:

case WM_NCACTIVATE: if (wParam == FALSE) wParam = TRUE; break;

这就像是在说:”如果Windows希望我绘制一个非活动状态的标题栏,则我会反过来将标题栏绘制为活动式的。

WM_NCACTIVATE消息解析
当窗口的非客户区需要标明窗口的活动状态时,Windows将向窗口发送这个消息。

第一个参数wParam
标明窗口的标题栏或者图标需要变更到的状态。
如果它为TRUE,则窗口的标题栏需要被绘制为活动式的。
如果它为FALSE,则窗口的标题栏需要被绘制为非活动式的。

第二个参数lParam
当一个可视化的风格(visual style)应用在这个窗口上时,这个参数不会被用到。
当没有任何可视化风格被应用到窗口时,这个参数是一个可选的非客户区更新区域的句柄。
如果这个参数被设置为-1,则默认的消息处理函数DefWindowProc将不会绘制非客户区来标明窗口的活动状态。

返回值
当wParam为FALSE的时候,应用程序应该返回TRUE表明这个消息由系统默认的消息处理函数进行处理,或者如果不希望系统做出修改的话,可以返回FALSE。
当wParam为TRUE时,消息的返回值将被忽略。

关于这个消息
一般来说,不推荐对窗口的非客户区消息进行自定义处理,因为如果真的打算这样做的话,应用程序必须绘制一个窗口的所有非客户区组件。如果应用程序处理了这个消息,则必须返回TRUE来请求系统完成所有这个消息的处理过程。如果窗口收到这个消息时已经处于最小化状态了,则应用程序应该将这个消息传递给默认的消息处理函数DefWindowProc。

当wParam为TRUE的时候,DefWindowProc将负责将窗口的标题栏或图标绘制为活动状态,否则将会将它们绘制为非活动状态。

总结
根据以上对WM_NCACTIVATE消息的解析,我们就能了解上面的一行魔术代码的意思了:现在收到了WM_NCACTIVATE消息,其WParam为FALSE,表明Windows希望将串口绘制为非活动状态,我们强行将wParam转为TRUE,并返回TRUE,这样这个消息还是会被默认消息处理函数处理,但是它发现wParam是TRUE,它就”无脑地”将标题栏绘制成了活动式的,尽管此时窗口此时是非活动状态。
一整套功夫下来,不由得感叹Windows开发的可定制性和开放性。

评论已关闭。