Продолжаем разговор о своем окне, всплывающем возле области уведомлений, там где 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); } }
Вот, что получилось: