Шаг 43.
Microsoft Visual C++ 2010. Начала.
Базовые компоненты. Компонент NotifyIcon

    На этом шаге мы рассмотрим назначение, основные свойства и пример использования этого компонента.

    Компонент NotifyIcon (рисунок 1) представляет собой "извещающий" значок (notify — извещать, напоминать), который изображает в панели задач программу, работающую в фоновом режиме.


Рис.1. Компонент NotifyIcon

    Обычно при позиционировании указателя мыши на таком значке появляется подсказка, а в результате щелчка правой кнопкой — контекстное меню, команды которого позволяют получить доступ к программе (открыть окно) или завершить ее работу.

    Свойства компонента приведены в таблице 1.

Таблица 1. Свойства компонента NotifyIcon
Свойство Описание
Icon Значок, который отображается в панели задач
Text Подсказка (обычно название программы). Отображается рядом с указателем мыши при позиционировании указателя на значке
ContextMenu Ссылка на компонент ContextMenu, который обеспечивает отображение контекстного меню как результат щелчка правой кнопкой мыши на значке
Visible Свойство позволяет скрыть (false) значок с панели задач или сделать его видимым (true)

    Программа "Будильник" (ее окно приведено на рисунке 2, а значения свойств компонентов — в таблице 2) демонстрирует использование компонента NotifyIcon. Во время создания формы надо присвоить значение свойству Icon компонента NotifyIcon — выбрать из доступных значков (ico-файлов) подходящий.


Рис.2. Форма программы "Будильник"

Таблица 2. Значения свойств компонентов
Свойство Значение
timer1.Interval 1000
timer1.Enabled True
contextMenuStrip1.toolStripMenuItem1.Text Показать
contextMenuStrip1.toolStripMenuItem2.Text О программе
contextMenuStrip1.toolStripMenuItem3.Text Завершить
notifyIcon1.Icon
notifyIcon1.Visible False
notifyIcon1.ContextMenu contextMenuStrip1

    В окне программы "Будильник" после ее запуска отображается текущее время. После того как пользователь установит время сигнала, задаст текст сообщения и сделает щелчок на кнопке OK, окно программы закроется и в системной области панели задач появится колокольчик — значок, изображающий работающую программу "Будильник". При позиционировании указателя мыши на колокольчике появляется подсказка, в которой отображается время, когда будильник должен подать сигнал и текст напоминания. В контекстном меню программы, которое появляется в результате щелчка правой кнопкой мыши, три команды: Показать, О программе и Завершить (рисунок 3).


Рис.3. Значок программы "Будильник" в панели задач: подсказка и контекстное меню

    Конструктор (он выполняет настройку компонентов) и функции обработки событий приведены в листинге ниже. Обратите внимание, в текст программы добавлена ссылка (ее надо поместить после списка используемых пространств имен) на библиотеку winmm.dll, в которой находится функция PlaySound, обеспечивающая воспроизведение звукового сигнала. Звуковой файл должен быть в папке программы (при запуске из среды разработки в режиме отладки — в папке Debug).

#pragma once

#include "Form2.h"

namespace N_Icon {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;

        // функция PlaySound, обеспечивающая воспроизведение
	// wav-файлов, находится в библиотеке winmm.dll
	// подключим эту библиотеку
	[System::Runtime::InteropServices::DllImport("winmm.dll")]
	extern
      bool PlaySound(String^ lpszName, int hModule, int dwFlags);

	/// <summary>
	/// Сводка для Form1
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
			InitializeComponent();
			//
			//TODO: добавьте код конструктора
			//
			// настройка компонентов numericUpDown
			numericUpDown1->Maximum = 23;
			numericUpDown1->Minimum = 0;
			
			numericUpDown2->Maximum = 59;
			numericUpDown2->Minimum = 0;
			
			numericUpDown1->Value = DateTime::Now.Hour;
			numericUpDown2->Value = DateTime::Now.Minute+5;
			
			notifyIcon1->Visible = false;
			
			isSet = false;
			
			// настройка и запуск таймера
			timer1->Interval = 1000;
			timer1->Enabled = true;
			
			label4->Text = DateTime::Now.ToLongTimeString();
		}
.    .    .    .    .
#pragma endregion

	private:		
		DateTime alarm; // время сигнала (отображения сообщения)
		bool isSet;     // true - будильник установлен (работает)

// щелчок на кнопке OK
private: System::Void button1_Click(System::Object^  sender, 
        System::EventArgs^  e) {
		// установить время сигнала
		alarm = DateTime(
			DateTime::Now.Year,
			DateTime::Now.Month,
			DateTime::Now.Day,
			Convert::ToInt16(numericUpDown1->Value),
			Convert::ToInt16(numericUpDown2->Value),
		0, 0);

// если установленное время будильника меньше
// текущего, нужно увеличить дату срабатывания
// на единицу (+1 день)
		if (DateTime::Compare(DateTime::Now, alarm) > 0)
			alarm = alarm.AddDays(1);

		// подсказка:
		// будет отображаться при
		// позиционировании указателя мыши
		// на значке программы
		notifyIcon1->Text =
			"Будильник - " + alarm.ToShortTimeString() + "\n" +
			textBox1->Text;

		isSet = true;
			
		this->Hide();
		notifyIcon1->Visible = true;
	 }

// сигнал от таймера
private: System::Void timer1_Tick(System::Object^  sender, 
	System::EventArgs^  e) {

	label4->Text = DateTime::Now.ToLongTimeString();

	// будильник установлен
	if ( isSet)
	{
		// время срабатывания будильника
		if (DateTime::Compare(DateTime::Now, alarm) > 0)
			{
				isSet = false;
			
				if ( checkBox1->Checked )
				{
				PlaySound(Application::StartupPath +
					"\\EXP.wav", 0, 1);
				}

				Form2^ frm; // окно сообщения
				// см. конструктор формы Form2
				frm = gcnew Form2(DateTime::Now.ToShortTimeString(),
					this->textBox1->Text);
				
				frm->ShowDialog(); // показать окно сообщения
				this->Show(); // показать окно программы
			}
	}
 }

// команда Показать
private: System::Void toolStripMenuItem1_Click(System::Object^  sender, 
		System::EventArgs^  e)
{
	isSet = false;     // остановить будильник
	this->Show();      // показать окно программы 
	notifyIcon1->Visible = false;
}

// команда О программе
private: System::Void toolStripMenuItem2_Click(System::Object^  sender, 
		System::EventArgs^  e)
{
		 
}

// команда Завершить
private: System::Void toolStripMenuItem3_Click(System::Object^  sender, 
		System::EventArgs^  e)
{
	 this->Close();
}
        
// щелчок на значке
private: System::Void notifyIcon1_Click(System::Object^  sender, 
		System::EventArgs^  e)
{         
	// если нет контекстного меню, то открыть окно программы можно так:
	/*    isSet = false;
	this->Show();
	notifyIcon1->Visible = false;*/           
}

    Обратите внимание на обработчик timer1_Tick, который вызывается при генерации сигнала от таймера. В его тексте используется еще одна форма (Form2) для вывода сообщения.

    Добавим в наш проект новую форму. Это можно сделать, вызвав пункт меню Проект | Добавить новый элемент..., и в появившемся окне выбрать Форма Windows Forms, а в строке Имя указать ее имя: Form2 (рисунок 4):


Рис.4. Добавление в проект новой формы

    Внешний вид этой формы приведен на рисунке 5:


Рис.5. Внешний вид второй формы

    На ней 3 компонента: две метки и кнопка. По нажатию на кнопку форма будет закрываться.

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

.   .   .   
	Form2(void)
	{
		InitializeComponent();
		//
		//TODO: добавьте код конструктора
		//
	}
	/*
	  Так как нам нужно, чтобы при появлении формы
	  в полях label отображалось текущее время
	  и сообщение, создадим конструктор с параметрами,
	  который будет устанавливать значение свойства Text
	  этих компонентов. Форму будем создавать, используя
	  этот, а не стандартный конструктор.
      */

	// мой конструктор
	Form2(String^ s1, String^ s2)
	{
		InitializeComponent();
		//
		label1->Text = s1;
		label2->Text = s2;
	}
.   .   .   
// кнопка OK
private: System::Void button1_Click(System::Object^  sender, 
System::EventArgs^  e) {
		  this->Close();
	 }
Архив проекта можно взять здесь.

    В заключение не забудьте к форме Form1 подключить форму Form2. Это делается использованием конструкции:

#include "Form2.h"
которая располагается в самом начале кода первой формы.

    На следующем шаге мы рассмотрим компонент ToolStrip.




Предыдущий шаг Содержание Следующий шаг