Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi ComboBox-Eintraege doppelt und x-fach vorhanden (https://www.delphipraxis.net/82035-combobox-eintraege-doppelt-und-x-fach-vorhanden.html)

Mackhack 7. Dez 2006 05:43


ComboBox-Eintraege doppelt und x-fach vorhanden
 
Hi DPler,

mit diesen beiden Functions ermittle ich die Workgroups und die dazugehoerigen Computernamen im Netzwerk.

Delphi-Quellcode:
function TfoNetworkConnection.GetNetComputerNames: String;
var
  I: Integer;
  hEnum: THandle;
  Entries: DWORD;
  BufferSize: DWORD;
  NetResourceBuf: Array[0..511] of TNetResource;
  NetResource: TNetResource;
begin
  if ( CbxWorkgroup.ItemIndex > -1 ) then
  begin
    CbxComputerName.Clear;
    try
      NetResource.dwScope := RESOURCE_GLOBALNET;
      NetResource.dwType := RESOURCETYPE_ANY;
      NetResource.dwDisplayType := RESOURCEDISPLAYTYPE_GENERIC;
      NetResource.dwUsage := RESOURCEUSAGE_CONNECTABLE;
      NetResource.lpLocalName := nil;
      NetResource.lpRemoteName := PChar(CbxWorkgroup.Items[CbxWorkgroup.ItemIndex]);
      NetResource.lpComment := nil;
      NetResource.lpProvider := nil;

      if ( WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, @NetResource, hEnum) <> NO_ERROR ) then
      begin
        ShowMessage('Could not connect to workgroup: ' + String(NetResource.lpRemoteName) + ' Error was: 0x' + IntToHex(GetLastError, 8));
        Exit;
      end;
      Entries := DWORD(-1);
      BufferSize := DWORD(16384);
      while ( WNetEnumResource(hEnum, Entries, @NetResourceBuf[0], BufferSize) = NO_ERROR ) do
      begin
        for I := 0 to Entries - 1 do
        begin
          if ( (CompareText(NetResourceBuf[I].lpRemoteName, '\\' + GetLocalComputerName) <> 0) ) then
          begin
            CbxComputerName.Items.Add(NetResourceBuf[I].lpRemoteName)
          end;
        end;
      end;
    finally
      WNetCloseEnum(hEnum);
    end;
  end;
end;

function TfoNetworkConnection.GetWorkgroups: String;
var
  NetResourceBuf, NetResourceBuf2: Array[0..511] of TNetResource;
  I: Integer;
  J: Integer;
  hEnum, hEnum2: THandle;
  Entries: DWORD;
  Entries2: DWORD;
  BufferSize: DWORD;
begin
  if ( WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, nil, hEnum) <> NO_ERROR ) then
  begin
    Exit;
  end;
  Entries := DWORD(-1);
  BufferSize := DWORD(16384);
  while ( WNetEnumResource(hEnum, Entries, @NetResourceBuf[0], BufferSize) = NO_ERROR ) do
  begin
    try
      for I := 0 to Entries - 1 do
      if ( (NetResourceBuf[I].dwUsage and RESOURCEUSAGE_CONTAINER) = RESOURCEUSAGE_CONTAINER) and (Pos('Microsoft Windows', NetResourceBuf[I].lpRemoteName) = 1 ) then
      begin
        try
          if ( WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, @NetResourceBuf[I], hEnum2) <> NO_ERROR ) then
          begin
            ShowMessage('Error enumerating Microsoft Network Resources!');
            Exit;
          end;
          Entries2 := DWORD(-1);
          while ( WNetEnumResource(hEnum2, Entries2, @NetResourceBuf2[0], BufferSize) = NO_ERROR ) do
          begin
            for J := 0 to Entries2 - 1 do
            begin
              CbxWorkgroup.Items.Add(String(NetResourceBuf2[J].lpRemoteName));
            end;
          end;
        finally
          WNetCloseEnum(hEnum2);
        end;
      end;
    finally
      WNetCloseEnum(hEnum);
    end;
  end;
end;
Ich starte die Workgroupsuche mit einem Buttonclick vorerst noch. Was mir jetzt aber aufgefallen ist ist folgendes:
Wenn ich auf den Button das 2...xte mal klicke kommen alle Workgroups 2 mal, 3 mal usw. Eben so oft man auf den Button drueck so oft wird die ComboBox gefuellt. Wie kann ich diese Misere Sinnvoll ausbuegeln?

Danke!

mkinzler 7. Dez 2006 05:48

Re: ComboBox-Eintraege doppelt und x-fach vorhanden
 
Überprüfe vor dem Eintragen, ob der Eintrag schon vorhanden ist ( .IndexOf)

Mackhack 7. Dez 2006 05:51

Re: ComboBox-Eintraege doppelt und x-fach vorhanden
 
Danke!

Loesung war ja zum greifen nahe :cry:

marabu 7. Dez 2006 06:17

Re: ComboBox-Eintraege doppelt und x-fach vorhanden
 
Guten Morgen,

noch ein paar Vorschläge:
  • die Routinen sollten keine Methoden der Form sein, sondern eigenständige Funktionen - mit einer ordentlichen Parameterleiste, damit auf keine Form- oder globalen Variablen zugegriffen werden muss
  • CompareText() <> 0 ist das gleiche wie SameText() - aber nicht so gut lesbar
  • warum auf Vorhandensein eines Eintrags prüfen, wenn doch eine Momentaufnahme gemacht wird? Ich würde beim Eintritt in die Funktion alle eventuell noch vorhandenen Items löschen (Items.Clear).
Freundliche Grüße

Mackhack 7. Dez 2006 06:23

Re: ComboBox-Eintraege doppelt und x-fach vorhanden
 
Hi marabu,

wie meinst du das mit dem 1. Punkt?

Thorben_K 7. Dez 2006 06:28

Re: ComboBox-Eintraege doppelt und x-fach vorhanden
 
er meint das du die funktion auslagern sollst, und statt auf globale variablen zuzugreifen, diese als parameter, ggf var. Damit ist es leichter lessbar, dein problem lösst das aber nicht ;)

marabu 7. Dez 2006 06:38

Re: ComboBox-Eintraege doppelt und x-fach vorhanden
 
Hi,

die Methoden einer Form dienen in erster Linie zur Realisierung der Benutzerschnittstelle. Rein funktionaler Code sollte dort nicht zu finden sein. Vielleicht willst du später mal ein Kommandozeilen-Programm mit einer ähnlichen Funktionalität schreiben. Wäre doch schön, wenn du dann einfach {$I Func.GetNetComputerNames.pas} schreibst und fertig.

Freundliche Grüße

Mackhack 7. Dez 2006 06:42

Re: ComboBox-Eintraege doppelt und x-fach vorhanden
 
Hi marabu,

meinst du ich soll die functions aus der private-Deklaration rausnehmen damit? Steh irgendwie grad auf dem Schlauch :-(

marabu 7. Dez 2006 07:29

Re: ComboBox-Eintraege doppelt und x-fach vorhanden
 
Etwa so habe ich es gemeint:

Delphi-Quellcode:
function GetNetComputerNames(const workGroup: String; list: TStrings): Boolean;
var
  I: Integer;
  hEnum: THandle;
  Entries: DWORD;
  BufferSize: DWORD;
  NetResourceBuf: Array[0..511] of TNetResource;
  NetResource: TNetResource;
begin
  list.Clear;
  NetResource.dwScope := RESOURCE_GLOBALNET;
  NetResource.dwType := RESOURCETYPE_ANY;
  NetResource.dwDisplayType := RESOURCEDISPLAYTYPE_GENERIC;
  NetResource.dwUsage := RESOURCEUSAGE_CONNECTABLE;
  NetResource.lpLocalName := nil;
  NetResource.lpRemoteName := PChar(workGroup);
  NetResource.lpComment := nil;
  NetResource.lpProvider := nil;

  Result := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, @NetResource, hEnum) = NO_ERROR;
  if not Result then Exit;

  Entries := DWORD(-1);
  BufferSize := DWORD(16384);
  while WNetEnumResource(hEnum, Entries, @NetResourceBuf[0], BufferSize) = NO_ERROR do
    for i := 0 to Entries - 1 do
      if not SameText(NetResourceBuf[I].lpRemoteName, '\\' + GetLocalComputerName) then
        list.Add(NetResourceBuf[I].lpRemoteName)
  WNetCloseEnum(hEnum);
end;
Freundliche Grüße

Mackhack 7. Dez 2006 07:33

Re: ComboBox-Eintraege doppelt und x-fach vorhanden
 
Hallo marabu,

ja so waere es ja im Prinzip dann auch raus gekommen. Aber spricht das nicht gegen das OOP die Funktions- und Prozedur-Koepfe nicht in der Deklaration zu verewigen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:32 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz