【问题标题】:Extend another application's title bar扩展另一个应用程序的标题栏
【发布时间】:2016-04-01 18:23:16
【问题描述】:

我正在开发 DeskPins 的开源 .NET clone (GitHub),作者为 Elias Fotinis(直接从 Google Drive 下载)。它的主要功能是使其他窗口始终处于顶部。当它们位于顶部时,会在标题栏中添加一个图钉图标,如下所示:

图钉图标在拖放过程中随窗口移动,看起来就像是窗口的一部分。它甚至响应单击事件,该事件始终取消顶部状态并从显示中删除图标。

问题。是否可以在 C# 中实现类似的东西(我假设是 p/invoke)?

研究

  1. 我试图运行这个项目。

这是一个 WPF 演示,它应该在标题栏上添加一个自定义控件。似乎不适用于 Windows 7 x64。不确定是操作系统还是其他。问题 - z 顺序不一致,标题栏也出现在其他窗口的顶部,并且它不随窗口移动,它会尝试,但会出现很多视觉伪影和闪烁。

  1. 尝试将此解决方案应用于#1:

基本上用这种模式替换对 SetWindowLong 的相关调用:

SetWindowLong(guestHandle, GWL_STYLE, GetWindowLong(guestHandle, GWL_STYLE) | WS_CHILD);
SetParent(guestHandle, hostHandle);

此更改破坏了一切,因此标题栏中没有添加任何内容。可能是它不适用于标题栏,仅适用于表单的用户区域。

无论如何,如果有简单的解决方案,请分享您的智慧。如果没有,我将不胜感激任何提示和/或链接,以进一步调查该主题。

【问题讨论】:

  • 这个问题可能就是你要找的。 stackoverflow.com/questions/2841180/…
  • @docflabby 另一个应用程序
  • deskpins 是如何做到的?
  • @DavidHeffernan:不知道,它是封闭源代码,可能是 C++。
  • 你不需要查看源代码来检查它是如何做到的。从 spy++ 开始。

标签: c# winforms pinvoke titlebar


【解决方案1】:

这是我在 DeskPins 中的做法。

每个图钉都是一个弹出窗口,带有自定义HRGN 定义其形状。我确实尝试过使用钩子将 DLL 注入进程并在标题上绘图,但当时这对我来说太麻烦了。

DeskPins 使用WS_POPUPWS_EX_TOPMOSTWS_EX_TOOLWINDOW 创建pin,0 作为父窗口。然后它立即向它发送一条消息(WM_PIN_ASSIGNWND),传递要固定的目标窗口和以毫秒为单位的轮询速率。之后,pin 独立于 DeskPins 运行,它们之间只发送信息消息。

pin 处理WM_PIN_ASSIGNWND 通过将目标窗口设置为其父窗口,使其位于最顶层并启动轮询计时器。设置它使用的父级:

SetWindowLong(hPin, GWL_HWNDPARENT, (LONG)hPinned);

请注意,Microsoft 警告不要像这样设置父级,而是建议使用SetParent()。但是,SetParent() 会进行一些内部处理,这会阻止它跨进程工作。使用SetWindowLong(GWL_HWNDPARENT) 本质上会欺骗窗口管理器来接受这一点。这有点像 hack,但是,嘿……它有效。

轮询计时器连续运行并测试目标窗口是否被破坏、隐藏、移动或其WS_EX_TOPMOST 标志是否已更改并做出适当响应。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 2016-07-17
  • 2015-12-01
  • 2017-11-18
相关资源
最近更新 更多