Ton*_*ony 38 .net c# user-interface
我已经看到一些应用程序(可能不是.NET应用程序)在表单标题栏上的最小化按钮左侧有一个额外的按钮?我怎样才能在C#中实现这一目标?
Chr*_*lor 37
更新:添加了适用于Windows Vista和Windows 7的Aero的解决方案
窗口交互的非客户区域由一系列非客户端特定消息管理.例如,WM_NCPAINT消息被发送到窗口过程以绘制非客户区域.
我从来没有从.NET做过这个,但我怀疑你可以覆盖WndProc并处理WM_NC*消息来实现你想要的.
更新:因为我从未尝试过.NET,所以我花了几分钟时间,我想我会试一试.
在Windows 7上尝试这个,我发现如果我想操作系统来执行非客户区的基本渲染,我需要禁用窗口的主题.所以这是一个简短的测试.我使用GetWindowDC获取整个窗口的DC而不是GetDCEx,这只是因为我可以从内存中互操作并且没有查找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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句.我打电话DisableProcessWindowsGhosting
,如果应用程序花费太长时间来响应Windows消息,这将阻止操作系统绘制非客户区域.如果您不这样做,那么在某些情况下,边框将被渲染,但您的装饰品将不会显示.这取决于您的要求它是否适合您.
@TheCodeKing的评论提示,我想我会再看看这个.事实证明,这可以在完全记录的方式完成,同时支持Aero.但它不适合胆小的人.我不会在这里提供一个完整的解决方案,仍有一些问题可以解决,但它确实是基础.
此代码/解决方案基于Win32示例,该示例可在以下位置找到: http://msdn.microsoft.com/en-us/library/bb688195(VS.85).aspx
原则上,您需要做的是以下内容.
上面的步骤将为您提供一个带有标准玻璃框架的窗口,不包括系统菜单(窗口图标)和标题.最小化,最大化和关闭按钮仍将被绘制并将起作用.你无法做的是拖动或调整窗口大小,这是因为框架实际上并不存在,请记住客户区覆盖整个窗口,我们刚刚要求操作系统将框架绘制到客户区.
现在,您可以正常地在窗口上绘图,即使在框架的顶部也是如此.您甚至可以将控件放在标题区域中.
最后,允许DWM通过从您(在处理之前)调用DwmDefWindowProc来为您处理命中测试WndProc
.它返回一个布尔值,指示DWM是否为您处理了该消息.
简单的解决方案:
第 1 步:创建一个 Windows 窗体(这将是您的自定义标题栏)
-Set Form Border Style to None
-Add whatever controls you would like to this
-I will name this custom form "TitleBarButtons"
Run Code Online (Sandbox Code Playgroud)
步骤 2. 在要使用此自定义控件的表单中,添加
titleBarBtn = new TitleBarButtons();
titleBarBtn.Location = new Point(this.Location.X + 100, this.Location.Y+5);
titleBarBtn.Show();
titleBarBtn.Owner = this;
Run Code Online (Sandbox Code Playgroud)
对于你的构造函数......你可以弄乱偏移量,这正好适合我的应用程序的一个很好的位置
步骤 3. 将 Move 事件添加到主窗体中
private void Form14_Move(object sender, EventArgs e)
{
titleBarBtn.Location = new Point(this.Location.X + 100, this.Location.Y+5);
}
Run Code Online (Sandbox Code Playgroud)
如果您想更好地解释上述任何代码,请告诉我。
归档时间: |
|
查看次数: |
39345 次 |
最近记录: |