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

在 C++ Builder 中使用 Windows 系統 IP 地址控件 (SysIPAddress32)

     編輯:關於C語言

為什麼需要 IP 地址控件

網絡程序頻繁需要用戶輸入 IPv4 地址。用普通 TEdit 不僅需自行驗證格式(四段 0-255),還要手動處理字符串與 32 位整數的轉換。Windows 內置的 IP Address Edit Control (SysIPAddress32) 完美解決這些問題:自動校驗、直接獲取/設置 32 位值、支持分段範圍限制。

初始化公共控件庫

IP 控件屬於 ICC_INTERNET_CLASSES 類,必須調用 InitCommonControlsEx 初始化:

#include <commctrl.h>
// 在 WinMain 或 FormCreate 最早處調用
INITCOMMONCONTROLSEX icc = {0};
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_INTERNET_CLASSES;
if (!InitCommonControlsEx(&icc)) {
    // 初始化失敗處理
    return;
}

注意: 僅調用 InitCommonControls 不會載入 IE3+ 新增的網絡類控件。

創建控件

使用 CreateWindowEx,窗口類名為 WC_IPADDRESS (定義在 commctrl.h,值為 "SysIPAddress32"):

HWND hIpEdit = CreateWindowEx(
    0, WC_IPADDRESS, NULL,
    WS_CHILD | WS_VISIBLE | WS_TABSTOP,
    10, 10, 135, 25,  // 位置、大小
    hwndParent,       // 父窗口
    (HMENU)IDC_IPADDRESS, // 控件 ID
    hInstance, NULL
);

在 C++ Builder 中,可在 FormCreate 動態創建,或放置一個 TPanel 後用 SetParent 移入。

核心消息交互 (WM_USER + 100~105)

消息常量值用途參數/返回
IPM_CLEARADDRESSWM_USER+100清空所有字段wParam/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低16位: 高字節=上限,低字節=下限
IPM_SETFOCUSWM_USER+104設置輸入焦點到指定字段wParam=字段索引(0-3)
IPM_ISBLANKWM_USER+105判斷是否全空返回非0=全空,0=有內容

常用操作封裝示例

// 宏:構造 32 位 IP 值 (網絡字節序)
#define MAKEIPADDRESS(b1,b2,b3,b4) \
    ((DWORD)(((DWORD)(b1)<<24) | ((DWORD)(b2)<<16) | ((DWORD)(b3)<<8) | (DWORD)(b4)))

// 設置 IP: 192.168.1.100
DWORD ip = MAKEIPADDRESS(192, 168, 1, 100);
SendMessage(hIpEdit, IPM_SETADDRESS, 0, (LPARAM)ip);

// 獲取 IP
DWORD ipOut = 0;
int fieldCount = SendMessage(hIpEdit, IPM_GETADDRESS, 0, (LPARAM)&ipOut);
if (fieldCount == 4) {
    // 解析四段
    int b1 = (ipOut >> 24) & 0xFF;
    int b2 = (ipOut >> 16) & 0xFF;
    int b3 = (ipOut >> 8) & 0xFF;
    int b4 = ipOut & 0xFF;
}

// 限制第一段為 100~200
SendMessage(hIpEdit, IPM_SETRANGE, 0, (LPARAM)MAKELONG(100, 200)); // 低字節=下限,高字節=上限

// 清空
SendMessage(hIpEdit, IPM_CLEARADDRESS, 0, 0);

// 判斷是否為空
if (SendMessage(hIpEdit, IPM_ISBLANK, 0, 0)) {
    ShowMessage("IP 不能為空");
}

處理通知消息

用戶修改字段或焦點移動時,控件向父窗口發送 WM_NOTIFY,NMHDR::code == IPN_FIELDCHANGED:


// 在表單的 WndProc 或消息映射中處理
void __fastcall TForm1::WndProc(TMessage &Message) {
    if (Message.Msg == WM_NOTIFY) {
        LPNMHDR pNMHDR = (LPNMHDR)Message.LParam;
        if (pNMHDR->code == IPN_FIELDCHANGED && pNMHDR->hwndFrom == hIpEdit) {
            // 實時驗證、聯動更新等
            DWORD ip; SendMessage(hIpEdit, IPM_GETADDRESS, 0, (LPARAM)&ip);
            // ...
        }
    }
    TForm::WndProc(Message);
}

遷移到 VCL 組件

若不想直接用 API,可將上述邏輯封裝為繼承自 TCustomControl 的 TIPAddressEdit 組件,發布 IPAddress (DWORD)、Range[4] 等屬性,並在 CreateParams 中指定 WC_IPADDRESS,實現設計時拖放使用。

總結

Windows IP 控件是處理 IPv4 輸入的「瑞士軍刀」:原生、無依賴、功能完備。掌握 InitCommonControlsEx 初始化與六條核心消息,即可在任何 Win32 框架(C++ Builder、MFC、WTL、純 SDK)中高效集成。

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