Нарисуйте полупрозрачное оверлейное изображение по всей форме окна с некоторыми элементами

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

Я пытался использовать прозрачный контроль. Это подклассификация элемента управления Panel и рисование изображения над этим элементом управления, однако все элементы управления полностью видны.

3 ответа

Для этого потребуется другая форма, которую вы отображаете поверх существующей. Его свойство Opacity может создать желаемый эффект. Добавьте новый класс в ваш проект и вставьте код, показанный ниже. Вызовите метод Close(), чтобы снова удалить эффект.

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class Plexiglass : Form {
    public Plexiglass(Form tocover) {
        this.BackColor = Color.DarkGray;
        this.Opacity = 0.30;      // Tweak as desired
        this.FormBorderStyle = FormBorderStyle.None;
        this.ControlBox = false;
        this.ShowInTaskbar = false;
        this.StartPosition = FormStartPosition.Manual;
        this.AutoScaleMode = AutoScaleMode.None;
        this.Location = tocover.PointToScreen(Point.Empty);
        this.ClientSize = tocover.ClientSize;
        tocover.LocationChanged += Cover_LocationChanged;
        tocover.ClientSizeChanged += Cover_ClientSizeChanged;
        this.Show(tocover);
        tocover.Focus();
        // Disable Aero transitions, the plexiglass gets too visible
        if (Environment.OSVersion.Version.Major >= 6) {
            int value = 1;
            DwmSetWindowAttribute(tocover.Handle, DWMWA_TRANSITIONS_FORCEDISABLED, ref value, 4);
        }
    }
    private void Cover_LocationChanged(object sender, EventArgs e) {
        // Ensure the plexiglass follows the owner
        this.Location = this.Owner.PointToScreen(Point.Empty);
    }
    private void Cover_ClientSizeChanged(object sender, EventArgs e) {
        // Ensure the plexiglass keeps the owner covered
        this.ClientSize = this.Owner.ClientSize;
    }
    protected override void OnFormClosing(FormClosingEventArgs e) {
        // Restore owner
        this.Owner.LocationChanged -= Cover_LocationChanged;
        this.Owner.ClientSizeChanged -= Cover_ClientSizeChanged;
        if (!this.Owner.IsDisposed && Environment.OSVersion.Version.Major >= 6) {
            int value = 1;
            DwmSetWindowAttribute(this.Owner.Handle, DWMWA_TRANSITIONS_FORCEDISABLED, ref value, 4);
        }
        base.OnFormClosing(e);
    }
    protected override void OnActivated(EventArgs e) {
        // Always keep the owner activated instead
        this.BeginInvoke(new Action(() => this.Owner.Activate()));
    }
    private const int DWMWA_TRANSITIONS_FORCEDISABLED = 3;
    [DllImport("dwmapi.dll")]
    private static extern int DwmSetWindowAttribute(IntPtr hWnd, int attr, ref int value, int attrLen);
}

Создайте многоуровневое окно, которое хранится поверх вашей основной формы и синхронизируется с его местоположением. Вы можете изменить альфа-слой многослойного окна, используя 32-битное изображение RGBA, чтобы получить желаемый эффект.

Здесь есть достойная статья о проекте кода, показывающая, как это сделать.

Я полагаю, что более простой подход - поместить прозрачный элемент управления Label, где вы устанавливаете его непрозрачность, а также отключить его функцию AutoSize и изменить размер этикетки до размера поверхности, которую вы хотите покрыть.

Затем, когда вы хотите наложить метку, вы отправляете ее на передний план (программно) и делаете ее видимой. Если вы хотите отключить оверлей, отправьте его обратно и сделайте его невидимым.

Я сделал это с помощью текстовой метки, которая перекрывает всю мою форму. Я думаю, что это будет работать точно так же, если вместо установки свойства Text элемента управления Label вы установите полупрозрачное (PNG) изображение.

Другие вопросы по тегам