Прозрачная Winform с изображением - PullRequest
1 голос
/ 23 апреля 2009

У меня есть изображение (файл PNG) с альфа-каналом, который установлен на 50% непрозрачным. Когда я пытаюсь нарисовать изображение в форме, в которой для параметра TransparencyKey установлено значение белого, а для заднего цвета - белый, я ожидаю, что изображение будет прорисовано на 50% прозрачным. Однако сначала он смешивается с фоновым цветом форм, и в результате он полностью непрозрачен. Есть ли способ обойти это? Я не хочу устанавливать свойство Opaque формы, поскольку некоторые изображения в форме должны быть полупрозрачными, а некоторые - непрозрачными.

Ответы [ 3 ]

1 голос
/ 02 сентября 2009

В итоге я использовал многоуровневое окно, используя расширенный стиль окна WS_EX_LAYERED.

http://msdn.microsoft.com/en-us/library/ms997507.aspx

0 голосов
/ 02 сентября 2009

Nice. Не забывайте, что в Vista есть менеджер окон рабочего стола для создания полупрозрачных окон (он же Areo) http://msdn.microsoft.com/en-us/magazine/cc163435.aspx

0 голосов
/ 26 апреля 2009

Не думаю, что ты можешь. У нас есть заставка, где мы сделали что-то подобное, но в итоге мы сделали снимок экрана и установили его в качестве фонового изображения формы. Очевидно, это работает только в том случае, если экран меняется, фон формы не меняется и все выглядит странно. Если вы найдете лучший способ сделать это, я хотел бы знать об этом.

Вот код для захвата экрана, просто установите ScreenRect для координат экрана форм и вызовите Process ():

using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace TourFactory.Core.Drawing
{
    public class CaptureScreenCommand
    {

        #region Initialization and Destruction

        public CaptureScreenCommand()
        {
        }

        #endregion

        #region Fields and Properties

        // BitBlt is a multipurpose function that takes a ROP (Raster OPeration) code
        // that controls exactly what it does. 0xCC0020 is the ROP code SRCCOPY, i.e.
        // do a simple copy from the source to the destination.
        private const int cRasterOp_SrcCopy = 0xCC0020; // 13369376;

        private Rectangle mScreenRect;
        /// <summary>
        /// Gets or sets the screen coordinates to capture.
        /// </summary>
        public Rectangle ScreenRect
        {
            get { return mScreenRect; }
            set { mScreenRect = value; }
        }

        #endregion

        #region Methods

        public Image Process()
        {
            // use the GDI call and create a DC to the whole display
            var dc1 = CreateDC("DISPLAY", null, 0, 0);
            var g1 = Graphics.FromHdc(dc1);

            // create a compatible bitmap the size of the form
            var bmp = new Bitmap(mScreenRect.Width, mScreenRect.Height, g1);
            var g2 = Graphics.FromImage(bmp);

            // Now go retrace our steps and get the device contexts for both the bitmap and the screen
            // Note: Apparently you have to do this, and can't go directly from the aquired dc or exceptions are thrown
            // when you try to release the dcs
            dc1 = g1.GetHdc();
            var dc2 = g2.GetHdc();

            // Bit Blast the screen into the Bitmap
            BitBlt(dc2, 0, 0, mScreenRect.Width, mScreenRect.Height, dc1, mScreenRect.Left, mScreenRect.Top, cRasterOp_SrcCopy);

            // Remember to release the dc's, otherwise problems down the road
            g1.ReleaseHdc(dc1);
            g2.ReleaseHdc(dc2);

            // return bitmap
            return bmp;
        }

        #endregion

        #region gdi32.dll

        [DllImport("gdi32")]
        private static extern IntPtr CreateDC(string lpDriverName, string lpDeviceName, int lpOutput, int lpInitData);

        [DllImport("gdi32")]
        private static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int width, int height, IntPtr hdcSrc, int xSrc, int ySrc, int dwRop);

        #endregion

    }
}
...