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

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

[复制链接]
发表于 2004-2-15 13:42:14 | 显示全部楼层 |阅读模式
作者: ccrun ,如转载请保证本文档的完整性,并注明出处。
( n& i7 h$ Y! |, l$ C1 E( d欢迎光临 C++ Builder 研究,http://www.ccrun.com/doc/go.asp?id=592& f( Y. O) w8 ^0 K3 O
本文是ccrun(老妖)根据偶然间看到的一篇文章略作修改而成。参考资料:* J7 l) W9 Z% ^! g$ i
标题:在Delphi中使用IP控件! S- [9 D, y4 ^: }
作者:西安交通大学9649# 刘明华9 U2 f) y( ?* R6 p1 p. J
在些对原作者的无私奉献表示感谢!如欲转载请保留完整版权信息。3 Z. o: Z+ y$ u& e  ^/ `8 k
如果这篇文章侵犯了您的版权,请来信告诉我们:info@ccrun.com
0 H/ I1 k( u$ N, [ccrun(老妖)(www.ccrun.com)  2003.10.29! Q: n( ~) z4 A6 }$ G- S

9 {% H2 G+ i) u/ ~在网络程序中,我们常常碰到需要用户输入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控件。
( L4 d8 M% _8 y1 _; J& W- w! ]3 g1 E1 @
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)。" f' V% _/ U$ b
  V2 ^4 N) U  S+ t6 N7 E' C) }
●初始化Windows自定义控制库●# L- f$ a& G  G  I6 h
Windows提供了两个API函数,InitCommonControls和InitCommonControlsEx,用来初始化自定义控制库。从名字我们不难看出这两个API函数的关系:后者是前者的增强。如果你希望在程序中使用IP控件,你必须用InitCommonControlsEx来完成对自定义控制库以及类的初始化。函数InitCommonControlsEx的原型如下:- E) g4 d" a: y7 `# P
& J* m( H. O2 @! P1 S
typedef struct tagINITCOMMONCONTROLSEX {$ o  Z: h! t  ?! G1 U
    DWORD dwSize;             // size of this structure' f# n' W- B8 }& j+ t! L
    DWORD dwICC;              // flags indicating which classes to be initialized/ `% r" K: H" h( r- U6 L
} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;
# u' s9 P- T7 j2 C3 o+ x& {2 {2 H0 \* O3 J& Z
WINCOMMCTRLAPI BOOL WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX);& J1 B9 X5 O6 s. N7 Z. C; g

4 G  y! s" b" y$ _" @* IIP控件属于ICC_INTERNET_CLASSES类别的控件,如果要使用该控件,你应该在程序中包含如下的初始化代码:) P: b' M. o% O  H2 k2 a" _- v
2 c. m2 j! l% B8 t0 g: m! @
TInitCommonControlsEx ICC;
  F; G$ b: `8 |) ]+ [6 @ICC.dwSize = sizeof(TInitCommonControlsEx);
- x# o& J! B6 v3 ^4 |& JICC.dwICC  = ICC_INTERNET_CLASSES;
* d6 Z1 F2 d/ t; J  A8 Gif(!InitCommonControlsEx(&ICC)), T% S, |0 `7 y( u
    return;  //初始化组件失败
9 U' H; j5 g6 e" }" k& S) _# j- P% f9 Q6 ?, b
●创建IP控件●
: ^/ V. l4 d( q: nWindows API函数CreateWindow或者CreateWindowEx都可以用来创建一个IP控件实例。IP控件的窗口类名为"SysIPAddress32",C++ Builder的commctrl.pas单元为其定义了一个符号常量WC_IPADDRESS。下面这条语句将在Form1上创建一个IP控件。
7 S: B; K3 F' A& ?( j' n4 F0 Q. U9 |( g
HWND hIpEdit = CreateWindow(WC_IPADDRESS,NULL,WS_CHILD|WS_VISIBLE,10,10,135,47,Handle,0,HInstance,NULL);, T0 ~' C0 m9 [$ m
' Y7 n+ ~6 E; k9 h
●使用IP控件●
3 u( a, ?& U  C& Y$ M9 N1 N7 d' j在程序中,我们通过向IP控件发送消息来与它通讯。IP控件可以响应的消息有以下6个,这些消息及它们的含义见下表:
) B4 b# \: [. _5 m5 C
) m1 [4 d/ M' E+ o. Z$ J消息常量            消息值         作用                                      参数及返回值' y# A# W) ~: u* t; \) q
IPM_CLEARADDRESS    WM_USER+100    清除IP控件中的IP串                        参数无
) H6 q1 E1 Q& ?IPM_SETADDRESS      WM_USER+101    设置IP控件的IP串                          Lparam为32位的IP值) _$ o% |% ^4 V; K
IPM_GETADDRESS      WM_USER+102    获取IP控件中的IP串所对应的IP值(32位整数)  Lparam为一个指向Integer变量的指针。返回值等于IP控件中非控的字段数目;获取到的IP值存放在lparam 所指向的Integer变量中。  
; k" m- C! v7 O* EIPM_SETRANGE        WM_USER+103    设置IP控件4个部分的其中一个的IP取值范围   Wparam指明要设置取值范围的部分;lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。- Z2 ]8 g* j' x, j5 V( C
IPM_SETFOCUS        WM_USER+104    设输入焦点                                Wparam指明哪个部分获取焦点/ ~% q$ n( o; U. T
IPM_ISBLANK         WM_USER+105    IP串是否为空                              参数无。返回值:若为空,返回非0;不为空,返回0
1 ]) i0 [- R8 J  _' }4 b# \
1 z! N: x7 T- u* H; M/ f2 U★㈠清空IP串(IPM_CLEARADDRESS)★
) [: d4 n9 E- b, h! X9 zSendMessage(hIpEdit,IPM_CLEARADDRESS,0,0);: ^' {) L% a4 n7 s
; y5 r. ^# s* `' \5 w' Z/ J; k6 J
★㈡设置IP串(IPM_SETADDRESS)★
9 F/ M) Y0 e6 n1 Y( y& D5 _4 ~" |int nIP;8 a7 t6 h' g) d* _; P* [  ^$ N0 {$ g
nIP=MAKEIPADDRESS(192,168,0,1); - j+ L% F. s& B5 S: N
SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);  k% d2 N/ |& n' c# z% V

3 g$ e$ x9 K% a/ x% _. m此例将IP控件的内容设为"192.168.0.1",其中MAKEIPADDRESS是一个Win32宏,定义在commctrl.h头文件中,它用来合成一个32位的IP值:
8 g5 ^" I; B0 s. I#define MAKEIPADDRESS(b1,b2,b3,b4)
! b2 b5 B8 l# B) c((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4))))# w1 I2 E/ |+ v
/ J0 [8 P9 b, n" ?5 G6 Q8 I
★㈢获取IP值(IPM_GETADDRESS)★
- ~" A/ A. O, r1 K4 J% ~int nIP;
2 W9 q; x/ S  w5 }SendMessage(hIpEdit,IPM_GETADDRESS,0,int(&nIP));
- E3 W$ S7 ^8 _3 c: r- g//nIP++;0 `" Y+ ]+ ^3 ^, t) W
//SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);   //将IP加1再赋给IP控件。
, ]- R9 k4 i! c; C& I% s* W# [- Q* G1 M* l* @$ m& f1 A7 X
若想要获取IP控件中IP串所对应的IP值,你应该向IP控件发送IPM_GETADDRESS消息,并且需要把一个32位整数的地址作为SendMessage的最后一个参数。5 l! r! S* J! T3 N, X2 ]0 R% T
* n/ g7 h& c; L" y  V
★㈣设置取值范围(IPM_SETRANGE)★
9 ^# y8 Z0 O8 J& vSendMessage (hIpEdit, IPM_SETRANGE, 0, 200<<8|100);# ]$ d: C1 F% _/ ^; V, }- q+ p. i
此语句将IP控件的第一部分的范围限制为100~200。在IPM_SETRANGE消息中,Wparam指明要设置的字段, 而lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。
) n7 t8 ]  v. I! p, P# P5 m' V" y6 J, R5 j6 ~. {: t7 E9 y* q: g
★㈤设置输入焦点(IPM_SETFOCUS)★% |8 O+ ^, c' t4 k' K9 y- }
SendMessage(hIpEdit,IPM_SETFOCUS,3,0);
! U. w. c. p* e% U  e7 s, d2 ~/ E//将输入焦点设在IP控件的第四部分。% v  Q4 N3 W" s1 t

' `! u3 E% ^" W0 Z, t㈥判断IP串是否为空(IPM_ISBLANK)
5 I* Y: X' l8 ^if(!SendMessage(hIpEdit,IPM_ISBLANK,0,0)) 6 Y$ S* I$ i3 L# m$ X) ]
{
: j; d9 W2 B5 Z    //IP控件中的IP串为空8 ^/ S( b9 |: x# i  [9 c4 D
}
# `* d! E( e* f" X# n& A. Relse
) ?  V0 S5 m; f$ l{- _& I7 [0 I& H. N- Y" x
    //IP控件中的IP串至少有一部分不是空的* b  N! L% m5 H- n" o2 Q) }
}* s" o6 E7 z% U/ g/ l$ O% O% ]" ?
: J7 i0 v  X, c: }9 ?. J# `6 _
●IP控件的通知消息●" V5 q- o' O( {6 _) V
当IP串被改动后或者输入焦点发生了转移,IP控件就会向它的父窗口发送通知消息IPN_FIELDCHANGED。在大多数情况下,我们都可以忽略此通知消息。以下是处理通知消息IPN_FIELDCHANGED的一个示例:, T  u: D, v8 h1 d/ h

$ k1 G& T) o$ X% [9 h: t) w$ qvoid __fastcall TForm1::WndProc(TMessage &Msg)
6 f5 j# T2 O% L- {5 ~" E; i/ u{
1 B  t- U( P' K/ B5 R$ I$ [    LPNMHDR p=(LPNMHDR)Msg.LParam;
/ A- D% F: j7 ?. |- A2 Y    if(Msg.Msg==WM_NOTIFY)! x. W4 G) g4 @: k' d
    {
+ X+ V0 n! ~1 @, U        if(p->code==IPN_FIELDCHANGED)
, |8 ?9 ^% Q2 b( G: U        {
* P2 K4 j9 N. c6 K. n            //处理IP控件的IPN_FIELDCHANGED通知消息( g6 I/ W# ]+ B* a  z4 _
        }% f4 a' @- d& b. X' m, i
    }& {* I" n7 n; o( _3 Q4 c
    TForm::WndProc(Msg);; g3 m2 q6 v* G% \* }# W4 \
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-15 10:27 , Processed in 0.017878 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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