Практическая часть
1. Реализуйте описанные в лабораторной работе действия с процессами, потоками и окнами:
- для каждого процесса рядом с его именем файла, создавшего процесс, выведите зачение его идентификатора, приоритета и дескриптора (дескриптор процесса можно получить с помощью функции OpenProcess);
- для каждого потока, помимо идентификатора родительского процесса и базового приоритета, выведите идентификатор потока;
- для каждого окна, выведите информацию о его дочерних окнах (дескриптор, заголовок окна, прямоугольник вывода, идентификатор родительского процесса и потока);
- добавьте в компонент StringGrid1, используемый для вывода информации о дочерних окнах, подписи к столбцам.
2. Для выбранного из списка процесса выведите сведения о его потоках, используя компонент StringGrid.
3. Для выбранного из списка процесса постройте список всех созданных им окон с указанием состояния каждого окна (видимое-невидимое), используя компонент StringGrid и функцию IsWindowVisible, которая в качестве параметра принимает дескриптор окна.
4. Добавьте возможность завершения процессов системы (и с ручным вводом идентификатора, и с указанием процесса курсором в окне просмотра ListBox). Не завершайте все подряд, чтобы не перезагружать компьютер.
5. Добавьте возможность изменения приоритета выбранного процесса. Уровень приоритета должен выбираться из списка возможных значений.
Приоритет процесса устанавливается функцией SetPriorityClass, в качестве первого параметра предеается дескриптор процесса. Рекомендуется проверять возвращаемое функцией значение, чтобы убедиться, что желаемое действие выполнено успешно. Функция завершается успешно, если величина возвращаемого значения – не ноль; функция завершается с ошибкой, если величина возвращаемого значения – ноль. Для задания значений приоритета процесса следует использовать символические константы, передавая в функцию SetPriorityClass в качестве второго параметра:
REALTIME_PRIORITY_CLASS,
HIGH_PRIORITY_CLASS,
NORMAL_PRIORITY_CLASS,
IDLE_PRIORITY_CLASS.
6. Добавьте возможность делать доступным или не доступным выбранное окно из списка. Для этого необходимо использовать функцию EnableWindow(hWnd: HWND, bEnable:boolean):Boolean, первый параметр которой hWnd – дескриптор того окна, которое должно быть сделано доступным или недоступным, второй параметр bEnable – задает устанавливаемое значение доступности: true – доступно, false – недоступно.
7. Получите и выведите на экран сведения о модулях, используемых выбранным процессом.
8. Представьте, на основании полученных результатов, дерево процессов.
Листинг 1:
unit Unit1;
Interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, TLHelp32, StdCtrls;
type
TForm1 = class(TForm)
SGProcess: TStringGrid;
SGThread: TStringGrid;
LProcess: TLabel;
LThread: TLabel;
SGWindow: TStringGrid;
LChildWindow: TLabel;
LWindow: TLabel;
SGChildWindow: TStringGrid;
BStartThread: TButton;
BStartWindow: TButton;
EExitProcess: TEdit;
BExitProcess: TButton;
LExitProcess: TLabel;
RBRealtime: TRadioButton;
LPriorityProcess: TLabel;
RBHigh: TRadioButton;
RBNormal: TRadioButton;
RBIdle: TRadioButton;
BPriorityProcess: TButton;
RBWindowBlock: TRadioButton;
RBNoWindowBlock: TRadioButton;
BWindowBlock: TButton;
LWindowBlock: TLabel;
MModule: TMemo;
LModule: TLabel;
procedure FormCreate(Sender: TObject);
procedure SGWindowMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure SGProcessMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure BStartThreadClick(Sender: TObject);
procedure BStartWindowClick(Sender: TObject);
procedure BExitProcessClick(Sender: TObject);
procedure BPriorityProcessClick(Sender: TObject);
procedure BWindowBlockClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const
Max_Char=256;
var
Form1: TForm1;
ColProcess, RowProcess : Integer;
ColWindow, RowWindow : Integer;
startThread : array [1..3, 1..2000] of string;
sizeStartThread : Integer;
startWindow : array [1..9, 1..1000] of string;
sizeStartWindow : Integer;
Implementation
{$R *.dfm}
procedure TForm1.BExitProcessClick(Sender: TObject);
var
procId,Ex : Cardinal;
Handlep : Thandle;
begin
if EExitProcess.Text = '' then
Procid:=StrToInt64(SGProcess.Cells[2, RowProcess]) { Окно служит для ручного ввода идентификатора завершаемого процесса }
else
Procid:=StrToInt64(EExitProcess.Text); { Окно служит для ручного ввода идентификатора завершаемого процесса }
HANDLEp:= OpenProcess( PROCESS_TERMINATE, false, procid );
TerminateProcess( HANDLEp, Ex); // завершить процесс
FormCreate(Form1);
FormCreate(Form1);
end;
procedure TForm1.BPriorityProcessClick(Sender: TObject);
var
handlep : Thandle;
begin
handlep := OpenProcess(PROCESS_ALL_ACCESS, false, StrToInt(SGProcess.Cells[2, RowProcess]));
if RBRealtime.Checked then SetPriorityClass(handlep, REALTIME_PRIORITY_CLASS);
if RBHigh.Checked then SetPriorityClass(handlep, HIGH_PRIORITY_CLASS);
if RBNormal.Checked then SetPriorityClass(handlep, NORMAL_PRIORITY_CLASS);
if RBIdle.Checked then SetPriorityClass(handlep, IDLE_PRIORITY_CLASS);
FormCreate(Form1);
end;
procedure TForm1.BStartThreadClick(Sender: TObject);
var
i, j: Integer;
begin
SGThread.RowCount := sizeStartThread + 1;
for i := 1 to sizeStartThread do
begin
for j := 1 to 3 do
SGThread.Cells[j, i] := startThread[j, i];
SGThread.Cells[0, i] := IntToStr(i);
end;
end;
procedure TForm1.BStartWindowClick(Sender: TObject);
var
i, j: Integer;
begin
SGWindow.RowCount := sizeStartWindow + 1;
for i := 1 to sizeStartWindow do
begin
for j := 1 to 9 do
SGWindow.Cells[j, i] := startWindow[j, i];
SGWindow.Cells[0, i] := IntToStr(i);
end;
end;
procedure TForm1.BWindowBlockClick(Sender: TObject);
var
handlep : Thandle;
begin
if RowWindow > 0 then
begin
handlep := StrToInt(SGWindow.Cells[1, RowWindow]);