{ Сетевая утилита. Аналогична функции NetWork-Neighborhood - Сетевое Окружение.} unit netres_main_unit; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs, ComCtrls, StdCtrls, Buttons, Menus, ExtCtrls; type TfrmMain = class(TForm)tvResources: TTreeView;btnOK: TBitBtn;btnClose: TBitBtn;Label1: TLabel;barBottom: TStatusBar;popResources: TPopupMenu;mniExpandAll: TMenuItem;mniCollapseAll: TMenuItem;mniSaveToFile: TMenuItem;mniLoadFromFile: TMenuItem;grpListType: TRadioGroup;grpResourceType: TRadioGroup;dlgOpen: TOpenDialog;dlgSave: TSaveDialog;procedure FormCreate(Sender: TObject);procedure btnCloseClick(Sender: TObject);procedure FormShow(Sender: TObject);procedure mniExpandAllClick(Sender: TObject);procedure mniCollapseAllClick(Sender: TObject);procedure mniSaveToFileClick(Sender: TObject);procedure mniLoadFromFileClick(Sender: TObject);procedure btnOKClick(Sender: TObject);privateListType, ResourceType: DWORD;procedure ShowHint(Sender: TObject);procedure DoEnumeration;procedure DoEnumerationContainer(NetResContainer: TNetResource);procedure AddContainer(NetRes: TNetResource);procedure AddShare(TopContainerIndex: Integer; NetRes:TNetResource); procedure AddShareString(TopContainerIndex: Integer; ItemName:String); procedure AddConnection(NetRes: TNetResource);public{ Public declarations }end; var frmMain: TfrmMain; implementation {$R *.DFM} procedure TfrmMain.ShowHint(Sender: TObject); begin barBottom.Panels.Items[0].Text:=Application.Hint;end; procedure TfrmMain.FormCreate(Sender: TObject); begin Application.OnHint:=ShowHint;barBottom.Panels.Items[0].Text:='';end; procedure TfrmMain.btnCloseClick(Sender: TObject); begin Close;end; { Перечисляем все сетевые ресурсы:} procedure TfrmMain.DoEnumeration; var NetRes: Array[0..2] of TNetResource;Loop: Integer;r, hEnum, EntryCount, NetResLen: DWORD;begin case grpListType.ItemIndex of{ Подключенные ресурсы: }1: ListType:=RESOURCE_CONNECTED;{ Возобновляемые ресурсы: }2: ListType:=RESOURCE_REMEMBERED;{ Глобальные: }else ListType:=RESOURCE_GLOBALNET;end; case grpResourceType.ItemIndex of{ Дисковые ресурсы: }1: ResourceType:=RESOURCETYPE_DISK;{ Принтерные ресурсы: }2: ResourceType:=RESOURCETYPE_PRINT;{ Все: }else ResourceType:=RESOURCETYPE_ANY;end; Screen.Cursor:=crHourGlass; try{ Удаляем любые старые элементы из дерева: }for Loop:=tvResources.Items.Count-1 downto 0 dotvResources.Items[Loop].Delete;exceptend; { Начинаем перечисление: }r:=WNetOpenEnum(ListType,ResourceType,0,nil,hEnum);if r<>NO_ERROR thenbeginif r=ERROR_EXTENDED_ERROR thenMessageDlg('Невозможно сделать обзор сети.'+#13+'Произошла сетевая ошибка.',mtError,[mbOK],0)elseMessageDlg('Невозможно сделать обзор сети.',mtError,[mbOK],0);Exit;end; try{ Мы получили правильный дескриптор перечисления; опрашиваем ресурсы: }while (1=1) dobeginEntryCount:=1;NetResLen:=SizeOf(NetRes);r:=WNetEnumResource(hEnum,EntryCount,@NetRes,NetResLen);case r of0: begin{ Это контейнер, организуем итерацию: }if NetRes[0].dwUsage=RESOURCEUSAGE_CONTAINER thenDoEnumerationContainer(NetRes[0])else{ Здесь получаем подключенные и возобновляемые ресурсы: }if ListType in [RESOURCE_REMEMBERED,RESOURCE_CONNECTED]then AddConnection(NetRes[0]);end; { Получены все ресурсы: }ERROR_NO_MORE_ITEMS: Break;{ Другие ошибки: }else beginMessageDlg('Ошибка опроса ресурсов.',mtError,[mbOK],0);Break;end;end;end; finallyScreen.Cursor:=crDefault;{ Закрываем дескриптор перечисления: }WNetCloseEnum(hEnum);end;end; { Перечисление заданного контейнера:Данная функция обычно вызывается рекурсивно.} procedure TfrmMain.DoEnumerationContainer(NetResContainer: TNetResource); var NetRes: Array[0..10] of TNetResource;TopContainerIndex: Integer;r, hEnum, EntryCount, NetResLen: DWORD;begin { Добавляем имя контейнера к найденным сетевым ресурсам: }AddContainer(NetResContainer);{ Делаем этот элемент текущим корневым уровнем: }TopContainerIndex:=tvResources.Items.Count-1;{ Начинаем перечисление: }if ListType=RESOURCE_GLOBALNET then{ Перечисляем глобальные объекты сети: }r:=WNetOpenEnum(ListType,ResourceType,RESOURCEUSAGE_CONTAINER,@NetResContainer,hEnum)else{ Перечисляем подключаемые и возобновляемые ресурсы (другие получить здесь невозможно):} r:=WNetOpenEnum(ListType,ResourceType,RESOURCEUSAGE_CONTAINER,nil,hEnum);{ Невозможно перечислить ресурсы данного контейнера;выводим соответствующее предупреждение и едем дальше: }if r<>NO_ERROR thenbeginAddShareString(TopContainerIndex,'<Не могу опросить ресурсы(Ошибка #'+ IntToStr(r)+'>');WNetCloseEnum(hEnum);Exit;end; { Мы получили правильный дескриптор перечисления; опрашиваем ресурсы: }while (1=1) dobeginEntryCount:=1;NetResLen:=SizeOf(NetRes);r:=WNetEnumResource(hEnum,EntryCount,@NetRes,NetResLen);case r of0: begin{ Другой контейнер для перечисления;необходим рекурсивный вызов: }if (NetRes[0].dwUsage=RESOURCEUSAGE_CONTAINER) or(NetRes[0].dwUsage=10) thenDoEnumerationContainer(NetRes[0])elsecase NetRes[0].dwDisplayType of{ Верхний уровень: }RESOURCEDISPLAYTYPE_GENERIC,RESOURCEDISPLAYTYPE_DOMAIN,RESOURCEDISPLAYTYPE_SERVER: AddContainer(NetRes[0]);{ Ресурсы общего доступа: }RESOURCEDISPLAYTYPE_SHARE:AddShare(TopContainerIndex,NetRes[0]); end;end;ERROR_NO_MORE_ITEMS: Break;else beginMessageDlg('Ошибка #'+IntToStr(r)+' при перечисленииресурсов.',mtError,[mbOK],0);Break;end;end;end; { Закрываем дескриптор перечисления: }WNetCloseEnum(hEnum);end; procedure TfrmMain.FormShow(Sender: TObject); begin DoEnumeration;end; { Добавляем элементы дерева; помечаем, что это контейнер:} procedure TfrmMain.AddContainer(NetRes: TNetResource); var ItemName: String;begin ItemName:=Trim(String(NetRes.lpRemoteName));if Trim(String(NetRes.lpComment))<>'' thenbeginif ItemName<>'' then ItemName:=ItemName+' ';ItemName:=ItemName+'('+String(NetRes.lpComment)+')';end;tvResources.Items.Add(tvResources.Selected,ItemName);end; { Добавляем дочерние элементы к контейнеру, обозначенному как текущий верхний уровень:} procedure TfrmMain.AddShare(TopContainerIndex: Integer; NetRes: TNetResource); var ItemName: String;begin ItemName:=Trim(String(NetRes.lpRemoteName));if Trim(String(NetRes.lpComment))<>'' thenbeginif ItemName<>'' then ItemName:=ItemName+' ';ItemName:=ItemName+'('+String(NetRes.lpComment)+')';end; tvResources.Items.AddChild(tvResources.Items[TopContainerIndex],ItemName); end; { Добавляем дочерние элементы к контейнеру, обозначенному как текущий верхний уровень;это просто добавляет строку для таких задач, как, например,перечисление контейнера. То есть некоторые контейнерныересурсы общего доступа нам не доступны.} procedure TfrmMain.AddShareString(TopContainerIndex: Integer; ItemName: String); begin tvResources.Items.AddChild(tvResources.Items[TopContainerIndex],ItemName); end; { Добавляем соединения к дереву.По большому счету к этому моменту все сетевые ресурсы типавозобновляемых и текущих соединений уже отображены.} procedure TfrmMain.AddConnection(NetRes: TNetResource); var ItemName: String;begin ItemName:=Trim(String(NetRes.lpLocalName));if Trim(String(NetRes.lpRemoteName))<>'' thenbeginif ItemName<>'' then ItemName:=ItemName+' ';ItemName:=ItemName+'-> '+Trim(String(NetRes.lpRemoteName));end;tvResources.Items.Add(tvResources.Selected,ItemName);end; { Раскрываем все контейнеры дерева:} procedure TfrmMain.mniExpandAllClick(Sender: TObject); begin tvResources.FullExpand;end; { Схлопываем все контейнеры дерева:} procedure TfrmMain.mniCollapseAllClick(Sender: TObject); begin tvResources.FullCollapse;end; { Записываем дерево в выбранном файле:} procedure TfrmMain.mniSaveToFileClick(Sender: TObject); begin if dlgSave.Execute thentvResources.SaveToFile(dlgSave.FileName);end; { Загружаем дерево из выбранного файла:} procedure TfrmMain.mniLoadFromFileClick(Sender: TObject); begin if dlgOpen.Execute thentvResources.LoadFromFile(dlgOpen.FileName);end; { Обновляем:} procedure TfrmMain.btnOKClick(Sender: TObject); begin DoEnumeration;end; end. |
[000200]