首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC++ 列表框枚舉顯示網上鄰居完整實現

     編輯:關於VC++

需求背景

CodeGuru 等網站雖有網絡鄰居枚舉類封裝,但對初學者理解底層原理不利。本文將核心邏輯直接實現於對話框類中,代碼直觀、無封裝干擾,適合學習 Windows 網絡 API 基礎。

核心 API 與結構

  • WNetOpenEnum:開啟枚舉句柄
  • WNetEnumResource:枚舉網絡資源
  • WNetCloseEnum:關閉枚舉句柄
  • NETRESOURCE:資源描述結構
  • 需連結 mpr.lib,包含 winnetwk.h

遞歸枚舉完整代碼

BOOL CNetEnum2Dlg::Enumerate(LPNETRESOURCE lpNetRC_p) {
    HANDLE hEnum = 0;
    DWORD dwScope = RESOURCE_GLOBALNET;
    DWORD dwType = RESOURCETYPE_ANY;
    DWORD dwResult = WNetOpenEnum(dwScope, dwType, 0, lpNetRC_p, &hEnum);
    if (dwResult != NO_ERROR) return FALSE;

    DWORD dwBuffer = 16384; // 16KB 緩衝區
    DWORD dwEntries = 0xFFFFFFFF; // 枚舉所有項目
    LPNETRESOURCE lpnrLocal = 0;
    BOOL bRet = TRUE;

    do {
        lpnrLocal = (LPNETRESOURCE)GlobalAlloc(GPTR, dwBuffer);
        dwResult = WNetEnumResource(hEnum, &dwEntries, lpnrLocal, &dwBuffer);
        
        if (dwResult == NO_ERROR) {
            for (DWORD i = 0; i < dwEntries; i++) {
                CString nsname;
                nsname = lpnrLocal[i].lpRemoteName;
                nsname += _T(" ");
                nsname += lpnrLocal[i].lpLocalName;
                nsname += _T(" ");
                nsname += lpnrLocal[i].lpComment;
                m_netList.AddString(nsname); // CListBox 成員變數

                // 遞歸進入容器類資源(非伺服器)
                if ((lpnrLocal[i].dwUsage & RESOURCEUSAGE_CONTAINER) &&
                    lpnrLocal[i].dwDisplayType != RESOURCEDISPLAYTYPE_SERVER) {
                    if (!Enumerate(&lpnrLocal[i])) return FALSE;
                }
            }
        } else if (dwResult != ERROR_NO_MORE_ITEMS) {
            return FALSE;
        }
    } while (dwResult != ERROR_NO_MORE_ITEMS);

    if (lpnrLocal) GlobalFree((HGLOBAL)lpnrLocal);
    WNetCloseEnum(hEnum);
    return bRet;
}

void CNetEnum2Dlg::OnListWNet() {
    Enumerate(0); // 從根開始枚舉
}

關鍵技術點解析

  1. 緩衝區管理:每次循環 GlobalAlloc/GlobalFree 避免記憶體洩漏
  2. 遞歸終止條件:ERROR_NO_MORE_ITEMS 表示枚舉完成
  3. 容器判斷:RESOURCEUSAGE_CONTAINER 標識可進入的資源(如共享資料夾),排除伺服器節點防止無限遞歸
  4. 資源類型:RESOURCETYPE_ANY 涵蓋磁碟、印表機等所有類型

界面整合

  • 對話框放置 CListBox m_netList(關聯 IDC_LIST)
  • 按鈕「枚舉網絡」綁定 OnListWNet
  • 編譯需在 Project Settings → Link → Object/library modules 加入 mpr.lib

常見問題與解決

現象原因對策
枚舉結果為空網絡未啟用/無共享資源檢查「網上鄰居」可見性、啟用檔案共享服務
Access Denied權限不足以管理員身份運行、檢查網絡存取權限
遞歸死循環未正確過濾伺服器節點嚴格判斷 dwDisplayType != RESOURCEDISPLAYTYPE_SERVER

總結

本實現直觀展示 Windows 網絡枚舉核心流程:開啟枚舉 → 分配緩衝 → 循環讀取 → 遞歸容器 → 釋放資源。代碼可直接移植至專案,或作為封裝類的基礎參考。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved