IP 位址控制項 (CIPAddressCtrl) 是常用 UI 元件,本文分享兩個實用技巧:即時響應欄位變更、程式化設定網段(非完整 IP)。
控制項提供 IPN_FIELDCHANGED 通知,但僅在欄位失焦時觸發。若需每次按鍵即時取得輸入值,可利用其內部編輯控制項的 EN_CHANGE 訊息。
// 標頭檔
afx_msg void OnIpAddressChange();
// 實作檔
ON_EN_CHANGE(1135, OnIpAddressChange)
void CMyDialog::OnIpAddressChange()
{
DWORD dwIp = 0;
m_ipCtrl.GetAddress(dwIp); // 取得目前四欄位值
// 即時驗證、顯示、啟用/停用按鈕等
}
SetAddress 需四個欄位皆指定數值。若想設定「100.6」網段(後兩欄留空),需直接操作 4 個子編輯控制項。
void SetIpAddressCtrlFields(CIPAddressCtrl* pCtrl,
BYTE nField0, BYTE nField1, BYTE nField2, BYTE nField3,
BYTE nFieldCount) // 實際要設定的欄位數 (1-4)
{
if (!pCtrl) return;
pCtrl->ClearAddress();
if (nFieldCount == 0) return;
if (nFieldCount >= 4)
{
pCtrl->SetAddress(nField0, nField1, nField2, nField3);
return;
}
BYTE fields[4] = { nField0, nField1, nField2, nField3 };
HWND hChild = ::GetWindow(pCtrl->m_hWnd, GW_CHILD);
int idx = 3; // 子視窗順序為欄位 3,2,1,0 (由右至左)
while (hChild && idx >= 0)
{
if (idx < nFieldCount)
{
TCHAR szBuf[4] = {0};
_stprintf_s(szBuf, _T("%d"), fields[idx]);
::SetWindowText(hChild, szBuf);
}
hChild = ::GetWindow(hChild, GW_HWNDNEXT);
idx--;
}
}
// 設定 100.6.x.x 網段(前兩欄)
SetIpAddressCtrlFields(&m_ipCtrl, 100, 6, 0, 0, 2);
// 設定單一欄位 192.x.x.x
SetIpAddressCtrlFields(&m_ipCtrl, 192, 0, 0, 0, 1);
SetWindowText 可繞過 SetAddress 的四欄位限制