在跨平台 GUI 開發中,獲取本機網絡標識(IP 地址、主機名、用戶名)是常見需求。wxWidgets 提供了封裝良好的網絡類 wxIPV4address 和全局函數 wxGetFullHostName()、wxGetUserId(),幾行代碼即可完成。本文提供完整可編譯示例並解析關鍵步驟。
| 類/函數 | 用途 | 所需頭文件 |
|---|---|---|
wxIPV4address | IPv4 地址封裝,支持主機名解析 | <wx/socket.h> |
wxGetFullHostName() | 獲取完整主機名(FQDN 或 NetBIOS 名) | <wx/utils.h> |
wxGetUserId() | 獲取當前用戶名/ID | <wx/utils.h> |
#include
#include // wxIPV4address
#include // wxGetFullHostName, wxGetUserId
class MyFrame : public wxFrame {
public:
MyFrame() : wxFrame(nullptr, wxID_ANY, "系統信息獲取", wxDefaultPosition, wxSize(400, 250)) {
// 初始化 socket 子系統(必須)
wxSocketBase::Initialize();
// 界面佈局
wxPanel* panel = new wxPanel(this);
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
txt_ip = new wxTextCtrl(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
txt_host = new wxTextCtrl(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
txt_user = new wxTextCtrl(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
sizer->Add(new wxStaticText(panel, wxID_ANY, "IP 地址:"), 0, wxALL, 5);
sizer->Add(txt_ip, 0, wxEXPAND | wxALL, 5);
sizer->Add(new wxStaticText(panel, wxID_ANY, "計算機名:"), 0, wxALL, 5);
sizer->Add(txt_host, 0, wxEXPAND | wxALL, 5);
sizer->Add(new wxStaticText(panel, wxID_ANY, "用戶名:"), 0, wxALL, 5);
sizer->Add(txt_user, 0, wxEXPAND | wxALL, 5);
wxButton* btn = new wxButton(panel, wxID_ANY, "獲取信息");
sizer->Add(btn, 0, wxALIGN_CENTER | wxALL, 10);
panel->SetSizer(sizer);
// 綁定事件
btn->Bind(wxEVT_BUTTON, &MyFrame::OnGetInfo, this);
}
~MyFrame() {
wxSocketBase::Shutdown(); // 關閉 socket 子系統
}
private:
wxTextCtrl* txt_ip;
wxTextCtrl* txt_host;
wxTextCtrl* txt_user;
void OnGetInfo(wxCommandEvent& event) {
// 1. 獲取本地計算機名
wxString hostName = wxGetFullHostName();
// 2. 獲取當前用戶名
wxString userName = wxGetUserId();
// 3. 通過主機名解析 IP
wxIPV4address addr;
addr.Hostname(hostName); // 觸發 DNS/本地解析
wxString ipAddr = addr.IPAddress(); // 獲取點分十進制字符串
// 4. 顯示結果
txt_ip->SetValue(ipAddr);
txt_host->SetValue(hostName);
txt_user->SetValue(userName);
}
};
class MyApp : public wxApp {
public:
virtual bool OnInit() {
MyFrame* frame = new MyFrame();
frame->Show(true);
return true;
}
};
wxIMPLEMENT_APP(MyApp);
wxSocketBase::Initialize() 必須在使用任何網絡功能前調用,程序退出時調用 Shutdown()。wxGetFullHostName() 返回 wxString,跨平台自動處理 Windows (GetComputerNameEx) / Unix (gethostname) 差異。addr.Hostname(hostName) 內部調用 getaddrinfo / gethostbyname 進行解析。addr.IPAddress() 返回如 "192.168.1.100" 格式的 wxString。Hostname() 通常返回第一個非環回地址,若需遍歷所有 IP,需使用 wxIPV4address::GetAllAddresses() (wxWidgets 3.1+)。wxIPV6address 類。wxSocketBase::SetFlags(wxSOCKET_NOWAIT) 配合事件循環。ws2_32.lib,CMake 中 find_package(wxWidgets REQUIRED COMPONENTS net)。
find_package(wxWidgets REQUIRED COMPONENTS core base net)
include(${wxWidgets_USE_FILE})
add_executable(SystemInfo main.cpp)
target_link_libraries(SystemInfo ${wxWidgets_LIBRARIES})
wxWidgets 將平台差異封裝在 wxIPV4address、wxGetFullHostName() 等 API 中,開發者無需處理 WSAStartup/gethostbyname 等底層細節,即可輕松獲取本機網絡標識。配合 wxSocketBase 的初始化/清理,構建健壯的跨平台網絡應用更加高效。