首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Windows /7航空标题栏上绘制自定义按钮

在Windows /7航空标题栏上绘制自定义按钮
EN

Stack Overflow用户
提问于 2010-11-07 13:18:40
回答 3查看 8.5K关注 0票数 10

我在StackOverflow上发现了这个问题。基本上,用户希望在标题栏上绘制自定义按钮。

我尝试了这个代码,并意识到它只有在Aero被禁用时才能在vista/7中工作。我的问题是,在启用时,是否可以在标题栏上绘制自定义按钮?

此外,是否有任何方式从当前主题读取信息,以便我可以样式我的按钮,以匹配已经存在的。

更新

这是我的电脑屏幕截图,演示了上述概念。安装DisplayFusion后,我得到了附加的标题栏按钮。

我知道DisplayFusion是一个.NET程序,因为它是在.NET Reflector中打开的。不利的一面是程序被混淆了。不像我想要解压缩程序或任何东西;我只想在标题栏中添加一个按钮来做其他事情(例如,最小化到系统托盘)。

下面是截图,证明这个程序是一个.NET应用程序。

EN

回答 3

Stack Overflow用户

发布于 2011-01-13 21:24:58

只要您愿意重新绘制整个标题栏内容,那么您就可以使用DWM的DwmExtendFrameIntoClientArea方法,该方法包括将窗口设置为没有标题栏,允许DWM将其玻璃绘制到可用区域,以创建一个新的空间,该空间看起来类似于标题栏,但实际上位于您的客户区域,这样您就可以在其上绘制按钮。

这种方法的缺点是,如果你想要的话,你必须制作标准的按钮。最小化、最大化和关闭都不是重新创建的问题(虽然您会发现最大化按钮是基于状态的外观切换按钮),但是您可能会发现重新创建左上角按钮有问题。当然,你也必须重新画你的标题,但我无法想象你会对此有任何异议。

至于阅读当前主题的数据,以重新调整您的按钮作为他们的,我很抱歉,但我对此一无所知。我的建议是在标题栏上建立按钮时使用透明度,并使用半透明的发光效果,等等。这样你就可以保留玻璃背景,只需通过覆盖半透明的颜色来改变它的外观。而且,如果你这样做,那么玻璃上不断变化的高光会自然地移动,而如果你只是得到它们的主题颜色,你会发现要么你没有接触到它们的反射,要么它们在你的按钮空间内重新重新出现。当然,只有我的两分钱--如果你能找到一种方法来做你的主题色彩等等。

但是,有一个警告--还有另一个StackOverflow线程(http://stackoverflow.com/questions/2666979/net-framework-4-0-and-drawing-on-aero-glass-issue/4656182#4656182),它描述了DWM API DwmExtendFrameIntoClientArea方法的一个问题,所以如果我是您,在尝试这个解决方案之前,我会仔细阅读它。

票数 4
EN

Stack Overflow用户

发布于 2012-06-11 21:21:27

当我在我自己的多监视器解决方案中实现这一点时,我对此做了一些研究。DisplayFusion和TeamViewer实现这一点的方式是在包含按钮的所需窗口上覆盖自定义表单。您可以使用Spy++来确认这一点。

这是总的想法:

  1. 编写DLL挂钩,以便在创建、删除、激活、重新定位或调整窗口大小时得到通知。
  2. 使用透明键或使用此α-PNG和GDI+溶液创建透明表单,并通过自己绘制按钮来模拟该按钮。
  3. 在创建/删除窗口时,显示/隐藏所需窗口的标题按钮形式。
  4. 在窗口调整大小/重新定位消息时,重新对齐标题按钮窗体。
  5. 在激活窗口时,设置窗口的Z位置,使其位于所需窗口的顶部。

通过GetWindowSetWindowPos API获取和设置Z位置。

请注意,DLL必须用本机语言编写。但是,您可以使用这样的方法来解决这个问题:在C#中使用窗口消息实现全局系统挂钩

以下是我的研究结果:

票数 4
EN

Stack Overflow用户

发布于 2015-11-13 11:50:26

好的,系统挂钩是获取更改窗口位置信息的直接方法,透明形式的杰尔氏方案非常好。但您可以使用一种较小的侵入性方法,使用user32.dll获取桌面窗口上的信息。

代码语言:javascript
复制
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect);

该窗口处理您可以使用EnumDesktopWindows获得的

代码语言:javascript
复制
[DllImport("user32.dll", EntryPoint = "EnumDesktopWindows", 
ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam);

为此,您可以从线程把所有的应用程序都列出来获得一个示例。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4117874

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档