- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我(终于!)找到了一种在玻璃上呈现 Windows.Forms 控件的方法,它似乎没有任何重大缺点,也没有任何大的实现时间。它的灵感来自 this article来自 Coded,它基本上解释了如何 native 覆盖控件的绘制以在其上绘制。
我使用这种方法将控件呈现为位图,然后使用 GDI+ 和 NativeWindow 的绘画区域上的适当 alpha channel 将其绘制回来。实现很简单,但可以针对可用性进行完善,但这不是这个问题的重点。然而,结果非常令人满意:
但是,要使其真正可用,需要修复 2 个区域。
SetStyles(this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true)
将基本控件设置为双缓冲不起作用,但我怀疑我们可以通过一些试验和错误使其工作。<某些控件不起作用。我已经能够完成以下工作:
但我无法让这些工作,虽然我不明白为什么不。我有根据的猜测是,我引用整个控件的实际 NativeWindow 句柄,而我需要引用它的“输入”(文本)部分,可能是一个 child 。欢迎 WinAPI 专家就如何获取该输入窗口句柄提供任何帮助。
但修复双缓冲将是可用性的主要焦点。
这是一个示例用法:
new GlassControlRenderer(textBox1);
代码如下:
public class GlassControlRenderer : NativeWindow
{
private Control Control;
private Bitmap Bitmap;
private Graphics ControlGraphics;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0xF: // WM_PAINT
case 0x85: // WM_NCPAINT
case 0x100: // WM_KEYDOWN
case 0x200: // WM_MOUSEMOVE
case 0x201: // WM_LBUTTONDOWN
this.Control.Invalidate();
base.WndProc(ref m);
this.CustomPaint();
break;
default:
base.WndProc(ref m);
break;
}
}
public GlassControlRenderer(Control control)
{
this.Control = control;
this.Bitmap = new Bitmap(this.Control.Width, this.Control.Height);
this.ControlGraphics = Graphics.FromHwnd(this.Control.Handle);
this.AssignHandle(this.Control.Handle);
}
public void CustomPaint()
{
this.Control.DrawToBitmap(this.Bitmap, new Rectangle(0, 0, this.Control.Width, this.Control.Height));
this.ControlGraphics.DrawImageUnscaled(this.Bitmap, -1, -1); // -1, -1 for content controls (e.g. TextBox, ListBox)
}
}
我真的很乐意解决这个问题,并且一劳永逸有一种真正的在玻璃上呈现的方式,适用于所有 .NET 控件,无需 WPF。
编辑:双缓冲/防闪烁的可能路径:
this.Control.Invalidate()
会消除闪烁,但会中断文本框中的输入。 我已经尝试了 WM_SETREDRAW 方法和 SuspendLayout 方法,但没有成功:
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);
private const int WM_SETREDRAW = 11;
public static void SuspendDrawing(Control parent)
{
SendMessage(parent.Handle, WM_SETREDRAW, false, 0);
}
public static void ResumeDrawing(Control parent)
{
SendMessage(parent.Handle, WM_SETREDRAW, true, 0);
parent.Refresh();
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0xF: // WM_PAINT
case 0x85: // WM_NCPAINT
case 0x100: // WM_KEYDOWN
case 0x200: // WM_MOUSEMOVE
case 0x201: // WM_LBUTTONDOWN
//this.Control.Parent.SuspendLayout();
//GlassControlRenderer.SuspendDrawing(this.Control);
//this.Control.Invalidate();
base.WndProc(ref m);
this.CustomPaint();
//GlassControlRenderer.ResumeDrawing(this.Control);
//this.Control.Parent.ResumeLayout();
break;
default:
base.WndProc(ref m);
break;
}
}
最佳答案
这是一个闪烁更少的版本,但仍然不完美。
public class GlassControlRenderer : NativeWindow
{
private Control Control;
private Bitmap Bitmap;
private Graphics ControlGraphics;
private object Lock = new object();
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0x14: // WM_ERASEBKGND
this.CustomPaint();
break;
case 0x0F: // WM_PAINT
case 0x85: // WM_NCPAINT
case 0x100: // WM_KEYDOWN
case 0x101: // WM_KEYUP
case 0x102: // WM_CHAR
case 0x200: // WM_MOUSEMOVE
case 0x2A1: // WM_MOUSEHOVER
case 0x201: // WM_LBUTTONDOWN
case 0x202: // WM_LBUTTONUP
case 0x285: // WM_IME_SELECT
case 0x300: // WM_CUT
case 0x301: // WM_COPY
case 0x302: // WM_PASTE
case 0x303: // WM_CLEAR
case 0x304: // WM_UNDO
base.WndProc(ref m);
this.CustomPaint();
break;
default:
base.WndProc(ref m);
break;
}
}
private Point Offset { get; set; }
public GlassControlRenderer(Control control, int xOffset, int yOffset)
{
this.Offset = new Point(xOffset, yOffset);
this.Control = control;
this.Bitmap = new Bitmap(this.Control.Width, this.Control.Height);
this.ControlGraphics = Graphics.FromHwnd(this.Control.Handle);
this.AssignHandle(this.Control.Handle);
}
public void CustomPaint()
{
this.Control.DrawToBitmap(this.Bitmap, new Rectangle(0, 0, this.Control.Width, this.Control.Height));
this.ControlGraphics.DrawImageUnscaled(this.Bitmap, this.Offset); // -1, -1 for content controls (e.g. TextBox, ListBox)
}
}
关于c# - 玻璃 : Solution found, 上的渲染控件需要双缓冲/完善,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7061531/
昨天发布于: MySQL: Finding most frequently occuring values in table 但想知道是否有办法改进答案,因为您不必在最后重复代码来获取MAX(COUN
在开发了一个展示基本智能的简单算法后,我渴望进行递归 self 改进,我遇到的问题是由于我对递归缺乏理解。 我明白,如果我有一些东西来评估我正在使用的算法的“适应性”以进行改进(我为算法提供其自身的二
我们使用二进制 (16) 字段来存储 IP 地址。我们这样做是因为它可以同时保存 IPv4 和 IPv6 地址,并且可以轻松地与 .Net IPAddress 类一起使用。 但是,我创建了以下 SQL
我在使用 wxPython 时遇到了一些纯粹的外观问题。例如,标签和它们所代表的控件之间的关系——一切看起来总是至少偏离目标 2-3 个像素,有时甚至更糟。在我当前正在创建的对话中,我已将文本控件的字
我正在开发一个具有 UICollectionView 的应用程序 - Collection View 的工作是显示来自网络服务的数据。 我正在尝试实现的应用程序的一个功能是使用户能够将此 UIColl
我(终于!)找到了一种在玻璃上呈现 Windows.Forms 控件的方法,它似乎没有任何重大缺点,也没有任何大的实现时间。它的灵感来自 this article来自 Coded,它基本上解释了如何
我是一名优秀的程序员,十分优秀!