如何解决调用GDI文本功能后,α值?如何解决、文本、功能、GDI

2023-09-03 23:10:30 作者:格格污的猫儿

我有一个使用航空玻璃效果的应用程序,所以每个像素具有除了红色,绿色和蓝色的值的α值。我有一个自定义绘制控件有一个坚实的白色背景(阿尔法= 255)。我想提请有关使用GDI文本功能的控制坚实的文本。然而,这些功能设置Alpha值的任意值,导致半透明显示任何窗口下我的应用程序的文本。

I have a application that uses the Aero glass effect, so each pixel has an alpha value in addition to red, green, and blue values. I have one custom-draw control that has a solid white background (alpha = 255). I would like to draw solid text on the control using the GDI text functions. However, these functions set the alpha value to an arbitrary value, causing the text to translucently show whatever window is beneath my application's.

在调用渲染的文字,我想经过的所有像素的控制,并设置其alpha值回255。什么是最好的方式做到这一点?

After calling rendering the text, I would like to go through all of the pixels in the control and set their alpha value back to 255. What's the best way to do that?

我还没有任何运气与的BitBlt GetPixel SetPixel 功能。他们似乎浑然不觉alpha值。

I haven't had any luck with the BitBlt, GetPixel, and SetPixel functions. They appear to be oblivious to the alpha value.

下面是我经过思考,并拒绝其他的解决方案:

Here are other solutions that I have considered and rejected:

在画一个位图,然后将位图复制到设备:使用这种方法时,文本渲染不使用的显示器(例如,明文)的特点。如果你知道一种方式来获得GDI呈现文本为位图的完全的,因为它会呈现在屏幕上,这也将解决我的问题。 使用GDI +的文本渲染:此应用程序最初使用GDI +的文本渲染(前我开始工作的Aero支持)。我换,因为我遇到试图精确地测量与GDI +串困难GDI。我宁愿不切换回来。 设置Aero的区域,以避免有问题的控制:我的应用程序的窗口,实际上是一个不同的应用在不同的进程中运行的子窗口。我没有直接控制顶层窗口的Aero的设置。 Draw to a bitmap, then copy the bitmap to the device: With this approach, the text rendering does not make use of the characteristics of the monitor (e.g., ClearText). If you know of a way to get GDI to render the text to the bitmap exactly as it would render to the screen, that would also solve my problem. Use GDI+ for text rendering: This application originally used GDI+ for text rendering (before I started working on Aero support). I switched to GDI because of difficulties I encountered trying to accurately measure strings with GDI+. I'd rather not switch back. Set the Aero region to avoid the control in question: My application's window is actually a child window of a different application running in a different process. I don't have direct control over the Aero settings on the top-level window.

使用Windows窗体应用程序是用C#,虽然我不是在使用互操作调用Win32 API函数。

The application is written in C# using Windows Forms, though I'm not above using Interop to call Win32 API functions.

推荐答案

下面是解决方案,我终于来到了。这是一种丑陋,也许可以简化,但它的工作原理。我们的想法是在原有基础Graphics对象(即屏幕)上创建一个BufferedGraphics对象。在BufferedGraphics对象,TextRenderer.DrawText()将呈现文本酷似它将如果它在屏幕上绘图。然后创建一个普通的图形对象时,缓冲图形对象复制到正规的图形对象,最后得出的常规图形对象在屏幕上。

Below is the solution I eventually came up with. It's kind of ugly and could probably be simplified, but it works. The idea is to create a BufferedGraphics object based on the original Graphics object (i.e., the screen). In the BufferedGraphics object, TextRenderer.DrawText() will render the text exactly like it would if it was drawing to the screen. I then create a regular graphics object, copy the Buffered Graphics object to the regular graphics object, and finally draw the regular graphics object to the screen.

Rectangle inner = new Rectangle(Point.Empty, ContentRectangle.Size);
using (BufferedGraphics bg = BufferedGraphicsManager.Current.Allocate(e.Graphics, inner)) {
    using (Bitmap bmp = new Bitmap(inner.Width, inner.Height, bg.Graphics)) {
        using (Graphics bmpg = Graphics.FromImage(bmp)) {
            bg.Graphics.Clear(BackColor);
            do_my_drawing(bg.Graphics);
            bg.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
            e.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
            bmpg.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;

            bg.Render(bmpg);
            e.Graphics.DrawImageUnscaledAndClipped(bmp, ContentRectangle);
        }
    }
}

设置所有的CompositingMode属性可能是没有必要的,但一旦我得到它的工作我没有理会测试所有的排列要弄清楚,如果有的话,是必要的。

Setting all of the CompositingMode attributes probably isn't necessary, but once I got it working I didn't bother testing all the permutations to figure out which, if any, are needed.