C# Всплывающая форма над областью уведомлений, делаем сами.

Продолжаем разговор о своем окне, всплывающем возле области уведомлений, там где NotifyIcon. Как в тех же мессенджерах при появлении нового сообщения.

На самом деле все оказывается довольно просто, и даже Ктулху вызывать пользоваться WinAPI не надо.

На первом этапе моделируем будущую всплывающую форму. Я, например, создал форму без границ (FormBorderStyle = none), поместил на нее TextBox, который будет отображать сообщение и PictureBox, который будет работать в качестве кнопки закрытия формы.

На форму добавляем необходимые компоненты, которые отвечают за отображение информации и таймер (tmrAni), который будет отвечать за анимацию всплытия формы.

1. Заводим переменные, сохраняющие позиции формы:

private int StartPosX; private int StartPosY;

Ну я еще добавил переменную для сообщения и экспортировал функцию WinAPI, прячущую текстовый курсор:

[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool HideCaret(IntPtr hWnd);
public string MessageText = "";

Плюс настроил в инициализации формы некоторые ее параметры:

public frmPopup()
{
    InitializeComponent();
    //Настройка формы
    this.TopMost = false;
    this.ShowInTaskbar = false;
}

TopMost = false нужен, чтоб форма всплывала из-за области уведомлений, а не загораживала ее собой.

2. Переопределяем обработчик события Load и в нем прячем форму за экран:

protected override void OnLoad(EventArgs e)
{
    //Прячем форму за экран
    StartPosX = Screen.PrimaryScreen.WorkingArea.Width - this.Width;
    StartPosY = Screen.PrimaryScreen.WorkingArea.Height;
    SetDesktopLocation(StartPosX, StartPosY);
    base.OnLoad(e);
    //запуск анимации всплытия
    tmrAni.Interval = 50;
    tmrAni.Start();

}

Туда же можно вставить запуск таймера, который будет анимировать всплытие формы (после base.OnLoad(e)).

Если просто вставить этот код в обработчик события Load, то форма на секунду появится на экране, и будет некрасиво.

3. Далее в обработчиках событий Load и Shown настраиваем нашу форму, например, присваиваем TextBox нужный текст и т.д.

private void frmPopup_Load(object sender, EventArgs e)
{
    //настраиваем TextBox с сообщением
    txtMessage.Height = this.Height - txtMessage.Location.Y - 3;
    txtMessage.Width = this.Width - txtMessage.Location.X - 3;
    txtMessage.BorderStyle = BorderStyle.None;
    txtMessage.BackColor = this.BackColor;
    txtMessage.Text = MessageText;
    txtMessage.ReadOnly = true;
    txtMessage.SelectionStart = 0;

    //и кнопку закрытия
    int CloseX = this.Width - pbClose.Width - 3;
    int CloseY = 3;
    pbClose.Location = new Point(CloseX, CloseY);
}

private void frmPopup_Shown(object sender, EventArgs e)
{
    HideCaret(txtMessage.Handle);
}

3. При каждом срабатывании таймера поднимаем форму на 5 пикселей, а когда форма покажется полностью, то останавливаем таймер и делаем ее «поверх всех окон» (TopMost = true;):

private void tmrAni_Tick(object sender, EventArgs e)
{
    //поднимаем форму на 5 пикселей
    StartPosY -= 5;

    //Если окно видно полностью - останавливаем таймер
    if (StartPosY < Screen.PrimaryScreen.WorkingArea.Height - Height)
    {
        tmrAni.Stop();
        this.TopMost = true;
    }
    else
    {
        SetDesktopLocation(StartPosX, StartPosY);
    }
}

Вот, что получилось:

Код примера целиком

На GitHub

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *