Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.09.03;
Скачать: CL | DM;

Вниз

Помогите с ComboBox   Найти похожие ветки 

 
SARbe   (2006-08-12 01:15) [0]

Ребята, мне надо определить список IP-интерфейсов ПК и завести в список ComboBox1.
Нашел такой листинг, с ним работать не знаю :(

unit Unit1;

interface

uses
Windows, Winsock;

{

Если Вы поместите строку результатов в wide TMEMO
(в его свойство memo.lines.text)
то никаких результатов не увидите.

Тестировалось на Win98/ME/2K, 95 OSR 2 и NT service
pack #3 , потому что используется WinSock 2 (WS2_32.DLL)

}

function EnumInterfaces(var sInt: string): Boolean;

{ функция WSAIOCtl импортируется из Winsock 2.0 - Winsock 2 доступен }
{ только в Win98/ME/2K и 95 OSR2, NT srv pack #3 }

function WSAIoctl(s: TSocket; cmd: DWORD; lpInBuffer: PCHAR; dwInBufferLen:
DWORD;
lpOutBuffer: PCHAR; dwOutBufferLen: DWORD;
lpdwOutBytesReturned: LPDWORD;
lpOverLapped: POINTER;
lpOverLappedRoutine: POINTER): Integer; stdcall; external "WS2_32.DLL";

{ Константы взятые из заголовка C файлов }

const
SIO_GET_INTERFACE_LIST = $4004747F;
IFF_UP = $00000001;
IFF_BROADCAST = $00000002;
IFF_LOOPBACK = $00000004;
IFF_POINTTOPOINT = $00000008;
IFF_MULTICAST = $00000010;

type sockaddr_gen = packed record
AddressIn: sockaddr_in;
filler: packed array [0..7] of char;
end;

type INTERFACE_INFO = packed record
iiFlags: u_long; // Флаги интерфейса
iiAddress: sockaddr_gen; // Адрес интерфейса
iiBroadcastAddress: sockaddr_gen; // Broadcast адрес
iiNetmask: sockaddr_gen; // Маска подсети
end;

implementation

{-------------------------------------------------------------------

1. Открываем WINSOCK
2. Создаём сокет
3. Вызываем WSAIOCtl для доступа к сетевым интерфейсам
4. Для каждого интерфейса, получаем IP, MASK, BROADCAST, статус
5. Разделяем строку символом CRLF
6. Конец :)

--------------------------------------------------------------------}

function EnumInterfaces(var sInt: string): Boolean;
var
s: TSocket;
wsaD: WSADATA;
NumInterfaces: Integer;
BytesReturned, SetFlags: u_long;
pAddrInet: SOCKADDR_IN;
pAddrString: PCHAR;
PtrA: pointer;
Buffer: array[0..20] of INTERFACE_INFO;
i: Integer;
begin
result := true; // Инициализируем переменную
sInt := "";

WSAStartup($0101, wsaD); // Запускаем WinSock
// Здесь можно дабавить различные обработчики ошибки :)

s := Socket(AF_INET, SOCK_STREAM, 0); // Открываем сокет
if (s = INVALID_SOCKET) then
  exit;

try // Вызываем WSAIoCtl
  PtrA := @bytesReturned;
  if (WSAIoCtl(s, SIO_GET_INTERFACE_LIST, nil, 0, @Buffer,
  1024, PtrA, nil, nil) <> SOCKET_ERROR) then
  begin // Если OK, то определяем количество существующих интерфейсов

    NumInterfaces := BytesReturned div SizeOf(INTERFACE_INFO);

    for i := 0 to NumInterfaces - 1 do // Для каждого интерфейса
    begin
      pAddrInet := Buffer[i].iiAddress.addressIn; // IP адрес
      pAddrString := inet_ntoa(pAddrInet.sin_addr);
      sInt := sInt + " IP=" + pAddrString + ",";
      pAddrInet := Buffer[i].iiNetMask.addressIn; // Маска подсети
      pAddrString := inet_ntoa(pAddrInet.sin_addr);
      sInt := sInt + " Mask=" + pAddrString + ",";
      pAddrInet := Buffer[i].iiBroadCastAddress.addressIn; // Broadcast адрес
      pAddrString := inet_ntoa(pAddrInet.sin_addr);
      sInt := sInt + " Broadcast=" + pAddrString + ",";

      SetFlags := Buffer[i].iiFlags;
      if (SetFlags and IFF_UP) = IFF_UP then
        sInt := sInt + " Interface UP," // Статус интерфейса up/down
      else
        sInt := sInt + " Interface DOWN,";

      if (SetFlags and IFF_BROADCAST) = IFF_BROADCAST then // Broadcasts
        sInt := sInt + " Broadcasts supported," // поддерживает или
      else // не поддерживается
        sInt := sInt + " Broadcasts NOT supported,";

      if (SetFlags and IFF_LOOPBACK) = IFF_LOOPBACK then // Циклический или
        sInt := sInt + " Loopback interface"
      else
        sInt := sInt + " Network interface"; // нормальный

      sInt := sInt + #13#10; // CRLF между каждым интерфейсом
    end;
end;
except
end;
//
// Закрываем сокеты
//
CloseSocket(s);
WSACleanUp;
result := false;
end;

end.


 
Zeqfreed_   (2006-08-12 01:24) [1]

const
MAX_ADAPTER_NAME_LENGTH = 256;
MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
MAX_ADAPTER_ADDRESS_LENGTH = 8;

MAX_INTERFACE_NAME_LEN = 256;

OutBufLen: ULONG = 2000;

type
PIP_ADDRESS_STRING = ^IP_ADDRESS_STRING;
IP_ADDRESS_STRING = array[0..15] of char; // IP as string

PIP_ADDR_STRING = ^IP_ADDR_STRING;
IP_ADDR_STRING = record
 Next: PIP_ADDR_STRING;
 IpAddress: IP_ADDRESS_STRING;
 IpMask: IP_ADDRESS_STRING;
 Context: DWORD;
end;

PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;
IP_ADAPTER_INFO = record
 Next: PIP_ADAPTER_INFO;
 ComboIndex: DWORD;
 AdapterName: array[1..MAX_ADAPTER_NAME_LENGTH + 4] of char;
 Description: array[1..MAX_ADAPTER_DESCRIPTION_LENGTH + 4] of char;
 AddressLength: UINT;
 Address: array[1..MAX_ADAPTER_ADDRESS_LENGTH] of byte;
 Index: DWORD;
 aType: UINT;
 DHCPEnabled: UINT;
 CurrentIPAddress: PIP_ADDR_STRING;
 IPAddressList: IP_ADDR_STRING;
 GatewayList: IP_ADDR_STRING;
 DHCPServer: IP_ADDR_STRING;
 HaveWINS: BOOL;
 PrimaryWINSServer: IP_ADDR_STRING;
 SecondaryWINSServer: IP_ADDR_STRING;
 LeaseObtained: LongInt;
 LeaseExpires: LongInt;
 SpareStuff: array [1..200] of char;
end;

TAddress = record
 Addr : String[15];
 Mask : String[15];
end;

TGateway = record
 Addr : String[15];
 Mask : String[15];
end;

TAdapter = record
 Name, Desc, MAC : String;
 Addresses : array of TAddress;
 Gateways : array of TGateway;
end;

. . .

var
 Adapters : array of TAdapter;
 frmMain: TfrmMain;

implementation

{$R *.dfm}

function GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO; pOutBufLen: PULONG): DWORD; stdcall; external "Iphlpapi.dll" name "GetAdaptersInfo";

function MAC2String(const MAC : array of Byte) : String;
begin
Result := Format("%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x", [MAC[0], MAC[1], MAC[2], MAC[3], MAC[4], MAC[5]]);
end;

function TfrmMain.GetInformation() : Boolean;
var
Info : PIP_ADAPTER_INFO;
Adapter : PIP_ADAPTER_INFO;
ulOutBufLen : ULONG;
i, alen, Res : DWORD;
begin
Result := false;

ulOutBufLen := OutBufLen;

GetMem(Info, ulOutBufLen);
if (GetAdaptersInfo(Info, @ulOutBufLen) = ERROR_BUFFER_OVERFLOW) then begin
 FreeMem(Info);
 GetMem(Info, ulOutBufLen);
end;

Res := GetAdaptersInfo(Info, @ulOutBufLen);
if (Res = NO_ERROR) then begin
 Adapter := Info;
 alen := 0;
 while (Adapter <> nil) do begin
  Inc(alen);
  SetLength(Adapters, alen);
 
  with frmMain.memDesc do begin
   Adapters[High(Adapters)].Name := Adapter^.AdapterName;
   Adapters[High(Adapters)].Desc := Adapter^.Description;
   SetLength(Adapters[High(Adapters)].Addresses, Adapter^.AddressLength);

   for i := 0 to Adapter^.AddressLength - 1 do begin
    Adapters[High(Adapters)].Addresses[i].Addr := Adapter^.IPAddressList.IpAddress;
    Adapters[High(Adapters)].Addresses[i].Mask := Adapter^.IPAddressList.IpMask;
    Adapters[High(Adapters)].MAC := MAC2String(Adapter^.Address);

    if (Adapter^.IPAddressList.Next <> nil) then
     Adapter^.IPAddressList := Adapter^.IPAddressList.Next^;
   end;

   SetLength(Adapters[High(Adapters)].Addresses, Adapter^.AddressLength);

   repeat
    SetLength(Adapters[High(Adapters)].Gateways, Length(Adapters[High(Adapters)].Gateways) + 1);
    Adapters[High(Adapters)].Gateways[High(Adapters[High(Adapters)].Gateways)].Addr := Adapter^.GatewayList.IpAddress;
    Adapters[High(Adapters)].Gateways[High(Adapters[High(Adapters)].Gateways)].Mask := Adapter^.GatewayList.IpMask;

    if (Adapter^.IPAddressList.Next <> nil) then
     Adapter^.GatewayList := Adapter^.GatewayList.Next^;
   until (Adapter^.GatewayList.Next = nil);
  end;

  Adapter := Adapter^.Next;  
 end;
end;

for i := 0 to High(Adapters) do begin
 cmbAdapters.Items.Add(Adapters[i].Name);
end;

cmbAdapters.ItemIndex := 0;

ShowAdapterInfo(0);

Result := true;
end;


Этого честное слово достаточно чтобы разобраться! Пожалуйста, не надо просить привести пример :)


 
Zeqfreed_   (2006-08-12 01:37) [2]

Я вот щас посмотрел и подумал, а не надо ли очищать выделенную память. Код я честно переписывал с примера из МСДН и там память не освобождается. Я теперь терзаюсь сомнениями: после вызова ф-ции система берет на себя ответственность за эту память или в МСДН код приведен не полностью?

Кстати сказать, если надо перечислить только интерфейсы, то GetAdaptersInfo здесь несколько избыточна, можно использовать GetInterfaceInfo.


 
Zeqfreed_   (2006-08-12 01:40) [3]

Немного оффтопика:

On Windows XP and later:  The list of adapters returned by GetAdaptersInfo includes unidirectional adapters. To generate a list of adapters that can both send and receive data, call GetUniDirectionalAdapterInfo, and exclude the returned adapters from the list returned by GetAdaptersInfo.

(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iphlp/iphlp/getadaptersinfo.asp)

Удивляюсь до чего в Майкрософт любят костыли. Хотя, вероятно, у них есть свои на то основания.


 
Anatoly Podgoretsky ©   (2006-08-12 14:31) [4]

Где ты увидел костыль. Такие интерфейсы имеют право на существование. даже более скажу очень, очень имеют право на существование.


 
Zeqfreed ©   (2006-08-12 15:11) [5]

> [4] Anatoly Podgoretsky ©   (12.08.06 14:31)

Мне это не кажется удобным и логичным. Гораздо правильнее было бы завести отдельную ф-цию или желательно флаг для перечисления только не однонаправленных устройств. Такие извороты, как мне кажется, свидетельствуют о неправильной внутренней архитектуре. Хотя, я допускаю что это было сделано ради оптимизации.


 
SARbe   (2006-08-12 20:38) [6]

Хмм.. скажите что делать.
Вобщем то тут кучу всего напишет, а мне надо только комбобокс с IP сетевых интерфейсов.


 
Ketmar ©   (2006-08-12 20:50) [7]

наверное, комбобокс делать?


 
SARbe   (2006-08-12 21:15) [8]

Ребят не знаю как... как мне функцию для комбобокса вызвать?

Помогите мне это единственное, что надо для того, что бы сделать программку для редактирования скриптов чата. Я айпи из реестра могу взять, но если несколько сетевых интерфейсов есть - оно не спавится :(


 
Ketmar ©   (2006-08-12 21:20) [9]

> [8] SARbe   (12.08.06 21:15)
чего? чей IP из реестра? какую "функцию для комбобокса"?

и -- не поверю. далеко не нединственное. неумение формулировать свои мысли на естественном языке автоматически означает неумение формулировать их на языках искуственных.


 
Zeqfreed ©   (2006-08-12 21:27) [10]

unit Main;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

const
 MAX_ADAPTER_NAME_LENGTH = 256;
 MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
 MAX_ADAPTER_ADDRESS_LENGTH = 8;
 MAX_INTERFACE_NAME_LEN = 256;

type
 PIP_ADDRESS_STRING = ^IP_ADDRESS_STRING;
 IP_ADDRESS_STRING = array[0..15] of char;

 PIP_ADDR_STRING = ^IP_ADDR_STRING;
 IP_ADDR_STRING = record
  Next: PIP_ADDR_STRING;
  IpAddress: IP_ADDRESS_STRING;
  IpMask: IP_ADDRESS_STRING;
  Context: DWORD;
 end;

 PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;
 IP_ADAPTER_INFO = record
  Next: PIP_ADAPTER_INFO;
  ComboIndex: DWORD;
  AdapterName: array[1..MAX_ADAPTER_NAME_LENGTH + 4] of char;
  Description: array[1..MAX_ADAPTER_DESCRIPTION_LENGTH + 4] of char;
  AddressLength: UINT;
  Address: array[1..MAX_ADAPTER_ADDRESS_LENGTH] of byte;
  Index: DWORD;
  aType: UINT;
  DHCPEnabled: UINT;
  CurrentIPAddress: PIP_ADDR_STRING;
  IPAddressList: IP_ADDR_STRING;
  GatewayList: IP_ADDR_STRING;
  DHCPServer: IP_ADDR_STRING;
  HaveWINS: BOOL;
  PrimaryWINSServer: IP_ADDR_STRING;
  SecondaryWINSServer: IP_ADDR_STRING;
  LeaseObtained: LongInt;
  LeaseExpires: LongInt;
  SpareStuff: array [1..200] of char;
 end;

 TEnumIPsCallback = procedure(const IPAddr : String; ArbitraryData : Pointer) of object;

 TForm1 = class(TForm)
   ComboBox1: TComboBox;
   procedure FormCreate(Sender: TObject);
 private
  procedure FillInTheComboBox(const ComboBox : TComboBox);
  procedure MyEnum(const IPAddr : String; Combo : Pointer);
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

function GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO; pOutBufLen: PULONG): DWORD; stdcall;

implementation

{$R *.dfm}

function GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO; pOutBufLen: PULONG): DWORD; stdcall; external "Iphlpapi.dll" name "GetAdaptersInfo";

function EnumIPs(const EnumIPsCallback : TEnumIPsCallback; ArbitraryData : Pointer) : Integer;
var
 Info, Adapter : PIP_ADAPTER_INFO;
 ulOutBufLen : ULONG;
 i : Integer;
begin
 Result := 0;

 ulOutBufLen := 1024;

 GetMem(Info, ulOutBufLen);
 if (GetAdaptersInfo(Info, @ulOutBufLen) = ERROR_BUFFER_OVERFLOW) then begin
  FreeMem(Info);
  GetMem(Info, ulOutBufLen);
 end;

 if (GetAdaptersInfo(Info, @ulOutBufLen) = NO_ERROR) then begin
  Adapter := Info;

  while (Adapter <> nil) do begin
   for i := 0 to Adapter^.AddressLength - 1 do begin
    EnumIPsCallback(Adapter^.IPAddressList.IpAddress, ArbitraryData);
    Inc(Result);

    if (Adapter^.IPAddressList.Next <> nil) then
     Adapter^.IPAddressList := Adapter^.IPAddressList.Next^;
   end;

   Adapter := Adapter^.Next;    
  end;
 end;
end;

procedure TForm1.MyEnum(const IPAddr : String; Combo : Pointer);
var
 ComboBox : TComboBox;

 function ItemAlreadyExists(const Item : String) : Boolean;
 var
  i : Integer;
 begin
  Result := false;
  if (ComboBox.Items.Count <= 0) then Exit;

  for i := 0 to ComboBox.Items.Count - 1 do
   if (ComboBox.Items[i] = Item) then begin
    Result := true;
    Exit;
   end;
 end;

begin
 if not Assigned(Combo) then Exit;
 ComboBox := TComboBox(Combo);

 if not ItemAlreadyExists(IPAddr) then
  ComboBox.Items.Add(IPAddr);
end;

procedure TForm1.FillInTheComboBox(const ComboBox : TComboBox);
begin
 if not Assigned(ComboBox1) then Exit;
 ComboBox1.Clear;
 EnumIPs(MyEnum, Pointer(ComboBox));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FillInTheComboBox(ComboBox1);
end;

end.


FillInTheComboBox(ComboBox1); — Ф-ция «для комбобокса» :)


 
SARbe   (2006-08-13 00:58) [11]

Zeqfreed: БОЛЬШОЕ ЧЕЛОВЕЧЕСКОЕ СПАСИБО!

Ketmar: Ранее я описывал какая у меня проблемма, что необходимо просто IP в ComboBox, придираться тут... ну не знаю, право, конечно твое, но не совсем красиво.
Если бы я был крутым программером, я бы НЕ ЛЕЗ В ФОРУМ ДЛЯ НАЧИНАЮЩИХ, а тут уж извини, что я не так выразился. Увы, так сложилось, что Delphi я увлекался в школе, а потом забросил :(


 
Ketmar ©   (2006-08-13 01:07) [12]

> [11] SARbe   (13.08.06 00:58)
а я вообще ужасно некрасивый. знакомые девушки подтверждают.


 
Zeqfreed ©   (2006-08-13 06:49) [13]

> [11] SARbe   (13.08.06 00:58)

Да пожалуйста, толку-то только от этого. В коде, кстати, есть парочка опечаток.

procedure TForm1.FillInTheComboBox(const ComboBox : TComboBox);
begin
if not Assigned(ComboBox1) then Exit;
ComboBox1.Clear;
EnumIPs(MyEnum, Pointer(ComboBox));
end;


Естественно, ComboBox1 надо заменить на ComboBox.



Страницы: 1 вся ветка

Текущий архив: 2006.09.03;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.031 c
2-1155224863
Финжер
2006-08-10 19:47
2006.09.03
Ярлык, Объект, Проводник. Функша.


15-1155461333
Чемульпо
2006-08-13 13:28
2006.09.03
Помогите плиз!


15-1154954506
antonn
2006-08-07 16:41
2006.09.03
ищу музончик...


11-1131995649
Flea
2005-11-14 22:14
2006.09.03
поиск в Richedit


15-1154961344
worldmen
2006-08-07 18:35
2006.09.03
Создание каталога в DOS