p align="left">ListBox1. Items. Add (NR^.lpProvider); L. Add(Buf); end; Q:= $FFFFFFFF; New(Buf); end; Dispose(Buf); end; WNetCloseEnum(R); end; end; procedure TForm4. FormCreate (Sender: TObject); begin ListBox1. Clear; L:= TList. Create; end; procedure TForm4. FormClose (Sender: TObject; var Action: TCloseAction); var I: Integer; begin for I:= 0 to L. Count - 1 do begin Dispose (L. Items[I]); end; L. Free; end; procedure TForm4. Button2Click (Sender: TObject); var s:string; begin if ListBox1. ItemIndex<>-1 then begin s:=ListBox1. Items [ListBox1. ItemIndex]; if s[1]='\' then Delete (s, 1, 2); Form2. Edit1. Text:=s; ModalResult:=mrOK; end; end; procedure TForm4. ListBox1DblClick (Sender: TObject); var Q, BufferSize: DWord; R: THandle; Buf: ^Buffer; P: Pointer; NR: ^NETRESOURCE; NREsource: NETRESOURCE; I: Integer; Err: Integer; Path: string; Sr: TSearchRec; begin NR:= L. Items [ListBox1. ItemIndex]; Move (NR^, NResource, SizeOf(NETRESOURCE)); ListBox1. Clear; Path:= NResource.lpRemoteName; Err:=WNetOpenEnumA (RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, @NResource, R); for I:= 0 to L. Count -1 do begin Dispose (L. Items[I]); end; L. Clear; if Err = NO_ERROR then begin BufferSize:= 1024; q:=1; New(Buf); while WNetEnumResourceA (R, Q, Buf, BufferSize) = NO_ERROR do begin begin P:= Buf; NR:= P; ListBox1. Items. Add (NR^.lpRemoteName); L. Add(Buf); end; New(Buf); end; Dispose(Buf); end; WNetCloseEnum(R); end; Отправление сообщений Приведем часть кода программы, реализующую отправление сообщений: function TForm2.NBName (s:string):string; const size=1024; var ncb:TNCB; buf, p:PChar; i, k:integer; ch:char; res:string; begin NBName:=''; GetMem (buf, size); FillChar (ncb, SizeOf(TNCB), 0); ncb.ncb_command:=char (NCBASTAT); ncb.ncb_buffer:=buf; ncb.ncb_length:=size; for i:=1 to Length (s) do ncb.ncb_callname [i_1]:=UpCase (s[i]); for i:=Length (s) to NCBNAMSZ do ncb.ncb_callname[i]:=' '; ncb.ncb_callname [NCBNAMSZ_1]:=#03; ch:=netbios (addr (ncb)); if (ch<>#0) and (ncb.ncb_retcode<>#0) then Exit; p:=ncb.ncb_buffer; with PAdapterStatus (ncb.ncb_buffer)^ do begin p:=p+SizeOf (TAdapterStatus); for i:=0 to name_count_1 do begin with PNameBuffer (p)^ do begin if (name [NCBNAMSZ_1]=' ') and ((ord (name_flags) and UNIQUE_NAME)=UNIQUE_NAME) then begin res:=''; for k:=0 to NCBNAMSZ_2 do if name[k]<>' ' then res:=res+name[k]; NBName:=res; end; end; p:=p+SizeOf (TNameBuffer); end; end; FreeMem (buf); end; procedure TForm2. Button1Click (Sender: TObject); var handle:THandle; lpFileName:PChar; lpNumberOfBytesWritten: Cardinal; buffer:string; i:integer; s:LPSTR; comp:string; name, name2:PChar; name1:string; namesize:DWORD; begin Button1. Enabled:=False; if RadioButton1. Checked then begin comp:=NBName (Edit1. Text); lpFileName:=PChar ('\\'+comp+'\mailslot\messngr'+#0); handle:=CreateFile (lpFileName, GENERIC_WRITE, 0, NIL, CREATE_ALWAYS, 0, 0); if handle=INVALID_HANDLE_VALUE then begin ShowMessage ('Error when executing CreateFile()'); end; buffer:=''; for i:=0 to Memo1. Lines. Count_1 do buffer:=buffer+Memo1. Lines. Text+#10+#13; name1:=''; namesize:=MAX_COMPUTERNAME_LENGTH + 1; GetMem (name, MAX_COMPUTERNAME_LENGTH + 1); GetComputerName (name, namesize); name2:=name; for i:=0 to namesize_1 do begin name1:=name1+name2^; name2:=name2+1; end; FreeMem (name); buffer:=name1+#0+Edit1. Text+#0+buffer; s:=LPSTR (buffer); WriteFile (handle, s^, length (buffer) - 2, lpNumberOfBytesWritten, NIL); if length (buffer) - 2<>lpNumberOfBytesWritten then begin ShowMessage ('Error when writing file. Number Of Bytes Written: '+IntToStr (lpNumberOfBytesWritten)); end; CloseHandle (handle); end; Button1. Enabled:=True; end; Используя функции NetBIOS, процедура Tform2.NBName определяет. является ли адресат пользователем удалённой машины или данное имя является самим компьютером, а также, не является ли адресат рабочей группой сети Microsoft. Также, часть данной процедуры определяет, запущена или нет на данной машине ещё одна программа «всплывающих сообщений». Так как для совместимости с аналогичными программами требуется указать одно и то же имя почтового слота (в данном случае, имя компьютера, на котором запущено данное приложение), то при наличии другой подобной программы показывается окно с кодом ошибки. Код ошибки определяется средствами NetBIOS и в данной дипломной работе реализована процедурой NBName. Рис. 1.11. Ошибка при создании почтового слота Коды ошибок, выдаваемые NetBIOS, указаны в техническом проекте. Структура приёма сообщений Прикладная программа, используя интерфейс WinAPI и встроенные функции Windows, постоянно опрашивает почтовый слот на наличие приходящего сообщения. В отличие от DOS, например, в котором данная реализация представляла бы бесконечный цикл и все ресурсы компьютера уходили бы на ожидание сообщения, операционная среда Windows позволяет создавать такие циклы без практической потери ресурсов, разделяя части программы на потоки (threads). При наличии сообщения в почтовом слоте оно передаётся в программу средствами NetBIOS. Почтовый слот может содержать в себе любое количество сообщений, независимо от того, когда они все будут востребованы данной программой. Прием сообщений можно реализовать следующим образом: Var L: Tlist; procedure TForm1. ShowMess; var p:PChar; s:string; begin Memo1. Clear; p:=L. Items[Current]; s:='Message from '; repeat s:=s+p^; p:=p+1; until (p^=#0); p:=p+1; s:=s+' to'; repeat s:=s+p^; p:=p+1; until (p^=#0); Label1. Caption:=s; p:=p+1; s:=''; repeat s:=s+p^; p:=p+1; until (p^=#0); Memo1. Lines. Add (s); StatusBar1. Panels[0].Text:='Current message: '+IntToStr (current+1); StatusBar1. Panels[1].Text:='Total number of messages: '+IntToStr (L. Count); end; procedure TForm1. Timer1Timer (Sender: TObject); var lpNextSize:DWORD; lpMessageCount:pointer; buffer:PChar; lpNumberOfBytesRead:DWORD; MessageCount, all:DWORD; s:string; begin lpMessageCount:=addr (MessageCount); if GetMailslotInfo (h, nil, lpNextSize, lpMessageCount, nil) then begin if lpNextSize<>MAILSLOT_NO_MESSAGE then begin Beep; all:=MessageCount; while all<>0 do begin GetMem (buffer, lpNextSize); if ReadFile (h, buffer^, lpNextSize, lpNumberOfBytesRead, nil) then begin s:=''; L. Add (buffer); StatusBar1. Panels[1].Text:='Total number of messages: '+IntToStr (L. Count); if L. Count=1 then begin current:=0; ShowMess; end; GetMailslotInfo (h, nil, lpNextSize, lpMessageCount, nil); end else FreeMem (buffer); all:=all_1; end; end; end; end; Процедура Timer1Timer является ядром получения сообщений, в то время как ShowMess - реализацией выдачи сообщения на экран в виде, понятном пользователю. Строки StatusBar1. Panels[0].Text:='Current message: '+IntToStr (current+1); StatusBar1. Panels[1].Text:='Total number of messages: '+IntToStr (L. Count), входящие в состав данной процедуры, характеризуют номер сообщения по счёту всего количества сообщений и количество всех сообщений. С учетом вышеописанного, пришедшее сообщение выглядит таким образом: Рис. 1.12. Пример полученного сообщения Используя кнопки навигации, можно легко просматривать все пришедшие сообщения, одновременно использую другие функции Messenger'a. Рис. 1.13. Обзор пришедших сообщений В данном разделе в части литературного обзора были рассмотрены общие положения, применяемые разработчиками программного обеспечения средств передачи информации в сетях Microsoft, даны основные подходы создания программ отправки и принятия сообщений; показан пример разработки данного программного обеспечения. В разделе «Постановка задачи» были рассмотрены требования к системе. Технический проект содержит общую структуру системы, структуру данных, связи между объектами, алгоритмические связи, простота использования подобных программ для пользователей, кратко описаны основные типы компонент и классов, используемые для написания программ отправки сообщений. В рабочем проекте дана конфигурация технических средств, алгоритмы работы программы, структурная схема работы программы, показана иерархия форм, включая примеры диалога с пользователем и участки программного кода, описывающие важные процедуры системы отправки и принятия сообщений. В целом представлена полная и объективная картина, отражающая содержание выполненных работ по проектированию программ работы с сетевыми протоколами операционных систем семейства Windows, созданию алгоритмов реализации аналогичного программного обеспечения и их программной реализации. Разработка программ в среде Borland Delphi 5 относится к технологии RAD (Rapid Application Development) - быстрое создание приложений. До появления RAD_средств делались попытки облегчить труд программиста, сделать этот труд более продуктивным, повысив этим быстродействие и удобство создания приложений. Первоначально появились интегрированные среды разработки - IDE (Integrated Development Environment), объединяющие компилятор, специальный текстовый редактор, ориентированный на работы с текстами на целевом языке программирования и средства отладки - трассировщик, дебаггер и другие. По сравнению с предыдущими средствами программирования это был большой шаг вперед, но затем появились CASE_средства, которые позволяли максимально визуализировать процесс создания программы, но пользоваться ими было чересчур неудобно из-за их негибкости. В большинстве случаев написать достаточно сложную программу было очень трудно. Средства RAD, взяв все лучшее из интегрированных сред разработки и CASE систем, объединили гибкость работы с исходными текстами с удобством создания графического интерфейса пользователя - GUI (Graphic User Interface). К сожалению, большинство RAD_средств не позволяют визуализировать логику самой программы, но и те методы, которые заложены в Delphi 5, позволяют поднять производительность разработки программ в 2-3 раза.
Страницы: 1, 2, 3, 4, 5, 6
|