【问题标题】:Update (redraw) system-tray window after a button is removed [duplicate]删除按钮后更新(重绘)系统托盘窗口
【发布时间】:2019-04-16 08:42:44
【问题描述】:

在我发送TB_DELETEBUTTON 消息以删除系统托盘工具栏中的(外部应用程序的)按钮后,它仍然是该已删除按钮的空白/空矩形,并且工具栏不会删除此空矩形,直到我左键或右键单击其他图标,最后工具栏窗口被重绘,我删除的按钮中的空矩形消失了。

这是一个我想避免的审美问题。我只是想在发送 TB_DELETEBUTTON 消息后以编程方式更新/重绘工具栏窗口,但是在我调用 UpdateWindowUpdateLayeredWindowRedrawWindow 后,已删除按钮的空矩形仍然存在。

我尝试与 RedrawWindow 一起使用的标志组合是:RDW_FRAME、RDW_ALLCHILDREN、RDW_UPDATENOW 和 RDW_INVALIDATE。

我传递给这些函数的窗口句柄是具有类名的窗口:“ToolbarWindow32”(其上驻留应用程序的系统托盘按钮/图标),可以找到获取此窗口句柄的示例here.

我的问题是:如何正确更新/重绘此窗口?

【问题讨论】:

  • 使用 SendInput 将鼠标移到按钮上,shell 将删除它。至于“我怎样才能正确”,一旦你开始攻击另一个应用程序和系统实现细节,那艘船就启航了。没有合适的方法来做到这一点。
  • 请注意:您是否检查过您正在处理哪个系统升级通知区域?可能有两个。一,TrayNotifyWnd::SysPager 的孩子,是你想要的。 TrayNotifyWnd 的另一个直接子代不是。
  • @Jimi 与此问题中的“GetSystemTrayHandle”函数相同:stackoverflow.com/questions/5174120/… 这是我必须调用绘画的正确句柄吗?
  • 是的,就是这个。 GetSystemTrayHandle() 方法(在问题中)搜索SysPager 的孩子。 ToolbarWindow32 是正确的。但是,您将很难与 Shell 进行交互。这些接口不是公开的,AFAIK。

标签: c# .net vb.net winapi window


【解决方案1】:

调用InvalidateRect函数后我注意到通知区窗口被重绘了(因为窗口闪烁了一下),所以重绘窗口似乎不是解决这个问题的有效解决方案......

但是,在下一个帖子中我找到了解决方案:

问题是,为了“正确”刷新通知区域的大小以从以前删除的按钮中删除任何空白空间,我只需要通过SendMessage 函数发送WM_LBUTTONDOWNWM_LBUTTONUP 消息。

这些窗口消息必须按照以下顺序发送两次(至少对于 Windows 10)到 ToolbarWindow32 窗口:WM_LBUTTONDOWN、WM_LBUTTONUP、WM_LBUTTONDOWN、WM_LBUTTONUP。这是为了在系统托盘内的第一个按钮中重现两次单击(而不是双击),这是我在应用此自动化解决方案之前需要手动执行的操作。发送消息后,窗口会正确“自动调整大小”。

唯一的美学问题是,如果第一个按钮是来自应用程序的按钮,在单击其按钮时会执行一些不希望的操作,但这并不常见。通常,用户只能双击以从系统托盘上的按钮恢复窗口,或者右键单击以打开其上下文菜单,但单击按钮不会发生任何事情......如果开发人员没有编程任何事情发生。

请注意,当向上箭头包含“隐藏”按钮时,此方法也适用。

【讨论】:

    猜你喜欢
    • 2019-06-21
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多