如何重写 Winforms 控件的绘制方法以使其绘制到纹理?

发布于 2025-01-08 06:46:22 字数 550 浏览 1 评论 0原文

我正在尝试将 Winforms 与 SharpDX 项目集成,以便在我的 3D 应用程序中使用 Winforms(最终通过 HostElement 使用 WPF)。

我需要创建或配置一个控件或表单,以便我可以

:将其渲染为纹理(我可以将其显示为精灵*)
b.当控件不活动时,过滤其输入以删除鼠标/键盘事件。

我尝试过对 Control 和 Form 进行子类化,以覆盖 OnPaint 和 OnPaintBackground 但这些对子控件没有影响 - 或者就表单边框而言(即使它们这样做了,它们本身也不够,因为我仍然留下一个白色的方块,我认为已经在其中绘制了“父级”)。

如何停止在屏幕上绘制控件或窗体,而只绘制位图?(例如,是否有某种方法可以在绘制树之前覆盖图形?)

*它需要以这种方式完成(而不是让控件渲染到屏幕),因为 Winforms 不支持真正的透明度,所以我需要在像素着色器中剪辑颜色编码的像素。

(确认一下,我并不是专门指 DirectX 纹理 - 我对(事实上更喜欢)一个简单的 System.Drawing 位图感到满意)

I am trying to integrate Winforms with a SharpDX project, in order to use Winforms (and eventually WPF via HostElement) in my 3D app.

I need to create or configure a Control or Form such that I can:

a. Render it to a texture (that I can display as a sprite*)
b. Filter its input to remove mouse/keyboard events when the control is not active.

I have tried subclassing Control and Form, to override the OnPaint and OnPaintBackground but these have no effect on the child controls - or for that matter the forms borders (and even if they did they are not sufficient on their own as I am still left with a white square where I presume the 'parent' has been drawn).

How can I stop a Control or Form painting to the screen and instead draw only to a bitmap? (Is there some way I can override Graphics before the tree is painted, for example?)

*It needs to be done this way (as opposed to letting the control render to the screen) as Winforms doesn't support true transparency, so I need to clip colour coded pixels in my pixel shader.

(To confirm, I don't mean a DirectX texture specifically - I am happy with (in fact would prefer) a simple System.Drawing Bitmap)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

静谧幽蓝 2025-01-15 06:46:22

下面是开始处理它的一种方法:

  • 创建一个派生控件类,以便我们可以公开受保护的 InvokePaint
  • 调用我们的自定义方法来获取控件的图像
  • 测试表单需要一个图片框和一个 Mybutton 实例

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1() { InitializeComponent(); }

        private void Form1_Load(object sender, EventArgs e)
        {
            // create image to which we will draw
            var img = new Bitmap(100, 100);

            // get a Graphics object via which we will draw to the image
            var g = Graphics.FromImage(img);

            // create event args with the graphics object
            var pea = new PaintEventArgs(g, new Rectangle(new Point(0,0), new Size(100,100)));

            // call DoPaint method of our inherited object
            btnTarget.DoPaint(pea);

            // modify the image with algorithms of your choice...

            // display the result in a picture box for testing and proof
            pictureBox.BackgroundImage = img;
        }
    }

    public class MyButton : Button
    {
        // wrapping InvokePaint via a public method
        public void DoPaint(PaintEventArgs pea)
        {
            InvokePaint(this, pea);
        }
    }
}

Here is one way to start going about it:

  • Create a derived control class so that we can expose InvokePaint which is protected
  • Call our custom method to get the Control's image
  • Test form needs a picture box and an instance of Mybutton

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1() { InitializeComponent(); }

        private void Form1_Load(object sender, EventArgs e)
        {
            // create image to which we will draw
            var img = new Bitmap(100, 100);

            // get a Graphics object via which we will draw to the image
            var g = Graphics.FromImage(img);

            // create event args with the graphics object
            var pea = new PaintEventArgs(g, new Rectangle(new Point(0,0), new Size(100,100)));

            // call DoPaint method of our inherited object
            btnTarget.DoPaint(pea);

            // modify the image with algorithms of your choice...

            // display the result in a picture box for testing and proof
            pictureBox.BackgroundImage = img;
        }
    }

    public class MyButton : Button
    {
        // wrapping InvokePaint via a public method
        public void DoPaint(PaintEventArgs pea)
        {
            InvokePaint(this, pea);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文