在網路應用開發中,使用一般 TEdit 輸入 IP 位址存在諸多痛點:無法自動驗證各段範圍 (0-255)、不支援鍵盤導航、需自行處理字串與 32 位整數轉換。Windows 通用控制庫 (comctl32.dll) 內建專業級 IP Address Control (SysIPAddress32),完美解決這些問題,且為系統原生元件,無額外部署負擔。
必須呼叫 InitCommonControlsEx 並指定 ICC_INTERNET_CLASSES 旗標:
#include <commctrl.h>
// 在 WinMain 或 FormCreate 最早處執行
INITCOMMONCONTROLSEX icex = {0};
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_INTERNET_CLASSES;
InitCommonControlsEx(&icex);
// 視窗類別名稱常數:WC_IPADDRESS (定義於 commctrl.h)
HWND hIpEdit = CreateWindowEx(
0, // 擴展樣式
WC_IPADDRESS, // 類別名稱 "SysIPAddress32"
NULL, // 無標題
WS_CHILD | WS_VISIBLE | WS_TABSTOP, // 樣式
10, 10, 150, 25, // 位置與大小
hWndParent, // 父視窗
(HMENU)IDC_IPADDRESS, // 控制項 ID
hInstance, // 應用程式實例
NULL // 建立參數
);
| 訊息常數 | 值 | 功能 | 參數說明 |
|---|---|---|---|
| IPM_CLEARADDRESS | WM_USER+100 | 清空所有欄位 | wParam=0, lParam=0 |
| IPM_SETADDRESS | WM_USER+101 | 設定 IP 位址 | lParam = 32 位 IP 值 (網路序) |
| IPM_GETADDRESS | WM_USER+102 | 取得 IP 位址 | lParam = 指向 DWORD 的指標,回傳非零欄位數 |
| IPM_SETRANGE | WM_USER+103 | 限制單欄位範圍 | wParam=欄位索引(0-3), lParam=LOWORD(上限<<8 | 下限) |
| IPM_SETFOCUS | WM_USER+104 | 設定輸入焦點 | wParam=欄位索引(0-3) |
| IPM_ISBLANK | WM_USER+105 | 檢查是否為空 | 回傳非零=空,零=有內容 |
DWORD dwIP = MAKEIPADDRESS(192, 168, 1, 100); // 宏定義於 commctrl.h
SendMessage(hIpEdit, IPM_SETADDRESS, 0, (LPARAM)dwIP);
DWORD dwIP = 0;
int nFields = (int)SendMessage(hIpEdit, IPM_GETADDRESS, 0, (LPARAM)&dwIP);
if (nFields == 4) {
char szIP[16];
wsprintfA(szIP, "%d.%d.%d.%d",
FIRST_IPADDRESS(dwIP), SECOND_IPADDRESS(dwIP),
THIRD_IPADDRESS(dwIP), FOURTH_IPADDRESS(dwIP));
// 使用 szIP...
}
// 低位元組=下限(10), 高位元組=上限(200)
SendMessage(hIpEdit, IPM_SETRANGE, 0, (LPARAM)(200 << 8 | 10));
if (SendMessage(hIpEdit, IPM_ISBLANK, 0, 0) == 0) {
// 至少有一欄有輸入
DWORD dwIP = 0;
if (SendMessage(hIpEdit, IPM_GETADDRESS, 0, (LPARAM)&dwIP) == 4) {
// 四欄皆已填滿
}
}
當使用者修改任一欄位或焦點移動時觸發,可用於即時驗證或啟用/停用按鈕:
void __fastcall TForm1::WndProc(TMessage &Message) {
if (Message.Msg == WM_NOTIFY) {
LPNMHDR pNMHDR = (LPNMHDR)Message.LParam;
if (pNMHDR->code == IPN_FIELDCHANGED) {
LPNMIPADDRESS pIPAddr = (LPNMIPADDRESS)pNMHDR;
// pIPAddr->iField = 變更的欄位索引 (0-3)
// pIPAddr->iValue = 該欄位新值 (0-255)
// 可在此即時檢查完整性
}
}
TForm::WndProc(Message);
}
FormCreate 或自訂元件建構子HWND 與訊息發送,提供 Text、IPAddress (DWORD)、Range[4] 等屬性comctl32.dll 為系統核心元件 (Win98/IE3 以上內建)| 問題 | 原因 | 解決方案 |
|---|---|---|
| 控件不顯示/建立失敗 | 未呼叫 InitCommonControlsEx 或旗標錯誤 | 確保 ICC_INTERNET_CLASSES 旗標,檢查 GetLastError() |
| GetAddress 回傳欄位數不足 4 | 使用者未填完所有欄位 | 搭配 IPM_ISBLANK 判斷,或視為不完整輸入 |
| 設定範圍無效 | IPM_SETRANGE 參數位元組序錯誤 | 記住:lParam 低位元組=下限,高位元組=上限 |
| 無法在對話方塊模板中直接使用 | 資源編輯器無原生支援 | 運行時動態建立,或建立 ActiveX 包裝元件 |