- Автор темы
- #1
Практический пример на элементы управления.
Данная программа позволяет отображать список загруженных в память компьютера процессов и просматривать связанную с ними информацию. Программа также предоставляет возможность завершить указанный пользователем процесс (если, конечно, права имеются).
Домашнее задание
Реализовать приложение для просмотра изображений. В программе необходимо использовать дерево для навигации по файловой системе и список для отображения содержимого каталога. Также необходимо использовать PictureBox для отображения графических файлов.
Данная программа позволяет отображать список загруженных в память компьютера процессов и просматривать связанную с ними информацию. Программа также предоставляет возможность завершить указанный пользователем процесс (если, конечно, права имеются).
Код:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
using System.Collections;
// Просмотр информации о загруженных процессах
namespace CSharpApplication.ProcessViewer
{
class ProcessViewer : Form
{
// Список процессов
ListView ProcessList;
// Таймер обновления информации
Timer RefreshTimer;
// Убить процесс
Button EndProcess;
// Номер столба, по которому происходит сортировка
int Column;
// Позиция выделения
int SelPos;
// Путь к исполняемому файлу процесса
Label ProcessPath;
// Всплывающая подсказка
ToolTip ProcessPathTip;
static void Main()
{
// Создаем мютекс
System.Threading.Mutex m =
new System.Threading.Mutex(false, "ProcessViewer.MyMutex");
// Проверяем не запущен ли уже экземпляр этого процесса
if(m.WaitOne(0, false) == false)
{
// Уже запущен
MessageBox.Show("This application is already running...",
"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// Запуск приложения
Application.Run(new ProcessViewer());
// Освобождение мютекса
m.ReleaseMutex();
}
// Конструктор
ProcessViewer()
{
// Нет сортировки
this.Column = -1;
// Нет выделения
this.SelPos = -1;
// Форма появляется по центру экрана
this.StartPosition = FormStartPosition.CenterScreen;
// Заголовок
this.Text = "ProcessList";
// Размер
this.Size = new Size(640, 480);
// Пиктограмма из ресурсов
this.Icon = new Icon(GetType(), "Process.ico");
// Путь к исполняемому файлу процесса
this.ProcessPath = new Label();
this.ProcessPath.Parent = this;
this.ProcessPath.AutoSize = true;
this.ProcessPath.Size = new Size(this.ClientSize.Width, 20);
// Расположение
this.ProcessPath.Location = new Point(0, this.ClientSize.Height - 50);
// Привязка
this.ProcessPath.Anchor = AnchorStyles.Bottom |
AnchorStyles.Left | AnchorStyles.Right;
// Создание всплывающей подсказки
this.ProcessPathTip = new ToolTip();
// Кнопка для окончания процесса
this.EndProcess = new Button();
this.EndProcess.Parent = this;
this.EndProcess.Text = "End Process";
this.EndProcess.Size = new Size(this.ClientSize.Width, 30);
this.EndProcess.Location = new Point(0, this.ClientSize.Height - 30);
this.EndProcess.Anchor = AnchorStyles.Bottom |
AnchorStyles.Left | AnchorStyles.Right;
this.EndProcess.TabIndex = 1;
// Обработчик нажатия
this.EndProcess.Click += new EventHandler(EndProcess_Click);
// Список запущенных процессов
this.ProcessList = new ListView();
this.ProcessList.Parent = this;
this.ProcessList.Size =
new Size(this.ClientSize.Width, this.ClientSize.Height - 50);
// Стиль - таблица
this.ProcessList.View = View.Details;
this.ProcessList.Anchor = AnchorStyles.Top |
AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
this.ProcessList.TabIndex = 0;
// Никогда не прятать выделение
this.ProcessList.HideSelection = false;
// Можно выбирать только одну строку одновременно
this.ProcessList.MultiSelect = false;
// Создание столбцов
ColumnHeader [] colHeaders = new ColumnHeader[8];
colHeaders[0] = new ColumnHeader();
// Имя процесса
colHeaders[0].Text = "Process Name";
colHeaders[0].Width = 90;
colHeaders[1] = new ColumnHeader();
// Идентификатор процесса
colHeaders[1].Text = "PID";
colHeaders[1].Width = 40;
colHeaders[2] = new ColumnHeader();
// Отвечает ли процесс на запросы
colHeaders[2].Text = "Responding";
colHeaders[2].Width = 70;
colHeaders[3] = new ColumnHeader();
// Дескриптор главного окна процесса
colHeaders[3].Text = "Main Window Handle";
colHeaders[3].Width = 115;
colHeaders[4] = new ColumnHeader();
// Заголовок главного окна процесса
colHeaders[4].Text = "Main Window Title";
colHeaders[4].Width = 105;
colHeaders[5] = new ColumnHeader();
// Количество использующихся дескрипторов
colHeaders[5].Text = "Handles";
colHeaders[5].Width = 55;
colHeaders[6] = new ColumnHeader();
// Количество запущеннымх процессом потоков
colHeaders[6].Text = "Threads";
colHeaders[6].Width = 55;
colHeaders[7] = new ColumnHeader();
// Объем памяти, который использует процесс
colHeaders[7].Text = "Mem Usage (Kb)";
colHeaders[7].Width = 95;
// Добавляем столбцы в список
this.ProcessList.Columns.AddRange(colHeaders);
// Обработчик щелчка по заголовку столбца
this.ProcessList.ColumnClick += new ColumnClickEventHandler(ProcessList_ColumnClick);
// Обработчик изменения выделения
this.ProcessList.SelectedIndexChanged += new EventHandler(ProcessList_SelectedIndexChanged);
// Можно перетаскивать столбцы
this.ProcessList.AllowColumnReorder = true;
// Выделение всей строки
this.ProcessList.FullRowSelect = true;
// Отображение сетки
this.ProcessList.GridLines = true;
// Создание таймера
this.RefreshTimer = new Timer();
// Время первого старта
this.RefreshTimer.Interval = 100;
// Обработчик таймера
this.RefreshTimer.Tick += new EventHandler(RefreshTimer_Tick);
// Запуск
this.RefreshTimer.Start();
}
// Таймер
private void RefreshTimer_Tick(object sender, EventArgs e)
{
// Тормозим таймер
this.RefreshTimer.Stop();
// Интервал для последующих обновлений
this.RefreshTimer.Interval = 3000;
// Элемент строки
ListViewItem lv;
// Запрет перерисовки списка
this.ProcessList.BeginUpdate();
// Очистка списка
this.ProcessList.Items.Clear();
// Получение списка запущенных процессов
Process [] proc = Process.GetProcesses();
for(int i = 0; i < proc.Length; i++)
{
try
{
// Добавление имени главного модуля процесса
lv = this.ProcessList.Items.Add(proc[i].MainModule.ModuleName);
}
catch
{
// Если нет доступа
continue;
}
// Вставка в строку идентификатора процесса
lv.SubItems.Add(proc[i].Id.ToString());
// Если процесс отвечает на запросы
lv.SubItems.Add((proc[i].Responding) ? "Yes" : "No");
// Если присутствует главное окно
if((int)proc[i].MainWindowHandle != 0)
{
// Дескриптор главного окна
lv.SubItems.Add(proc[i].MainWindowHandle.ToString());
// Заголовок главного окна
lv.SubItems.Add(proc[i].MainWindowTitle);
// Если наш процесс (отрабатывает при первом запуске)
if(this.SelPos == -1 && this.Text == proc[i].MainWindowTitle)
this.SelPos = i;
}
else
{
// Главное окно отсутствует
lv.SubItems.Add("-");
lv.SubItems.Add("");
}
// Количество дескрипторов
lv.SubItems.Add(proc[i].HandleCount.ToString());
// Количество потоков
lv.SubItems.Add(proc[i].Threads.Count.ToString());
// Объем занимаемой памяти в Кб
lv.SubItems.Add((proc[i].WorkingSet / 1024).ToString());
// Запоминаем порядковый номер процесса
lv.Tag = i;
}
// Если установлен столбец сортировки
if(this.Column != -1)
{
// Указываем класс, реализующий интерфейс IComparer,
// который будет использоваться для сортировки строк списка
this.ProcessList.ListViewItemSorter = new ListViewItemComparer(this.Column);
// Сортировка
this.ProcessList.Sort();
// Убираем сортировку
this.ProcessList.ListViewItemSorter = null;
}
// Перебор строк списка
foreach(ListViewItem lvi in this.ProcessList.Items)
{
// Ищем позицию ранее выделенного элемента (до сортировки)
if((int)lvi.Tag == this.SelPos)
{
// Вписываем путь к исполняемому файлу процесса
this.ProcessPath.Text = "Path: " + proc[this.SelPos].MainModule.FileName;
// Ассоциируем всплывающую подсказку с надписью
this.ProcessPathTip.SetToolTip(this.ProcessPath, this.ProcessPath.Text);
//Выделяем найденную строку
this.ProcessList.Items[lvi.Index].Selected = true;
// Убеждаемся, что выделенная строка видима
this.ProcessList.EnsureVisible(lvi.Index);
// Ставим фокус на элемент
lvi.Focused = true;
break;
}
}
// Разрешаем перерисовку списка
this.ProcessList.EndUpdate();
// Запуск таймера
this.RefreshTimer.Start();
}
// Щелчок по заголовку столбца
private void ProcessList_ColumnClick(object sender, ColumnClickEventArgs e)
{
// Номер столбца
this.Column = e.Column;
// Указываем класс, реализующий интерфейс IComparer,
// который будет использоваться для сортировки строк списка
this.ProcessList.ListViewItemSorter = new ListViewItemComparer(e.Column);
// Сортировка
this.ProcessList.Sort();
// Убираем сортировку
this.ProcessList.ListViewItemSorter = null;
}
// Убиваем процесс
private void EndProcess_Click(object sender, EventArgs e)
{
// Если нет выделения
if(this.ProcessList.SelectedIndices.Count == 0)
return;
// Номер выделенной строки
int item = this.ProcessList.SelectedIndices[0];
// Получаем идентификатор процесса
int id = Convert.ToInt32(this.ProcessList.Items[item].SubItems[1].Text);
// Находим процесс по идентификатору
Process pr = Process.GetProcessById(id);
try
{
// Пытаемя закрыть глауное окно (если оно есть)
if(pr.CloseMainWindow() != true)
// "Мочим окно по-взрослому"
pr.Kill();
// Удалем запись из списка
this.ProcessList.Items[item].Remove();
// Убираем путь
this.ProcessPath.Text = "";
// и подсказку
this.ProcessPathTip.SetToolTip(this.ProcessPath, "");
}
catch(Exception ex)
{
// Не сложилось
MessageBox.Show(ex.Message);
}
}
// Выделение изменилось
private void ProcessList_SelectedIndexChanged(object sender, EventArgs e)
{
// Если нет выделения
if(this.ProcessList.SelectedIndices.Count == 0)
return;
// Получаем порядковый номер процесса
this.SelPos = (int)this.ProcessList.SelectedItems[0].Tag;
// Получаем идентификатор процесса
string pid = this.ProcessList.SelectedItems[0].SubItems[1].Text;
// Находим процесс по идентификатору
Process pr = Process.GetProcessById(Convert.ToInt32(pid));
// Обновляем путь
this.ProcessPath.Text = "Path: " + pr.MainModule.FileName;
// и подсказку
this.ProcessPathTip.SetToolTip(this.ProcessPath, this.ProcessPath.Text);
}
}
// Класс, который используется для сортировки строк списка,
// исходя из данных в указанном столбце
class ListViewItemComparer : IComparer
{
// Номер столбца
private int col;
public ListViewItemComparer()
{
col=0;
}
public ListViewItemComparer(int column)
{
col=column;
}
// Функция сравнения
public int Compare(object x, object y)
{
// Вынимаем текст из двух переданных элементов столбца
string s1 = ((ListViewItem)x).SubItems[col].Text;
string s2 = ((ListViewItem)y).SubItems[col].Text;
int i, j;
try
{
// Пытаемся определить числовой ли это столбец
i = Convert.ToInt32(s1);
j = Convert.ToInt32(s2);
}
catch
{
// Столбец строковый
return String.Compare(s1, s2);
}
// Столбец числовой
return i - j;
}
}
}
Домашнее задание
Реализовать приложение для просмотра изображений. В программе необходимо использовать дерево для навигации по файловой системе и список для отображения содержимого каталога. Также необходимо использовать PictureBox для отображения графических файлов.