我已经看到某些应用程序(可能不是.NET应用程序)在表单标题栏上的“最小化”按钮左侧有一个额外的按钮吗?如何在C#中实现呢?
更新 :添加了一个解决方案,该解决方案将与启用了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.Unicode)] 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绘制非客户区。如果您不这样做,则在某些情况下将渲染边框,但不会显示您的装饰。因此,这取决于您的要求,它是否适合您。
DisableProcessWindowsGhosting
航空支持的解决方案
在@TheCodeKing的评论提示下,我想我会再来看一下。事实证明,可以在支持Aero的同时以完整记录的方式完成此操作。但这不是为了胆小的人。在这里,我将不提供完整的解决方案,但仍有一些锻炼方法,但是它具有基本知识。
此代码/解决方案基于Win32示例,该示例可在以下位置找到: http://msdn.microsoft.com/zh- cn/library/bb688195(VS.85).aspx
原则上,您需要执行以下操作。
以上步骤将为您提供带有标准玻璃框的窗口,但不包括系统菜单(“窗口”图标)和标题。最小化,最大化和关闭按钮仍将绘制并起作用。您将无法执行的操作是拖动或调整窗口大小,这是因为框架并不真正存在,请记住客户区域覆盖了整个窗口,我们只是要求操作系统将框架绘制到客户区域上。
现在,您可以像平常一样在窗口上绘制,甚至可以在框架顶部绘制。您甚至可以将控件放在字幕区域。
最后,通过从您的DwmDefWindowProc调用DWMWndProc(在处理它之前),为您处理命中测试。它返回一个布尔值,指示DWM是否为您处理了该消息。
WndProc