Текущий архив: 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.51 MB
Время: 0.059 c