本例实现的是检索局域网内的计算机。
编程思路:
首先,由于本例实现的是检索局域网内的计算机,所以首先加入网络的支持,在对框类的头文件中包含“winsock2.h”,在工程设置对话框中连接ws2_32.lib和mpr.lib.
其次,调用WSAStarup,加载所需要的WinsockDLL版本,随后调用WnetEnumResource对网络资源做枚举,之后调用gethostname获得主机名,然后通过主机名,调用gethostbyname获得主机名对应的相关数据。并在函数的结尾部分调用WSACleanup卸载Winsock DLL.具体步骤如下:
即先向对话框中加入一个列表框和一个按钮控件,修改其ID分别为ID_LIST和ID_ENUM
在“VIEW/类向导”中,为检索按钮添加消息映射函数OnEnum();
为对话框类CMyDlg添加成员函数EnumHosts(CString& list).此函数用来枚举网内的计算机信息
添加代码如下:
void CMyDlg::EnumHosts(CStringArray &list)
{
//先清空列表
list.RemoveAll();
CString strTemp;
struct hostent *host;
struct in_addr *ptr; //获得IP地址
DWORD dwScope=RESOURCE_CONTEXT;
NETRESOURCE *NetResource=NULL;
HANDLE hEnum;//定义句柄
WNetOpenEnum(dwScope,NULL,NULL,NULL,&hEnum);//启动对网络资源进行枚举
WSADATA wsaData;//这个结构被用来存储被WSAStartup函数调用后返回的 Windows Sockets数据。它包含Winsock.dll执行的数据。
//开始枚举网络资源
if(hEnum) //如果句柄有效
{
DWORD Count=0xFFFFFFFF;
DWORD BufferSize=2048;
LPVOID Buffer=new char[2048];
//调用WSAStartup后调用WNetEnumResource做进一步的枚举工作
WNetEnumResource(hEnum,&Count,Buffer,&BufferSize);
NetResource=(NETRESOURCE*)Buffer;
char szHostName[200];
for(unsigned int i=0;i<BufferSize/sizeof(NETRESOURCE);i++,NetResource++)
{
if(NetResource->dwUsage==RESOURCEUSAGE_CONTAINER&&NetResource->dwType==RESOURCETYPE_ANY)
{
if(NetResource->lpRemoteName)
{
CString strFullName=NetResource->lpRemoteName;
if(0==strFullName.Left(2).Compare("\\\\"))
strFullName=strFullName.Right(strFullName.GetLength()-2);
//获得主机名
gethostname(szHostName,strlen(szHostName));
//由主机名获得跟它对应的主机信息
host=gethostbyname(strFullName);
if(host==NULL) continue;
ptr=(struct in_addr*)host->h_addr_list[0];
//提取IP地址信息,地址形式如下:211.40.35.76
int a=ptr->S_un.S_un_b.s_b1;
int b=ptr->S_un.S_un_b.s_b2;
int c=ptr->S_un.S_un_b.s_b3;
int d=ptr->S_un.S_un_b.s_b4;
strTemp.Format("%s-->%d.%d.%d.%d",strFullName,a,b,c,d);
//加入到链表中
list.Add(strTemp);
}
}
}
delete Buffer;
//结束枚举工作
WNetCloseEnum(hEnum);
}
//卸载Winsock.dll
WSACleanup();
}
然后在给“检索”按钮添加映射函数代码:
void CMyDlg::OnEnum()
{
// TODO: Add your control notification handler code here
//从开始枚举后使枚举按钮变灰
GetDlgItem(IDC_ENUM)->EnableWindow(FALSE);
//调用枚举函数进行枚举操作
CStringArray list;
EnumHosts(list);
//显示枚举结果
CListBox* pList=(CListBox*)GetDlgItem(IDC_LIST);
pList->ResetContent();
pList->AddString("检索结果如下:");
for(int i=0;i<list.GetSize();i++)
pList->AddString(list.GetAt(i));
//枚举完毕使枚举按钮有效
GetDlgItem(IDC_ENUM)->EnableWindow(TRUE);
}