Список использованных источников
1 Рудаков А.В., Федорова Г.Н., Технология разработки программных продуктов. Практикум/ А.В. Рудаков, Г.Н. Федорова – М.: Юнити – Дана, 2014
2 Александр Ч. В., Программирование в Delphi. Трюки и эффекты/ Ч. В. Александр. – М.: ИД "Форум", 2010
3 Рубанцев В. С., Большой самоучитель Delphi XE3/, В. С. Рубанцев. – М.:Гелиос АРВ, 2012
4 Осипов Д. Е., Delphi. Профессиональное программирование/ Д. Е. Осипов. – М.: Издательский центр "Академия", 2006
Приложение А.
Исходный текст программного продукта
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, IpExport, IpRtrMib, IpHlpApi, IpTypes, IpIfConst,
ToolWin, winsock2, Ping, winsock, ShellApi;
type
TPhysAddrByteArray = array [0..MAXLEN_PHYSADDR - 1] of BYTE;
TForm1 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
TabSheet3: TTabSheet;
TabSheet4: TTabSheet;
TabSheet5: TTabSheet;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
GroupBox1: TGroupBox;
Label7: TLabel;
Edit8: TEdit;
Label8: TLabel;
IPListView1: TListView;
Label12: TLabel;
Edit11: TEdit;
Edit12: TEdit;
Label13: TLabel;
Edit13: TEdit;
Label14: TLabel;
Edit14: TEdit;
Label15: TLabel;
ToolBar1: TToolBar;
ToolButton1: TToolButton;
RichEdit1: TRichEdit;
Label16: TLabel;
Label17: TLabel;
Edit15: TEdit;
Edit16: TEdit;
Button1: TButton;
RichEdit2: TRichEdit;
Ping1: TPing;
Label18: TLabel;
Label19: TLabel;
Label20: TLabel;
Edit17: TEdit;
Edit18: TEdit;
Edit19: TEdit;
Button2: TButton;
RichEdit3: TRichEdit;
ProgressBar1: TProgressBar;
TabSheet6: TTabSheet;
Button3: TButton;
Label9: TLabel;
procedure PageControl1Change(Sender: TObject);
procedure ToolButton1Click(Sender: TObject);
|
|
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Ping1DnsLookupDone(Sender: TObject; Error: Word);
procedure Ping1EchoReply(Sender, Icmp: TObject; Error: Integer);
procedure Ping1EchoRequest(Sender, Icmp: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
procedure GetIpInfo;
procedure GetAdapterInfo;
procedure SetArpEntry(const InetAddr, EtherAddr, IntfAddr: string);
function LookupName: TInAddr;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.PageControl1Change(Sender: TObject);
begin
if PageControl1.ActivePageIndex=0 then
GetIpInfo;
if PageControl1.ActivePageIndex=1 then
GetAdapterInfo;
end;
procedure TForm1.GetIpInfo;
var
FixedInfoSize, Err:DWord;
pFixedInfo:PFixed_Info;
pAddrStr:Pip_Addr_String;
begin
FixedInfoSize:=0;
//Записываем размер необходимой памяти для получения полной информации
Err:=GetNetworkParams(nil, FixedInfoSize); //GetNetworkParams возвращает информацию о сети
//Проверяем на ошибки
if (Err<>0) and (Err<>Error_Buffer_OverFlow) then
begin
Edit1.Text:='Ошибка';
exit;
end;
//Выделяем память, куда мы будем записывать полученную информацию
pFixedInfo:=PFixed_Info(GlobalAlloc(GPTR, FixedInfoSize));
GetNetworkParams(pFixedInfo, FixedInfoSize);
Edit1.Text:=StrPas(pFixedInfo.HostName);
Edit3.Text:=StrPas(pFixedInfo.DnsServerList.IpAddress.S);
case pFixedInfo.NodeType of
1: Edit2.Text:='Широковещательный';
2: Edit2.Text:='Одноранговый';
4: Edit2.Text:='Смешаный';
8: Edit2.Text:='Гибридный';
end;
if pFixedInfo.EnableDns>0 then
Edit6.Text:='Активный'
|
|
else
Edit6.Text:='Не активный';
if pFixedInfo.EnableRouting>0 then
Edit5.Text:='Активный'
else
Edit5.Text:='Не активный';
if pFixedInfo.EnableProxy>0 then
Edit4.Text:='Активный'
else
Edit4.Text:='Не активный';
end;
procedure TForm1.GetAdapterInfo;
var
Err, AdapterInfoSize:DWORD;
pAdapterInfo, pAdapt:PIP_ADAPTER_INFO;
Str:String;
i:Integer;
pAddrStr:PIP_ADDR_STRING;
begin
Edit11.Text:='';
Edit14.Text:='';
Edit8.Text:='';
IPListView1.Clear;
Edit13.Text:='';
Edit12.Text:='';
AdapterInfoSize:=0;
Err:=GetAdaptersInfo(nil, AdapterInfoSize);
//Получение информации об устройствах и выделение памяти
pAdapterInfo := PIP_ADAPTER_INFO(GlobalAlloc(GPTR, AdapterInfoSize));
GetAdaptersInfo(pAdapterInfo, AdapterInfoSize);
pAdapt := pAdapterInfo;
//Проверяем тип полученного адаптера
case pAdapt.Type_ of
MIB_IF_TYPE_ETHERNET:
Edit11.Text:=('Адаптер сети интернет');
MIB_IF_TYPE_TOKENRING:
Edit11.Text:=('Token Ring адаптер');
MIB_IF_TYPE_FDDI:
Edit11.Text:=('FDDI адаптер');
MIB_IF_TYPE_PPP:
Edit11.Text:=('PPP адаптер');
MIB_IF_TYPE_LOOPBACK:
Edit11.Text:=('Loopback адаптер');
MIB_IF_TYPE_SLIP:
Edit11.Text:=('Slip адаптер');
MIB_IF_TYPE_OTHER:
Edit11.Text:=('Остальные адаптеры сети');
end;
Str:='';
for i:=0 to pAdapt.AddressLength-1 do
begin
Str:=Str+IntToHex(pAdapt.Address[i],2);
if i<>pAdapt.AddressLength-1 then
Str:=Str+'-';
end;
Edit8.Text:=Str;
pAddrStr:=@pAdapt.IpAddressList;
while pAddrStr<>nil do
begin
with IPListView1.Items.Add do
begin
Caption:=pAddrStr.IpAddress.S;
SubItems.Add(pAddrStr.IpMask.S);
end;
pAddrStr := pAddrStr.Next;
end;
if pAdapt.DhcpEnabled=0 then
|
|
Edit12.Text:='Не активен'
else
Edit12.Text:='Активен';
Edit14.Text:=pAdapt.Description;
Edit13.Text:=pAdapt.GatewayList.IpAddress.S;
end;
//Перевод МАС-адреса из машиного слова
function CharHex(const C: AnsiChar): Byte;
const
AnsiDecDigits = ['0'..'9'];
AnsiHexDigits = ['0'..'9', 'A'..'F', 'a'..'f'];
begin
Result := $FF;
if C in AnsiDecDigits then
Result := Ord(C) - 48
else if C in AnsiHexDigits then
Result := Ord(C) - 55;
end;
//Получение IP-адреса
function StringToIpAddr(const Addr: string): DWORD;
begin
Result := inet_addr(PChar(Addr));
end;
//Определение количества символов в МАС-адресе
procedure StringToPhysAddr(PhysAddrString: string; var PhysAddr: TPhysAddrByteArray);
var
C: Char;
I, V: Integer;
begin
Assert(Length(PhysAddrString) = 17);
Assert(
(PhysAddrString[3] = '-') and
(PhysAddrString[6] = '-') and
(PhysAddrString[9] = '-') and
(PhysAddrString[12] = '-') and
(PhysAddrString[15] = '-'));
PhysAddrString := UpperCase(PhysAddrString);
for I := 0 to 5 do
begin
C := PhysAddrString[I * 3];
V := CharHex(C) shl 4;
C := PhysAddrString[(I * 3) + 1];
V := V + CharHex(C);
PhysAddr[I] := V;
end;
end;
//Добавление IP-адреса в строку
function IpAddrToString(Addr: DWORD): string;
var
inad: in_addr;
begin
inad.s_addr := Addr;
Result:=inet_ntoa(inad);
end;
//Определение типа IP-адреса
function ArpTypeToString(dwType: DWORD): string;
begin
case dwType of
MIB_IPNET_TYPE_OTHER: Result := 'Остальное';
MIB_IPNET_TYPE_INVALID: Result := 'Неизвестный';
MIB_IPNET_TYPE_DYNAMIC: Result := 'Динамический';
MIB_IPNET_TYPE_STATIC: Result := 'Статический';
end;
end;
//Выделение памяти переменной
function GetIpAddrTableWithAlloc: PMibIpAddrTable;
|
|
var
Size: ULONG;
begin
Size := 0;
GetIpAddrTable(nil, Size, True);
Result := AllocMem(Size);
if GetIpAddrTable(Result, Size, True) <> NO_ERROR then
begin
FreeMem(Result);
Result := nil;
end;
end;
//Определение МАС-адреса
function PhysAddrToString(Length: DWORD; PhysAddr: TPhysAddrByteArray): string;
var
I: Integer;
begin
Result := '';
if Length = 0 then Exit;
for I := 0 to Length - 1 do
if I = Integer(Length - 1) then
Result := Result + Format('%.2x', [PhysAddr[I]])
else
Result := Result + (Format('%.2x-', [PhysAddr[I]]));
end;
//Формирования строки с IP-адресом, МАС-фдресом, тип IP-адреса
function IntfIndexToIpAddress(IpAddrTable: PMibIpAddrTable; Index: DWORD): string;
var
I: Integer;
begin
if IpAddrTable = nil then
Result := '<Неопределен>'
else
begin
for I := 0 to IpAddrTable^.dwNumEntries - 1 do
begin
{$R-}
if IpAddrTable^.table[I].dwIndex = Index then
begin
Result := IpAddrToString(IpAddrTable^.table[I].dwAddr);
Break;
end;
{$R+}
end;
end;
end;
//Определение сетевого адаптера
function FirstNetworkAdapter(IpAddrTable: PMibIpAddrTable): Integer;
var
I: Integer;
IfInfo: TMibIfRow;
begin
Result := -1;
for I := 0 to IpAddrTable^.dwNumEntries - 1 do
begin
{$R-}IfInfo.dwIndex := IpAddrTable^.table[I].dwIndex;{$R+}
if GetIfEntry(@IfInfo) = NO_ERROR then
begin
if IfInfo.dwType in [MIB_IF_TYPE_ETHERNET, MIB_IF_TYPE_TOKENRING] then
begin
Result := IfInfo.dwIndex;
Break;
end;
end;
end;
end;
procedure TForm1.SetArpEntry(const InetAddr, EtherAddr, IntfAddr: string);
var
Entry: TMibIpNetRow;
IpAddrTable: PMibIpAddrTable;
begin
//Обнуляем строку
FillChar(Entry, SizeOf(Entry), 0);
//Назначаем IP-адрес
Entry.dwAddr := StringToIpAddr(InetAddr);
Assert(Entry.dwAddr <> DWORD(INADDR_NONE));
//Назначает физический адрес
Entry.dwPhysAddrLen := 6;
StringToPhysAddr(EtherAddr, TPhysAddrByteArray(Entry.bPhysAddr));
Entry.dwType := MIB_IPNET_TYPE_STATIC;
if IntfAddr <> '' then
Entry.dwIndex := StrToInt(IntfAddr)
else
begin
//Указывает интерфейс
IpAddrTable := GetIpAddrTableWithAlloc;
Assert(IpAddrTable <> nil);
Entry.dwIndex := FirstNetworkAdapter(IpAddrTable);
FreeMem(IpAddrTable);
end;
RichEdit1.SelAttributes.Color:=clTeal;
RichEdit1.SelAttributes.Style:=RichEdit1.SelAttributes.Style+[fsBold];
//Дабовляет запись, выводит результат работы
RichEdit1.Lines.Add(SysErrorMessage(SetIpNetEntry(Entry)));
end;
procedure TForm1.ToolButton1Click(Sender: TObject);
var
Size: ULONG;
I: Integer;
NetTable: PMibIpNetTable; // ARP таблица
NetRow: TMibIpNetRow; // строка ARP
CurrentIndex: DWORD; // Используется для показа заголовка
IpAddrTable: PMibIpAddrTable; // Таблица адресов
begin
RichEdit1.Clear;
Size := 0;
GetIpNetTable(nil, Size, True);
NetTable := AllocMem(Size);
try
if GetIpNetTable(NetTable, Size, True) = NO_ERROR then
begin
// Получет таблицу IP адресов
IpAddrTable := GetIpAddrTableWithAlloc;
try
// Запомнить первый интерфейс
CurrentIndex := NetTable^.table[0].dwIndex;
RichEdit1.SelAttributes.Color:=clTeal;
RichEdit1.SelAttributes.Style:=RichEdit1.SelAttributes.Style+[fsBold];
RichEdit1.Lines.Add(Format('Интерфейс: %s на интерфейсе 0x%u', [IntfIndexToIpAddress(IpAddrTable, CurrentIndex), CurrentIndex]));
RichEdit1.SelAttributes.Color:=clTeal;
RichEdit1.SelAttributes.Style:=RichEdit1.SelAttributes.Style+[fsBold];
RichEdit1.Lines.Add(' IP адрес Физический адрес Тип');
// Для каждой записи ARP
for I := 0 to NetTable^.dwNumEntries - 1 do
begin
{$R-}NetRow := NetTable^.table[I];{$R+}
if CurrentIndex <> NetRow.dwIndex then
begin
// Определяем интерфейс
CurrentIndex := NetRow.dwIndex;
RichEdit1.SelAttributes.Color:=clTeal;
RichEdit1.SelAttributes.Style:=RichEdit1.SelAttributes.Style+[fsBold];
RichEdit1.Lines.Add(Format('Интерфейс: %s на интерфейсе 0x%u',
[IntfIndexToIpAddress(IpAddrTable, CurrentIndex), CurrentIndex]));
RichEdit1.SelAttributes.Color:=clTeal;
RichEdit1.SelAttributes.Style:=RichEdit1.SelAttributes.Style+[fsBold];
RichEdit1.Lines.Add(' IP адрес Физический адрес Тип ');
end;
// Отображаем строки
RichEdit1.Lines.Add(Format(' %-20s %-30s %s', [IpAddrToString(NetRow.dwAddr),
PhysAddrToString(NetRow.dwPhysAddrLen, TPhysAddrByteArray(NetRow.bPhysAddr)),
ArpTypeToString(NetRow.dwType)]));
RichEdit1.Lines.Add('');
end;
finally
FreeMem(IpAddrTable);
end;
end
else
begin
//Если таблица не найдена, то выводим сообщение
RichEdit1.SelAttributes.Color:=clRed;
RichEdit1.SelAttributes.Style:=RichEdit1.SelAttributes.Style+[fsBold];
RichEdit1.Lines.Add('ARP таблица не найдена.');
end;
finally
FreeMem(NetTable);
end;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
ToolButton1Click(nil);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
RichEdit2.Lines.Add('Поиск'''+Edit15.Text+'');
Ping1.Size:=StrToInt(Edit16.Text);
Ping1.DnsLookup(Edit15.Text);
end;
procedure TForm1.Ping1DnsLookupDone(Sender: TObject; Error: Word);
begin
//Если произошла ошибка, то
if Error <> 0 then
begin
//Вывести сообщение об ошибке
RichEdit2.Lines.Add('Хочт не найден ' +Edit15.Text + '''');
//Выход
exit;
end;
//Если ошибок не было, то выводим в Rich результат поиска
RichEdit2.Lines.Add('Хост ''' +Edit15.Text + '''- ' +Ping1.DnsResult);
//Устанавливаем свойство Address компонента Ping равным адресу, найденному в базе DNS
Ping1.Address:=Ping1.DnsResult;
//Запускаем Ping
Ping1.Ping;
end;
procedure TForm1.Ping1EchoReply(Sender, Icmp: TObject; Error: Integer);
begin
//Выполняем результат Ping
//проверка на ошибки, если равно 0, то вывести сообщение об ошибке
if Error = 0 then
RichEdit2.Lines.Add('Не могу выполнить операцию ping: '+Ping1.ErrorString)
else
//Если нет ошибки, то показывается время, за которое прошел Ping
RichEdit2.Lines.Add('Получено ' +IntToStr(Ping1.Reply.DataSize)+ ' байт от '
+Ping1.HostIp+' за ' +IntToStr(Ping1.Reply.Rtt)+' милисекунд ');
end;
procedure TForm1.Ping1EchoRequest(Sender, Icmp: TObject);
begin
//Это событие вылавливает и выводится сообщение о том, что сейчас отправляются
//данные в определенном размере на машину с указанным алресом
//Выводит состояния Ping
RichEdit2.Lines.Add('Посылка ' +IntToStr(Ping1.Size) +' байт на '+
Ping1.HostName);
end;
//Функция преобразовывает введенный адрес сервера в специальный формат
//Если введено символьное имя, то она сначало преобразовывает в IP адрес,
//а потом переводит в специальный формат
function TForm1.LookupName: TInAddr;
var
HostEnt: PHostEnt;
InAddr: TInAddr;
begin
if Pos('.', Edit17.Text)>0 then
InAddr.s_addr := inet_addr(PChar(Edit17.Text))
else
begin
HostEnt := gethostbyname(PChar(Edit17.Text));
FillChar(InAddr, SizeOf(InAddr), 0);
if HostEnt <> nil then
begin
with InAddr, HostEnt^ do
begin
S_un_b.s_b1 := h_addr^[0];
S_un_b.s_b2 := h_addr^[1];
S_un_b.s_b3 := h_addr^[2];
S_un_b.s_b4 := h_addr^[3];
end;
end
end;
Result := InAddr;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i, j, s, o, index: Integer;
FSocket: array [0..41] of TSOCKET; //Массив сокета
busy : array [0..41] of boolean; //Массив, в котором будет храниться информация о каждом сканируемом сокете
port : array [0..41] of integer; //Массив сканируемых портов
addr : TSockAddr;
hEvent : THandle; //Объект для обработки сетевых событий
fset : TFDset;
tv : TTimeval;
tec :PServEnt;
PName:String;
GInitData : TWSADATA;
begin
//Устанавливаю максимальное и минимальное значение полоски состояния сканирование
//Я устанавливаю в минимум начальный порт сканирования, а в максимум конечный порт
ProgressBar1.Min:=StrToInt(Edit18.Text);
ProgressBar1.Max:=StrToInt(Edit19.Text);
//Инициализирует WinSock
WSAStartup(MAKEWORD(2,0), GInitData);
//Записывает в переменную i значение начального порта
i:=StrToInt(Edit18.Text);
//Заполняет основные поля структуры addr, которая будет использоваться
//при вызове функции connect
addr.sin_family := AF_INET;
addr.sin_addr.s_addr := INADDR_ANY;
//Выводит сообщение о том, что начат поис введенных портов
RichEdit3.SelAttributes.Color:=clTeal;
RichEdit3.SelAttributes.Style:=RichEdit3.SelAttributes.Style+[fsBold];
RichEdit3.Lines.Add('Поиск хоста');
//LookupName - эта функция написана выше и она возращает адрес в специальном формате указанного сервера
//Результат этой функции записывается в поле адреса сервера структуры addr
addr.sin_addr := LookupName;
//Выводит сообщение о том, что начато сканирование
RichEdit3.SelAttributes.Color:=clTeal;
RichEdit3.SelAttributes.Style:=RichEdit3.SelAttributes.Style+[fsBold];
RichEdit3.Lines.Add('Сканирование...');
//В index находится количество сокетов проверяемы за один раз
index:=40;
//Создает объект для обработки сетевых событий
hEvent:=WSACreateEvent();
while i<StrToInt(Edit19.Text) do
begin
//Всем элементам массива busy присваевает значение false
for j:=0 to index do
busy[j]:=false;
//В этом цикле будут посылаться асинхронно запросы на соединение
//переменная j будет изменятся от 0 до максимального количества
//элементов в массиве
for j:=0 to index do
begin
//Если j-й порт превысил значение указанного максимальное
//порта, то прервать цикл
if i>StrToInt(Edit19.Text) then
begin
index:=j-1;
break;
end;
//Инициализируем очередной j-й сокет из массива FSocket
FSocket[j]:=socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
//Добавляем j-й сокет к объекту событий с помощью WSAEventSelect
//1-ый параметр - добавляемый сокет
//2-? Параметр - объект событий, который бфл создан с помощью WSACreateEvent
//3-? параметр - какие события ожидать. Указываем FD_WRITE - событие записи и FD_CONNECT - событие о заключение соединение
WSAEventSelect(FSocket[j], hEvent, FD_WRITE + FD_CONNECT);
//Указываем порт, на который нужно произвести попытку соединения
addr.sin_port := htons(i);
//Попытка соединения на очередной порт
connect(FSocket[j], addr, sizeof(addr));
//Даем ОС поработать и обработать накопившиеся события.
//Если этого не делать то вовремя сканирования произойдет
//происходить эффект зависания
Application.ProcessMessages;
//Проверяет, были ошибки
if WSAGetLastError()=WSAEINPROGRESS then
begin
//Если ошибка бала, то закрывает порт
closesocket (FSocket[j]);
//Устанавливает соответствующий элемент в массиве busy в true
//чтобы потом не проверять этот порт, потому что он все равно
//уже закрыт
busy[j]:=true;
end;
//Указывает в массиве port, на какой именно порт мы послали запрос
port[j]:=i;
//Увеличивает счетчик i в котором утслеживается какой порт сейчас сканироуется
//чтобы на следующем этапе цикла for запустить сканирование следующего порта
i:=i+1;
end;
//Обнуляем переменную fset
FD_Zero(fset);
//Заполняет сканируемый массив сокетов в переменную fset
for j := 0 to index do
begin
if busy[j] <> true then
FD_SET (FSocket[j], fset);
end;
//Даем ОС поработать и обработать накопившиеся события.
Application.ProcessMessages;
//Заполняем структуру в котором указано время ожидания события от сокета
tv.tv_sec := 1; //Будем ждать 1 секунду
tv.tv_usec := 0;
//Ожидаем пока произойдет событие от любого из сокета
s:=select (1, nil, @fset, nil, @tv);
//Даем ОС поработать и обработать накопившиеся события.
Application.ProcessMessages;
//Запускаем массив, в котором будет проверяться, какие из сокетов в массиве FSocket
//прошли подключение успешно, а какие нет.
for j := 0 to index do
begin
//Проверяет был за крыт соответствующий порт из-за ошибки
//Если да, то нет смысла проверять.
if busy[j] then continue;
if FD_ISSET (FSocket[j], fset) then
begin
//В переменную s записывается размер переменной O
s:=Sizeof(O);
o:=1;
//Получаем состояние j-го сокета
//результат состояния будет в переменной o
getsockopt(FSocket[j], SOL_SOCKET, SO_ERROR, @o, s);
//Если o равно 0 порт открыт и к нему можно подключиться
if o=0 then
begin
//Узнает сивольное имя порта
tec := getservbyport(htons(Port[j]),'TCP');
if tec=nil then
PName:='Недоступен'
else
begin
PName:=tec.s_name;
end;
//Выводит сообщение об открытом порте
RichEdit3.Lines.Add('Хост:'+Edit17.Text+': порт :'+IntToStr(Port[j])+' ('+Pname+') '+' открыт ');
end;
end;
//Закрыть j-й сокет, потому что он больше уже не нужен
closesocket(FSocket[j]);
end;
//Увеличивает позицию ProgressBar1
ProgressBar1.Position:=i;
end;
//Закрывает объект событий
WSACloseEvent(hEvent);
//Выводит сообщение о завершении сканирования
RichEdit3.SelAttributes.Color:=clTeal;
RichEdit3.SelAttributes.Style:=RichEdit3.SelAttributes.Style+[fsBold];
RichEdit3.Lines.Add('Сканирование завершено...');
ProgressBar1.Position:=0;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
ShellExecute(Handle, 'open', 'Help\help.chm',nil, nil, SW_SHOW);
end;
end.
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm2 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses Unit1;
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
var
SaveTxt: TStringList;
iterIntCount: integer;
Login: string;
begin
if (edit1.Text='') or (edit2.Text='') then Application.MessageBox('Введите логин и пароль!','Внимание!',MB_OK) else begin
SaveTxt := TStringList.Create;
SaveTxt.LoadFromFile(ExtractFilePath(Application.ExeName) + 'Login.txt');
Login:= Edit1.Text + ' ' + Edit2.Text;
for iterIntCount:= 0 to SaveTxt.Count - 1 do
begin
If Login = SaveTxt[iterIntCount] then
begin
Form1.Show;
Break;
end
else
Application.MessageBox('Неверный логин или пароль!','Внимание!',MB_OK);
end;
end;
end;
procedure TForm2.Button2Click(Sender: TObject);
begin
Close;
Application.Terminate;
end;
end.
Дата добавления: 2019-02-22; просмотров: 234; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!