gpt4 book ai didi

c# - 扩展另一个应用程序的标题栏

转载 作者:行者123 更新时间:2023-11-30 20:21:13 25 4
gpt4 key购买 nike

我正在开发一个开源 .NET clone (GitHub) DeskPins通过 Elias Fotinis (直接从 Google 云端硬盘下载)。它的主要功能是让其他窗口永远在最前面。当它们位于顶部时,标题栏中会添加一个图钉图标,如下所示:

enter image description here

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

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

研究

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

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

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

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

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

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

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

最佳答案

以下是我在 DeskPins 中完成此操作的方法。

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

DeskPins 使用 WS_POPUPWS_EX_TOPMOSTWS_EX_TOOLWINDOW 创建图钉,父窗口为 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 标志是否已更改并做出适当响应。

关于c# - 扩展另一个应用程序的标题栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34484429/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com