Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.09.03;
Скачать: [xml.tar.bz2];

Вниз

Помогите с 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.048 c
15-1155099866
KygECHuK
2006-08-09 09:04
2006.09.03
UPX


9-1133771636
@!!ex
2005-12-05 11:33
2006.09.03
OpenGL на ATI и Intel


1-1153480564
МикроДИП
2006-07-21 15:16
2006.09.03
Вопрос по расположению формы...


2-1155460952
Vovan#1
2006-08-13 13:22
2006.09.03
Назначит событию процедуру


15-1155287138
flad
2006-08-11 13:05
2006.09.03
Читать тексты(книги)на ДВД-проигрывателе?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский