找回密码
 注册
搜索
查看: 4129|回复: 0

[收藏]使用Windows系统提供的IP控件

[复制链接]
发表于 2004-2-15 13:39:03 | 显示全部楼层 |阅读模式
作者: ccrun ,如转载请保证本文档的完整性,并注明出处。/ p1 x% P: h# a6 ]) w$ t
欢迎光临 C++ Builder 研究,http://www.ccrun.com/doc/go.asp?id=592
: u/ f. R/ C; P/ U& n: E" ]- i3 Q, K# ?本文是ccrun(老妖)根据偶然间看到的一篇文章略作修改而成。参考资料:' a+ S( i3 C4 D. Y% b8 Z, [+ n
标题:在Delphi中使用IP控件
" F9 v% G& C. _# `, m3 Q( I9 o( F, e作者:西安交通大学9649# 刘明华8 t0 c0 \& }! ]3 w- b5 r0 a+ t
在些对原作者的无私奉献表示感谢!如欲转载请保留完整版权信息。' r/ F& J% L0 c2 h
如果这篇文章侵犯了您的版权,请来信告诉我们:info@ccrun.com) w8 M' v- p7 O
ccrun(老妖)(www.ccrun.com)  2003.10.298 b5 @5 S+ B+ K; m& L4 W
2 w# D0 A( V6 p/ z/ h+ \
在网络程序中,我们常常碰到需要用户输入IP地址的情况。然而C++ Builder并没有为我们提供可以用于输入IP串的控件,于是我们只好用TEdit控件(单行文本框)来接受用户输入的IP串。但是,使用TEdit来输入IP串并不是一个好的主意,因为处理起来非常不方便。事实上,在我们的身旁有一个专门用来输入IP串的Windows控件,就象网络链接属性中, Internet 协议 (TCP/IP) 属性中输入IP的控件。IP控件会拒绝非法的IP串(在每个部分只能输入0~255之间的数字);它让你可以轻松地获取控件中的IP串所对应的IP值(32位整数),这省去了IP串和IP值之间相互转换的麻烦;此外,你还能限制IP控件中所能输入的IP的范围。在本文中,我将向大家介绍如何在我们的C++ Builder程序中使用Windows的IP控件。5 ~3 Q* ^# i/ Z( t. t
& N+ b4 S2 [& ?8 g" w
Windows中有两个非常重要的动态联结库:commctrl.dll和comctl32.dll,它们是Windows的自定义控制库(Windows Common Controls)。自定义控制库中包含了许多常用的Windows控件,如Statusbar,Coolbar,HotKey等;在C++ Builder中,这些控件大多数都已被包装成可视化控件了。在Microsoft推出Internet Explorer 3之后,自定义控制库中新增了一些控件,其中就包括Windows的IP控件(IP Address edit control)。
4 U9 U5 ?; A6 K# ^6 T& V1 ^0 B  o/ `* p" a% r
●初始化Windows自定义控制库●6 _8 c3 ]5 `4 K+ R! ~
Windows提供了两个API函数,InitCommonControls和InitCommonControlsEx,用来初始化自定义控制库。从名字我们不难看出这两个API函数的关系:后者是前者的增强。如果你希望在程序中使用IP控件,你必须用InitCommonControlsEx来完成对自定义控制库以及类的初始化。函数InitCommonControlsEx的原型如下:
# G" e5 A0 L0 O/ B$ R, x6 t9 `) M3 k3 z( X
typedef struct tagINITCOMMONCONTROLSEX {9 B, v. p, V( v8 Y
    DWORD dwSize;             // size of this structure
. d% m' ^# v$ h0 g9 K) r  ?% `; L# ~    DWORD dwICC;              // flags indicating which classes to be initialized1 B# C8 v' _5 W% D2 @. F1 p
} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;
0 {2 Q: r; k% N, b5 o
, e- |8 X7 d+ z. A2 IWINCOMMCTRLAPI BOOL WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX);
( i7 b+ ~$ c$ i( G. V- [8 l% x% y* \; r6 Q
IP控件属于ICC_INTERNET_CLASSES类别的控件,如果要使用该控件,你应该在程序中包含如下的初始化代码:
* B) ]+ N8 W6 A3 @8 ~! s1 g' |$ q  {5 H  A! ^/ t8 M: O
TInitCommonControlsEx ICC;! j4 c6 m& K* \( A9 j# Z$ |/ C, Y
ICC.dwSize = sizeof(TInitCommonControlsEx);/ R! Z. y# x8 v2 L5 F
ICC.dwICC  = ICC_INTERNET_CLASSES;
2 I( P* p. p/ g1 K7 k- ^  Z# jif(!InitCommonControlsEx(&ICC))
( s8 Y+ ?+ J- V    return;  //初始化组件失败
, d8 i8 r* w$ `0 M% N9 ~  c- D" Y# j  P. C/ H5 _
●创建IP控件●' [7 E$ M) t$ D4 A' S
Windows API函数CreateWindow或者CreateWindowEx都可以用来创建一个IP控件实例。IP控件的窗口类名为"SysIPAddress32",C++ Builder的commctrl.pas单元为其定义了一个符号常量WC_IPADDRESS。下面这条语句将在Form1上创建一个IP控件。9 W4 d/ `2 U3 N- J. E: F

" e0 l1 T2 J0 v7 KHWND hIpEdit = CreateWindow(WC_IPADDRESS,NULL,WS_CHILD|WS_VISIBLE,10,10,135,47,Handle,0,HInstance,NULL);  [* I9 w) |4 m% T, N, Z9 G" t" I
  x9 t! i6 |: m! O4 `, \% Y" S
●使用IP控件●
& E$ X3 a: L3 o8 Y! @- S9 v在程序中,我们通过向IP控件发送消息来与它通讯。IP控件可以响应的消息有以下6个,这些消息及它们的含义见下表:: K) c. o6 V. i. D8 W/ Y
) \" I& r5 ]! ~. u: R6 D
消息常量            消息值         作用                                      参数及返回值( T! q  \! _7 n3 R
IPM_CLEARADDRESS    WM_USER+100    清除IP控件中的IP串                        参数无- R& e& H; E# Q/ O
IPM_SETADDRESS      WM_USER+101    设置IP控件的IP串                          Lparam为32位的IP值4 w6 \9 S$ U: s$ Q* B: A, C
IPM_GETADDRESS      WM_USER+102    获取IP控件中的IP串所对应的IP值(32位整数)  Lparam为一个指向Integer变量的指针。返回值等于IP控件中非控的字段数目;获取到的IP值存放在lparam 所指向的Integer变量中。  
) o2 t3 r( e4 s( N$ aIPM_SETRANGE        WM_USER+103    设置IP控件4个部分的其中一个的IP取值范围   Wparam指明要设置取值范围的部分;lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。2 X) m9 O8 A# j6 |! Z9 w
IPM_SETFOCUS        WM_USER+104    设输入焦点                                Wparam指明哪个部分获取焦点: U& j+ a; ~# P; p
IPM_ISBLANK         WM_USER+105    IP串是否为空                              参数无。返回值:若为空,返回非0;不为空,返回05 w' L& W' K6 R3 \: O
% B0 |7 }8 M0 Z- u. {6 k
★㈠清空IP串(IPM_CLEARADDRESS)★
- S1 w, i' u+ J9 ^# Q7 b+ L1 R, ASendMessage(hIpEdit,IPM_CLEARADDRESS,0,0);5 Q, Q2 a* W; F+ i" m0 }

5 n  q/ z; X7 p8 v! R$ U★㈡设置IP串(IPM_SETADDRESS)★2 `# X/ v# [5 j% e- y
int nIP;
! B1 h" B, Z9 b4 s8 l9 J, \+ vnIP=MAKEIPADDRESS(192,168,0,1);
7 _) y+ w5 w: J% w$ h3 N$ x3 f) aSendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);
9 h! {3 E8 B7 d* J* p7 n3 Q; A; i  k) ~
此例将IP控件的内容设为"192.168.0.1",其中MAKEIPADDRESS是一个Win32宏,定义在commctrl.h头文件中,它用来合成一个32位的IP值:, X4 j* s2 y+ n( k
#define MAKEIPADDRESS(b1,b2,b3,b4)
1 K- F$ L4 L/ x: I, ?6 W3 {7 a((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4))))+ s" w) W3 E) _, h3 p2 ]7 W
/ U+ Q! L* ~- ^/ d8 w, k8 {
★㈢获取IP值(IPM_GETADDRESS)★
* t2 w/ w# W* i- `! `) G; pint nIP;
2 y% O/ ^4 W  fSendMessage(hIpEdit,IPM_GETADDRESS,0,int(&nIP));, q$ ], V7 t6 ]8 Z2 |/ R4 f
//nIP++;' t- \5 S! o8 n1 x+ B  ^' ~2 Z
//SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);   //将IP加1再赋给IP控件。
  o) N; p( y4 B) F" A. V
2 H. d4 s: p" B6 A) m- A0 K5 N若想要获取IP控件中IP串所对应的IP值,你应该向IP控件发送IPM_GETADDRESS消息,并且需要把一个32位整数的地址作为SendMessage的最后一个参数。) a; S4 q" g; J6 K# U
8 M  u. ]5 ~  V; Q% V+ J- H
★㈣设置取值范围(IPM_SETRANGE)★7 ]; R) L. T3 E3 N  f
SendMessage (hIpEdit, IPM_SETRANGE, 0, 200<<8|100);
; ?$ ~/ \8 {' i" H此语句将IP控件的第一部分的范围限制为100~200。在IPM_SETRANGE消息中,Wparam指明要设置的字段, 而lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。3 m6 o8 r( h0 J

. H! R, }- G' t# B9 _★㈤设置输入焦点(IPM_SETFOCUS)★, `8 S6 F' G! X' ^$ `
SendMessage(hIpEdit,IPM_SETFOCUS,3,0);
! w- l) e0 b" ]7 n% \# [, O! b//将输入焦点设在IP控件的第四部分。
2 h* o) V# G6 W4 h# k0 \# V1 F
7 ?7 h' A/ q# c2 Q6 P2 |) V. f㈥判断IP串是否为空(IPM_ISBLANK)8 R/ z3 s) Z7 b  e& {: ~- B
if(!SendMessage(hIpEdit,IPM_ISBLANK,0,0))
6 |8 Q2 x1 z/ d. |4 U: d1 d2 C" K{  U2 N5 [1 I6 F5 ^
    //IP控件中的IP串为空
2 W- e- o$ d/ \' u6 c, G* K) |}+ {) l5 G  w7 s" \) [, M
else( ~* H7 y0 `2 [4 S
{* Q( A2 c6 j* r; o! V- w- r
    //IP控件中的IP串至少有一部分不是空的
4 G; i# r' M; H; K: \}
) t7 R, q2 I/ ~$ o( [1 z* ?
7 D! l1 Z; U+ J. K6 w* ^- ~●IP控件的通知消息●* @" {* d6 e/ _2 L3 X$ l3 _
当IP串被改动后或者输入焦点发生了转移,IP控件就会向它的父窗口发送通知消息IPN_FIELDCHANGED。在大多数情况下,我们都可以忽略此通知消息。以下是处理通知消息IPN_FIELDCHANGED的一个示例:; [- ^) E0 a) E. d

8 z6 }; ~+ O* D( yvoid __fastcall TForm1::WndProc(TMessage &Msg)
% F" g" s! m& v{
  C& V4 I. X. |8 A    LPNMHDR p=(LPNMHDR)Msg.LParam;8 S3 }$ I- A& N2 g6 b
    if(Msg.Msg==WM_NOTIFY)
8 a. }9 L* g; {    {
/ M0 v* N) K3 C+ g        if(p->code==IPN_FIELDCHANGED). i3 W. b. d+ v; t- f7 f, \
        {& n8 ^* S4 i9 ?' u- Z/ _; l# u3 R
            //处理IP控件的IPN_FIELDCHANGED通知消息9 k0 m" x3 w7 i+ d
        }
6 Z3 N" U) i) z3 H3 O! M1 p. r0 f    }
( {1 L9 `. X8 Y1 g# D    TForm::WndProc(Msg);6 H/ b3 b# A3 C# [' h; `
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2026-6-18 08:52 , Processed in 0.017916 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表