Hallo,
ich versuche eine GUI zu programmieren zum folgenden Beitrag:
http://www.tutorials.de/forum/c-c-tutorials/117448-c-windows-netzwerk-durchsuchen-teil-1-a.html
Das Programm als Konsolenanwedung klappt wunderbar, jedoch mit GUI komm ich ins stottern. Wahrscheinlich zu wenig Hintergrundwissen....
Meine Vorgehensweise:
1. Erstelle eine neue VCL -Formularanwendung (Borland C++ Builder) (Oberfläche mit einem Button als Auslöser, ComboBoxEx zur Auswahl der Domänen und CheckListBox für die einzelnen Rechner, die An- oder Abgewählt werden können, zur Weiterverarbeitung gedacht)
2. Binde Dateien (netscan.cpp und netscan.h) im Projekt ein
netscan.h
nescan.cpp
3.main.cpp versuche ich in meine Unit1.cpp zu integrieren:
Unit1.cpp
Erste rot markierte Zeile ist der Auslöser und dann folgen meine Änderungen in dem ich versuche die Ausgabe (statt cout)in ShowMessage oder ComboBoxEx zuumwandeln:
ComboBoxEx1->Items->Text=iter->first;
So und beim Compilieren kommt schon ein Fehler:
Konvertierung von 'const string' nach 'UnicodeString' nicht möglich
So wie kann ich das am besten lösen? Ist meine Vorgehensweise falsch?
ich versuche eine GUI zu programmieren zum folgenden Beitrag:
http://www.tutorials.de/forum/c-c-tutorials/117448-c-windows-netzwerk-durchsuchen-teil-1-a.html
Das Programm als Konsolenanwedung klappt wunderbar, jedoch mit GUI komm ich ins stottern. Wahrscheinlich zu wenig Hintergrundwissen....
Meine Vorgehensweise:
1. Erstelle eine neue VCL -Formularanwendung (Borland C++ Builder) (Oberfläche mit einem Button als Auslöser, ComboBoxEx zur Auswahl der Domänen und CheckListBox für die einzelnen Rechner, die An- oder Abgewählt werden können, zur Weiterverarbeitung gedacht)
2. Binde Dateien (netscan.cpp und netscan.h) im Projekt ein
netscan.h
Code:
#ifndef NETSCAN_H
#define NETSCAN_H
//#error !! Bitte das Projekt gegen die mpr.lib linken ==> dann diese Zeile löschen
#include <windows.h>
#include <string>
#include <map>
#include <winerror.h>
using namespace std;
typedef map<string,string> StringToString;
typedef void (*func)(void *, DWORD, string);
class NetworkBase
{
public:
bool NetScan(StringToString* dic,
void* obj,
func eh,
string resource="",
DWORD displaytype = RESOURCEDISPLAYTYPE_GENERIC,
DWORD type = RESOURCETYPE_ANY,
LPNETRESOURCE lpnr=NULL);
};
Code:
#include "netscan.h"
bool NetworkBase::NetScan(StringToString* dic,
void* obj,
func eh,
string resource,
DWORD displaytype,
DWORD type,
LPNETRESOURCE lpnr)
{
DWORD dwResult, dwResultEnum;
HANDLE hEnum;
DWORD cbBuffer = 16384;
DWORD cEntries = -1;
LPNETRESOURCE lpnrLocal;
DWORD i;
// wenn wir eine Resource übergeben, dann erstellen wir und eine
// NETRECOURCE Struktur
if(lpnr == NULL && !resource.empty())
{
NETRESOURCE rec;
rec.dwScope = RESOURCE_GLOBALNET;
rec.dwType = type;
rec.dwDisplayType = displaytype;
// wenn wir nach einer Freigabe oder nach einem Netzwerkdrucker suchen
if( (type == RESOURCETYPE_DISK) || (type == RESOURCETYPE_PRINT) )
rec.dwUsage = RESOURCEUSAGE_CONNECTABLE;
else
rec.dwUsage = RESOURCEUSAGE_CONTAINER;
rec.lpLocalName = NULL;
rec.lpComment = NULL;
rec.lpProvider = NULL;
rec.lpRemoteName = (char *)resource.c_str();
lpnr = &rec;
}
// open the enumeration of network
dwResult = WNetOpenEnum(RESOURCE_GLOBALNET, // alle Netzwerkressourcen
type, // alle Ressources
0, // enumerate alle Ressources
lpnr, // die vordefinierte Ressource z.B. ein Server zum scannen seiner Shares
&hEnum ); // handle zu der Resource
if(dwResult != NO_ERROR)
{
eh(obj, dwResult, "");
return false; // Error Handling
}
// start enumeration
// Schleife bis the enumeration keine Items mehr findet
do
{
// Speicher für das struct-array allokieren
lpnrLocal = new NETRESOURCE[cbBuffer];
// es konnte kein Speicher allokiert werden
if(!lpnrLocal)
{
eh(obj, 0, "Speicher allokieren fehlgeschlagen");
return false;
}
// denn Speicher auf 0 setzen
ZeroMemory(lpnrLocal, cbBuffer);
// Das Netzwerk enumieren und die Ressourcen raus holen
dwResultEnum = WNetEnumResource(hEnum, // resource handle
&cEntries, // auf -1 vorbelegt
lpnrLocal, // Zeiger auf die lokale Struktur
&cbBuffer); // Puffergröße
// wenn kein Fehler auf getreten ist ( es wurden Ressourcen gefunden
if (dwResultEnum == NO_ERROR)
{
// Die Ressourcen iterieren, die in dieser Ebene gefunden wurden
for(i = 0; i < cEntries; i++)
{
// hier holen wir die Daten raus
string name = "";
string comment = "";
if(lpnrLocal[i].lpRemoteName)
name= (char*)lpnrLocal[i].lpRemoteName;
if(lpnrLocal[i].lpComment)
comment= (char*)lpnrLocal[i].lpComment;
// Überprüfen, ob die Resource ein Container ist
if(RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage & RESOURCEUSAGE_CONTAINER))
{
// jetzt überprüfen wir ob die Ressource der angegebenen Ebene von <displaytype> entspricht
if(displaytype == lpnrLocal[i].dwDisplayType)
{
// wir ersetzten alle Backslashes durch nichts fals vorhanden
while(name.find("\\") != string::npos)
name.replace(name.find("\\"), strlen("\\"), "");
//jetzt fügen wir die gefundene Resource in unsere map ein
dic->insert(StringToString::value_type(name, comment));
}
// wenn die Resource nicht userer eben entspricht, aber trotzdem ein Conteiner ist (s.o.)
// dann rufen wir die NetScan-Funktion rekursiv auf
else
{
if(!NetScan(dic, obj, eh, name, displaytype, type, &lpnrLocal[i] ))
{
eh(obj, 0, "NetScan fehlgeschlagen");
}
}
}
else
{
// Wenn die Resource kein Container ist (evtl. eine Datenfreigabe oder Drucker
// dann überprüfen wir trotzdem, ob sie der angegebenen Ebene enspricht
// denn dann können wir sie in die map einfügen
if(displaytype == lpnrLocal[i].dwDisplayType)
{
// wir entfernen zunächst den Rechnernamen
if(name.find(resource) != string::npos)
name.replace(name.find(resource), resource.size(), "");
//dann entfernen wir wieder alle Backslashes
while(name.find("\\") != string::npos)
name.replace(name.find("\\"), strlen("\\"), "");
// Schließlich können wir die Resource in die map einfügen
dic->insert(StringToString::value_type(name, comment));
}
}
}
}
else if (dwResultEnum != ERROR_NO_MORE_ITEMS)
{
// löschen des arrays
delete[] lpnrLocal;
eh(obj, dwResultEnum, "");
// ein Fehler ist in dieser Ebene aufgetreten wir brechen die Schleife ab
break;
}
// löschen des arrays
delete[] lpnrLocal;
}
while(dwResultEnum != ERROR_NO_MORE_ITEMS); // ende der Schleife
// schließen der Enumeration
dwResult = WNetCloseEnum(hEnum);
if(dwResult != NO_ERROR)
{
eh(obj, dwResult, "");
return false;
}
return true;
}
Unit1.cpp
Code:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "netscan.cpp"
#include "netscan.h"
#include <iostream>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void ErrorHandling(void*, DWORD error, string errortext);
void __fastcall TForm1::Button1Click(TObject *Sender)
{
StringToString dic;
// der Iterator der für die Map
StringToString::iterator iter;
bool ret;
NetworkBase net;
/*
* Domain suchen
*/
// hier holen wir uns die domains/workgroups
ret = net.NetScan(&dic, NULL, &ErrorHandling, "", RESOURCEDISPLAYTYPE_DOMAIN);
if(!ret)
{
ShowMessage((NULL, 0, "NetScan fehlgeschlagen"));
exit;
//return -1;
}
// wurden domains gefunden ?
if(!dic.size())
{
ShowMessage("Keine Domains/Wourkgroups gefunden");
exit;
//return -1;
}
// iterate der domains und ausgeben
iter = dic.begin();
//cout << "Folgende Domains gefunden:" << endl;
while(iter != dic.end())
{
ShowMessage(iter->first);
cout << "Domain: " << iter->first << " | Kommentar: " << iter->second << endl;
iter++;
}
// wir speichern uns die 1. domain
iter = dic.begin();
string firstDomain = iter->first;
// dann löschen wir die map
ComboBoxEx1->Items->Text=iter->first;
dic.clear();
/*
* Rechner in der 1. Domain suchen
*/
// nun holen wir uns die Rechner aus der 1. Domain
cout << "\n\nRechner aus " << firstDomain << ":" << endl;
// aufruf der NetScan-Funktion mit der 1. Domain
ret = net.NetScan(&dic, NULL, &ErrorHandling, firstDomain, RESOURCEDISPLAYTYPE_SERVER);
if(!ret)
{
ErrorHandling(0, NULL, "NetScan fehlgeschlagen");
exit;
//return -1;
}
// wurden Rechner gefunden
if(!dic.size())
{
cout << "Keine Rechner in " << firstDomain << " gefunden" << endl;
exit;
//return -1;
}
// wenn ja dann ausgeben
iter = dic.begin();
cout << "\nFolgende Rechner in " << firstDomain << " gefunden:" << endl;
while(iter != dic.end())
{
cout << "Rechner: " << iter->first << " | Kommentar: " << iter->second << endl;
iter++;
}
// wir speichern uns den 1. Rechner
iter = dic.begin();
string firstServer = iter->first;
// dann löschen wir die map
dic.clear();
}
void ErrorHandling(void*, DWORD error, string errortext)
{
cout << " FEHLER ";
if(error)
cout << "-> Fehlernummer: " << error << endl;
if(errortext.empty())
cout << "Hier koennte jetzt noch eine Beschreibung des Fehlers stehen\n" << endl;
else
cout << "-> " << errortext << endl;
}
Erste rot markierte Zeile ist der Auslöser und dann folgen meine Änderungen in dem ich versuche die Ausgabe (statt cout)in ShowMessage oder ComboBoxEx zuumwandeln:
ComboBoxEx1->Items->Text=iter->first;
So und beim Compilieren kommt schon ein Fehler:
Konvertierung von 'const string' nach 'UnicodeString' nicht möglich
So wie kann ich das am besten lösen? Ist meine Vorgehensweise falsch?
Zuletzt bearbeitet: