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

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

[复制链接]
发表于 2004-2-15 13:39:03 | 显示全部楼层 |阅读模式
作者: ccrun ,如转载请保证本文档的完整性,并注明出处。" ^- e6 T; l. p  d
欢迎光临 C++ Builder 研究,http://www.ccrun.com/doc/go.asp?id=592
' l0 y3 j& ^0 y  T6 P6 N! _8 Y本文是ccrun(老妖)根据偶然间看到的一篇文章略作修改而成。参考资料:
0 k1 m+ r: u" O) F" u, @7 e' s- Z" b标题:在Delphi中使用IP控件+ U3 K; d" _* [4 s
作者:西安交通大学9649# 刘明华
, J, x" c, s  _# Q+ b: x* K/ L在些对原作者的无私奉献表示感谢!如欲转载请保留完整版权信息。1 b' I! ^5 q# B4 z, W8 a4 M4 y
如果这篇文章侵犯了您的版权,请来信告诉我们:info@ccrun.com6 q+ I. G, ^! E5 e, C
ccrun(老妖)(www.ccrun.com)  2003.10.29
, q2 ~" S, ^1 ~* b) d
1 C  o7 s8 K5 E" U- J在网络程序中,我们常常碰到需要用户输入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控件。
4 ^, k+ u# _1 H* Z7 U  l& X, _  G  H
+ Y2 f( J- S+ c5 [5 W' Q: YWindows中有两个非常重要的动态联结库:commctrl.dll和comctl32.dll,它们是Windows的自定义控制库(Windows Common Controls)。自定义控制库中包含了许多常用的Windows控件,如Statusbar,Coolbar,HotKey等;在C++ Builder中,这些控件大多数都已被包装成可视化控件了。在Microsoft推出Internet Explorer 3之后,自定义控制库中新增了一些控件,其中就包括Windows的IP控件(IP Address edit control)。
: _- {) }7 l8 A( E3 s# ]9 A
/ C2 Z) z" i; v& W: y8 ^. V●初始化Windows自定义控制库●
; t9 A5 ^" \% K7 @/ ~- I. V* ZWindows提供了两个API函数,InitCommonControls和InitCommonControlsEx,用来初始化自定义控制库。从名字我们不难看出这两个API函数的关系:后者是前者的增强。如果你希望在程序中使用IP控件,你必须用InitCommonControlsEx来完成对自定义控制库以及类的初始化。函数InitCommonControlsEx的原型如下:
& Z) H7 _3 I4 C6 m  l! O5 L  T7 }6 J$ j% h+ z+ ^1 |3 s
typedef struct tagINITCOMMONCONTROLSEX {
7 F7 d7 T7 j- l: E    DWORD dwSize;             // size of this structure: G) |; }/ I" B
    DWORD dwICC;              // flags indicating which classes to be initialized" o' Z* C+ j' E) z2 z* T
} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;0 F/ A  U1 i) W1 T! j. ]! v/ c' f2 @* X
, r/ H/ I( G% ]: N- M
WINCOMMCTRLAPI BOOL WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX);
: m0 c# U# B5 a% B& f9 V5 v$ t; U; @1 a  n8 w
IP控件属于ICC_INTERNET_CLASSES类别的控件,如果要使用该控件,你应该在程序中包含如下的初始化代码:8 D2 e5 J) d' J* p  K. P
  e% O$ B/ A4 u. _
TInitCommonControlsEx ICC;' r* v+ ^1 m2 d, K9 D2 U- m
ICC.dwSize = sizeof(TInitCommonControlsEx);
9 ]2 G9 D0 ]0 J4 z! @. ]# tICC.dwICC  = ICC_INTERNET_CLASSES;
: _# o1 R; r4 `7 Dif(!InitCommonControlsEx(&ICC))
1 v, ?  Q% K$ n3 P: I0 M    return;  //初始化组件失败0 {) P2 A; J3 S' g5 m

  Y1 {1 A) R2 a6 r3 y( w' ~●创建IP控件●
  x* e7 q5 K$ O3 u* pWindows API函数CreateWindow或者CreateWindowEx都可以用来创建一个IP控件实例。IP控件的窗口类名为"SysIPAddress32",C++ Builder的commctrl.pas单元为其定义了一个符号常量WC_IPADDRESS。下面这条语句将在Form1上创建一个IP控件。2 S5 F3 n- R7 l. \5 f
2 K7 J: {! R2 K% f2 W' l
HWND hIpEdit = CreateWindow(WC_IPADDRESS,NULL,WS_CHILD|WS_VISIBLE,10,10,135,47,Handle,0,HInstance,NULL);
( u: k$ `2 @; y- \
0 k* a+ Z4 d) T1 N●使用IP控件●
1 V5 e9 e( b: F在程序中,我们通过向IP控件发送消息来与它通讯。IP控件可以响应的消息有以下6个,这些消息及它们的含义见下表:
8 W! V$ I* H( p- g. S+ U
$ B2 j1 C8 V2 y) |7 I% d0 }6 \消息常量            消息值         作用                                      参数及返回值0 K) ^1 W2 U; {* v7 k
IPM_CLEARADDRESS    WM_USER+100    清除IP控件中的IP串                        参数无
( x; o/ J& j4 s  ~. r6 zIPM_SETADDRESS      WM_USER+101    设置IP控件的IP串                          Lparam为32位的IP值
2 Q4 i9 M9 T- @0 }8 x- d, }IPM_GETADDRESS      WM_USER+102    获取IP控件中的IP串所对应的IP值(32位整数)  Lparam为一个指向Integer变量的指针。返回值等于IP控件中非控的字段数目;获取到的IP值存放在lparam 所指向的Integer变量中。  7 }# |0 ~- S! |# ~
IPM_SETRANGE        WM_USER+103    设置IP控件4个部分的其中一个的IP取值范围   Wparam指明要设置取值范围的部分;lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。
+ v. s5 P9 z* b: ]- zIPM_SETFOCUS        WM_USER+104    设输入焦点                                Wparam指明哪个部分获取焦点
$ T' ?, B# Q5 P" v4 P1 TIPM_ISBLANK         WM_USER+105    IP串是否为空                              参数无。返回值:若为空,返回非0;不为空,返回0
& q: g# W: W/ Y0 R0 ~' t5 u6 u& s. u" H9 N
★㈠清空IP串(IPM_CLEARADDRESS)★- N6 ~2 a! a: x' |+ c7 ^! B+ x. o
SendMessage(hIpEdit,IPM_CLEARADDRESS,0,0);
5 H9 z0 z7 g/ t. H: G, Y2 ^) P" A
★㈡设置IP串(IPM_SETADDRESS)★
2 v( ]3 O* d( ~7 Z9 @. r  }7 Hint nIP;; b) b+ k. T3 n  {4 \
nIP=MAKEIPADDRESS(192,168,0,1);   P6 L: h% P& \5 E( l+ S+ f; [* I' i6 ^
SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);
  q$ b  W" L9 {. y/ J8 y) a/ o4 L% c8 F7 w
此例将IP控件的内容设为"192.168.0.1",其中MAKEIPADDRESS是一个Win32宏,定义在commctrl.h头文件中,它用来合成一个32位的IP值:
9 c2 F' }3 E! u6 n#define MAKEIPADDRESS(b1,b2,b3,b4)
- |/ p2 G/ W7 n7 ~: D% v/ _((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4))))2 i: z( v( m) k- V; ?4 O

5 F4 A: Z! W( E7 b, x" t★㈢获取IP值(IPM_GETADDRESS)★
( E/ F4 E& M. ^: A0 Y5 M. I& c2 kint nIP;
( S& R, k* ^9 Q/ m# c6 U2 eSendMessage(hIpEdit,IPM_GETADDRESS,0,int(&nIP));
9 O4 i9 @- I7 m7 x//nIP++;; ]! f$ {2 q) a% T0 j' R
//SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);   //将IP加1再赋给IP控件。
6 t, C& d. Z# {$ E* p/ A+ o& M# l7 N% x! g$ f6 V3 e+ }
若想要获取IP控件中IP串所对应的IP值,你应该向IP控件发送IPM_GETADDRESS消息,并且需要把一个32位整数的地址作为SendMessage的最后一个参数。9 a1 o; G. H# M0 W/ P8 k( H/ O$ o
9 {) i" u8 d0 u0 P; @
★㈣设置取值范围(IPM_SETRANGE)★
: p$ Q( H- ?4 }7 k' t2 c; GSendMessage (hIpEdit, IPM_SETRANGE, 0, 200<<8|100);* f7 @, Z. h7 D# U
此语句将IP控件的第一部分的范围限制为100~200。在IPM_SETRANGE消息中,Wparam指明要设置的字段, 而lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。: m; _2 u! w6 c3 S, s1 M
$ F) N* j% L1 z- e9 O1 `3 x
★㈤设置输入焦点(IPM_SETFOCUS)★
' ^3 r8 @. d( f) `: vSendMessage(hIpEdit,IPM_SETFOCUS,3,0);
4 Q1 Y2 X' ~% H7 o9 |' l8 I//将输入焦点设在IP控件的第四部分。1 p4 X7 @7 Z1 [; C/ X) G9 `4 T

8 x; u# \) K3 V  C㈥判断IP串是否为空(IPM_ISBLANK)5 T; [  t- A' w0 H/ [. P  f
if(!SendMessage(hIpEdit,IPM_ISBLANK,0,0))
, s9 Y' R- N; h7 C- w5 x) ]- g{
: q0 R6 f+ r/ t    //IP控件中的IP串为空
' D' C/ v0 s0 M: W" S$ k+ L- a2 Y}8 G! H; k  v: D; A2 s) c' K
else
+ Z! k1 i4 o6 z+ k% ~, `# \. m0 O{
" y9 u$ R% m( S+ R  f& G8 P    //IP控件中的IP串至少有一部分不是空的
8 \2 I2 w! I; Q7 S0 w. G}
3 K  t; b8 X8 _8 U- w/ X; e7 C% `7 K+ f# h* d' K3 z6 a- |% n
●IP控件的通知消息●
4 D# ^# A) }, Q+ _% i当IP串被改动后或者输入焦点发生了转移,IP控件就会向它的父窗口发送通知消息IPN_FIELDCHANGED。在大多数情况下,我们都可以忽略此通知消息。以下是处理通知消息IPN_FIELDCHANGED的一个示例:: i2 S9 X0 R. Y4 r! y+ K, _

' P% w6 [$ u. o; L, V. gvoid __fastcall TForm1::WndProc(TMessage &Msg)$ e! V2 ~. W  _% \
{+ X9 ?, C! }# f. A3 @' c/ B# q" q& x
    LPNMHDR p=(LPNMHDR)Msg.LParam;
2 l+ `$ R" i- p9 U- i' F" }6 B5 X    if(Msg.Msg==WM_NOTIFY)
+ R0 O6 d6 |: y8 e- ^# L    {- G) x( v7 Q8 L
        if(p->code==IPN_FIELDCHANGED)
8 Q' I' N: x5 N/ H7 L        {4 v3 e3 R/ _$ S- R6 v  Y& L; W
            //处理IP控件的IPN_FIELDCHANGED通知消息4 L& Q  Q9 p9 h& }' P4 e; `
        }$ |& h$ g3 m1 |
    }
5 f3 q0 J, C( x6 P7 X" A- t    TForm::WndProc(Msg);
2 _+ Q) x7 n1 X$ U7 {" ^; f# C}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 16:27 , Processed in 0.017039 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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