栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何在窗口的标题栏中添加一个额外的按钮?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何在窗口的标题栏中添加一个额外的按钮?

更新 :添加了一个解决方案,该解决方案将与启用了Windows Vista和Windows 7的Aero一起使用


非航空解决方案

窗口交互的非客户区域由一系列非客户特定消息管理。例如,将WM_NCPAINT消息发送到窗口过程以绘制非客户区。

我从未从.NET做到这一点,但我怀疑您可以覆盖WndProc并处理WM_NC *消息以实现所需的功能。

更新:因为我从没有尝试过.NET,所以花了几分钟时间,我想我可以快速尝试一下。

在Windows
7上尝试此操作,我发现如果我想让OS进行非工作区的基础渲染,则需要禁用窗口主题。因此,这是一个简短的测试。我使用GetWindowDC而不是GetDCEx来获取整个窗口的DC,这仅仅是因为我可以从内存中互操作,并且没有查找GetDcEx的所有标志常量。当然,该代码可以执行更多错误检查。

using System;using System.Drawing;using System.Windows.Forms;using System.Runtime.InteropServices;namespace WindowsFormsApplication1{  public partial class CustomBorderForm : Form  {    const int WM_NCPAINT = 0x85;    [Dllimport("user32.dll", SetLastError = true)]    public static extern IntPtr GetWindowDC(IntPtr hwnd);    [Dllimport("user32.dll", SetLastError = true)]    public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);    [Dllimport("user32.dll", SetLastError = true)]    public static extern void DisableProcessWindowsGhosting();    [Dllimport("UxTheme.dll", SetLastError = true, CharSet = CharSet.Unipre)]    public static extern IntPtr SetWindowTheme(IntPtr hwnd, string pszSubAppName, string pszSubIdList);    public CustomBorderForm()    {      // This could be called from main.      DisableProcessWindowsGhosting();      InitializeComponent();    }    protected override void onHandleCreated(EventArgs e)    {      SetWindowTheme(this.Handle, "", "");      base.onHandleCreated(e);    }    protected override void WndProc(ref Message m)    {      base.WndProc(ref m);      switch (m.Msg)      {        case WM_NCPAINT:          { IntPtr hdc = GetWindowDC(m.HWnd); using (Graphics g = Graphics.FromHdc(hdc)) {   g.FillEllipse(Brushes.Red, new Rectangle((Width-20)/2, 8, 20, 20)); } int r = ReleaseDC(m.HWnd, hdc);          }          break;      }    }  }}

顺便说一句。我叫

DisableProcessWindowsGhosting
,如果应用程序响应Windows消息花费的时间太长,这将阻止OS绘制非客户区。如果您不这样做,则在某些情况下将渲染边框,但不会显示您的装饰。因此,这取决于您的要求,它是否适合您。


航空支持的解决方案

在@TheCodeKing的评论提示下,我想我会再来看一下。事实证明,可以在支持Aero的同时以完整记录的方式完成此操作。但这不是为了胆小的人。在这里,我将不提供完整的解决方案,但仍有一些锻炼方法,但是它具有基本知识。

此代码/解决方案基于Win32示例,该示例可在以下位置找到: http://msdn.microsoft.com/zh-
cn/library/bb688195(VS.85).aspx

原则上,您需要执行以下操作。

  • 扩展窗口的工作区以覆盖框架。这是通过处理WM_NCCALCSIZE消息并返回0来完成的。这使非客户端区域的大小为0,因此客户端区域现在覆盖了整个窗口。
  • 使用DwmExtendframeIntoClientArea将frame扩展到工作区。这使操作系统可以在客户端区域上渲染框架。

以上步骤将为您提供带有标准玻璃框的窗口,但不包括系统菜单(“窗口”图标)和标题。最小化,最大化和关闭按钮仍将绘制并起作用。您将无法执行的操作是拖动或调整窗口大小,这是因为框架并不真正存在,请记住客户区域覆盖了整个窗口,我们只是要求操作系统将框架绘制到客户区域上。

现在,您可以像平常一样在窗口上绘制,甚至可以在框架顶部绘制。您甚至可以将控件放在字幕区域。

最后,通过从您的DwmDefWindowProc调用DWM

WndProc
(在处理它之前),为您处理命中测试。它返回一个布尔值,指示DWM是否为您处理了该消息。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/390702.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号