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

C++ Builder 使用 Windows 系統 IP 位址輸入控件完整教學

     編輯:關於C++

為什麼需要專用 IP 控件?

在網路應用開發中,使用一般 TEdit 輸入 IP 位址存在諸多痛點:無法自動驗證各段範圍 (0-255)、不支援鍵盤導航、需自行處理字串與 32 位整數轉換。Windows 通用控制庫 (comctl32.dll) 內建專業級 IP Address Control (SysIPAddress32),完美解決這些問題,且為系統原生元件,無額外部署負擔。

核心初始化步驟

1. 初始化通用控制庫

必須呼叫 InitCommonControlsEx 並指定 ICC_INTERNET_CLASSES 旗標:

#include <commctrl.h>

// 在 WinMain 或 FormCreate 最早處執行
INITCOMMONCONTROLSEX icex = {0};
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_INTERNET_CLASSES;
InitCommonControlsEx(&icex);

2. 建立 IP 控件實例

// 視窗類別名稱常數: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_CLEARADDRESSWM_USER+100清空所有欄位wParam=0, lParam=0
IPM_SETADDRESSWM_USER+101設定 IP 位址lParam = 32 位 IP 值 (網路序)
IPM_GETADDRESSWM_USER+102取得 IP 位址lParam = 指向 DWORD 的指標,回傳非零欄位數
IPM_SETRANGEWM_USER+103限制單欄位範圍wParam=欄位索引(0-3), lParam=LOWORD(上限<<8 | 下限)
IPM_SETFOCUSWM_USER+104設定輸入焦點wParam=欄位索引(0-3)
IPM_ISBLANKWM_USER+105檢查是否為空回傳非零=空,零=有內容

實用操作範例

設定 IP 位址 (192.168.1.100)

DWORD dwIP = MAKEIPADDRESS(192, 168, 1, 100); // 宏定義於 commctrl.h
SendMessage(hIpEdit, IPM_SETADDRESS, 0, (LPARAM)dwIP);

取得 IP 位址並轉為字串

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 (私有網段)

// 低位元組=下限(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) {
        // 四欄皆已填滿
    }
}

處理通知訊息 IPN_FIELDCHANGED

當使用者修改任一欄位或焦點移動時觸發,可用於即時驗證或啟用/停用按鈕:

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);
}

C++ Builder 整合技巧

  • 將上述建立碼置於 FormCreate 或自訂元件建構子
  • 建立包裝類別封裝 HWND 與訊息發送,提供 Text、IPAddress (DWORD)、Range[4] 等屬性
  • 專案選項 Linker → Output → Dynamic RTL 需關閉,確保通用控制庫正確連結
  • 部署時無需額外 DLL,comctl32.dll 為系統核心元件 (Win98/IE3 以上內建)

常見陷阱與解決方案

問題原因解決方案
控件不顯示/建立失敗未呼叫 InitCommonControlsEx 或旗標錯誤確保 ICC_INTERNET_CLASSES 旗標,檢查 GetLastError()
GetAddress 回傳欄位數不足 4使用者未填完所有欄位搭配 IPM_ISBLANK 判斷,或視為不完整輸入
設定範圍無效IPM_SETRANGE 參數位元組序錯誤記住:lParam 低位元組=下限,高位元組=上限
無法在對話方塊模板中直接使用資源編輯器無原生支援運行時動態建立,或建立 ActiveX 包裝元件
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved