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

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

[复制链接]
发表于 2004-2-15 13:42:14 | 显示全部楼层 |阅读模式
作者: ccrun ,如转载请保证本文档的完整性,并注明出处。
5 c& a0 Q( w' C$ d1 Z  C+ T8 }欢迎光临 C++ Builder 研究,http://www.ccrun.com/doc/go.asp?id=592) m6 K$ A/ i, G  g
本文是ccrun(老妖)根据偶然间看到的一篇文章略作修改而成。参考资料:. T' E2 Q0 _' I6 x9 F$ U
标题:在Delphi中使用IP控件
4 [; `* N+ T* m* ^3 X  {1 r7 X作者:西安交通大学9649# 刘明华  f( X8 c' h9 y9 h; s. g
在些对原作者的无私奉献表示感谢!如欲转载请保留完整版权信息。3 }1 j+ Z  [0 K3 l) N
如果这篇文章侵犯了您的版权,请来信告诉我们:info@ccrun.com
9 m/ w  T& I; D6 Z, s0 Q* E$ Uccrun(老妖)(www.ccrun.com)  2003.10.29
, T2 M* ^( o7 Z! n! p0 q+ a
( u* m0 l7 C6 N  R在网络程序中,我们常常碰到需要用户输入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控件。) {# H) E9 o. O
. {) Y7 ?0 b% N9 A( S7 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)。
  s% K5 K' s2 f# [! E8 v  I
1 o, N: K4 v( Q3 [# \5 M( U) z●初始化Windows自定义控制库●1 A! @8 F4 x! S1 ?8 z" l' @
Windows提供了两个API函数,InitCommonControls和InitCommonControlsEx,用来初始化自定义控制库。从名字我们不难看出这两个API函数的关系:后者是前者的增强。如果你希望在程序中使用IP控件,你必须用InitCommonControlsEx来完成对自定义控制库以及类的初始化。函数InitCommonControlsEx的原型如下:
7 @* X1 g; Z! w
- _2 i: r" R7 p( V4 z/ T$ n* Ztypedef struct tagINITCOMMONCONTROLSEX {) a5 {- w  l  P$ G. i' B$ d# n
    DWORD dwSize;             // size of this structure: z% a/ g6 z% j4 ~/ o0 B
    DWORD dwICC;              // flags indicating which classes to be initialized: t8 E, {7 O" c- w! N1 C$ w; N
} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;6 w- F0 L0 F1 p8 `2 p8 P  t

0 I* F+ T) Y6 K5 A: a( A. v8 yWINCOMMCTRLAPI BOOL WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX);
. N  p3 j3 L+ j/ `$ y* s) s- z* Q. d- X9 M6 ]
IP控件属于ICC_INTERNET_CLASSES类别的控件,如果要使用该控件,你应该在程序中包含如下的初始化代码:0 S2 K0 j) J0 r& t9 N
1 b- R( r" r: W4 z3 @
TInitCommonControlsEx ICC;
1 a8 Q6 A8 t0 U: S" [5 Z# m$ T2 ZICC.dwSize = sizeof(TInitCommonControlsEx);% M5 s5 k* {9 N- y0 d* }% m
ICC.dwICC  = ICC_INTERNET_CLASSES;
" L* K- s3 r7 P# n  F5 G0 @5 }if(!InitCommonControlsEx(&ICC))
5 ?& y2 t" y/ e8 Z    return;  //初始化组件失败
9 @1 p. P$ P7 s- W6 Z7 }) z) @2 x- u+ M0 l! ?$ e) N8 L( m0 F* Q
●创建IP控件●
" E5 N& A9 o4 ]6 k/ ?/ |Windows API函数CreateWindow或者CreateWindowEx都可以用来创建一个IP控件实例。IP控件的窗口类名为"SysIPAddress32",C++ Builder的commctrl.pas单元为其定义了一个符号常量WC_IPADDRESS。下面这条语句将在Form1上创建一个IP控件。8 p2 }: v1 c6 @/ B$ j- Q
% |% k8 b6 v( ]( V1 ^! h# w
HWND hIpEdit = CreateWindow(WC_IPADDRESS,NULL,WS_CHILD|WS_VISIBLE,10,10,135,47,Handle,0,HInstance,NULL);9 t7 j/ x/ n- c5 m% S
+ w1 }; W/ u/ T+ c
●使用IP控件●
; _9 t0 [5 A  D" u! k! n  J" X9 Z# s在程序中,我们通过向IP控件发送消息来与它通讯。IP控件可以响应的消息有以下6个,这些消息及它们的含义见下表:% J* V' ]" a( r# v! u
' K. r" D/ P8 l- }, Y( o  s
消息常量            消息值         作用                                      参数及返回值0 b8 S) J, U- q* X
IPM_CLEARADDRESS    WM_USER+100    清除IP控件中的IP串                        参数无
) U0 L( ~8 t, i, T% c' V3 CIPM_SETADDRESS      WM_USER+101    设置IP控件的IP串                          Lparam为32位的IP值# v8 }' e; V1 ?
IPM_GETADDRESS      WM_USER+102    获取IP控件中的IP串所对应的IP值(32位整数)  Lparam为一个指向Integer变量的指针。返回值等于IP控件中非控的字段数目;获取到的IP值存放在lparam 所指向的Integer变量中。  
9 }2 E# a" v6 z# e- mIPM_SETRANGE        WM_USER+103    设置IP控件4个部分的其中一个的IP取值范围   Wparam指明要设置取值范围的部分;lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。$ N/ n' A7 P0 M; e; l$ X' p- b4 N- V
IPM_SETFOCUS        WM_USER+104    设输入焦点                                Wparam指明哪个部分获取焦点
+ ~1 V  B3 X4 d6 vIPM_ISBLANK         WM_USER+105    IP串是否为空                              参数无。返回值:若为空,返回非0;不为空,返回0! S1 [! q9 P6 p# |6 I" v' K; {
# b) a* X$ x. `# g# m1 n7 p
★㈠清空IP串(IPM_CLEARADDRESS)★
/ y  ]: e) `! N3 a2 g( JSendMessage(hIpEdit,IPM_CLEARADDRESS,0,0);. C' F7 U  i# P0 x8 f- ]# `
3 I- S" n3 n( ]6 a' f$ L, `
★㈡设置IP串(IPM_SETADDRESS)★
- ?5 ~" P7 b& |int nIP;
' _+ H5 K/ p+ ]; l" z" cnIP=MAKEIPADDRESS(192,168,0,1); ( z* R$ f) w. p6 w. b" Z
SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);
9 F# v  Y+ K: x. L+ w4 |
9 l: z* g  L+ }5 ~此例将IP控件的内容设为"192.168.0.1",其中MAKEIPADDRESS是一个Win32宏,定义在commctrl.h头文件中,它用来合成一个32位的IP值:
2 b# w, ]. a3 U( ?1 Y#define MAKEIPADDRESS(b1,b2,b3,b4)
- i9 o# n/ \; V((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4))))
7 x5 g4 Q* V) W5 U
* g; s9 A' M% A8 d( ?★㈢获取IP值(IPM_GETADDRESS)★, D5 K# A2 \; E+ u
int nIP;6 n  k$ u% K( i9 V! `- J
SendMessage(hIpEdit,IPM_GETADDRESS,0,int(&nIP));
) b- }6 }4 n5 f- w( n//nIP++;0 M" i& d( ]! C" b
//SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);   //将IP加1再赋给IP控件。  N' n. [9 H0 U

! m. A1 z- H' A0 F$ n1 @5 P; c若想要获取IP控件中IP串所对应的IP值,你应该向IP控件发送IPM_GETADDRESS消息,并且需要把一个32位整数的地址作为SendMessage的最后一个参数。! x. ?0 g6 ~! G: t3 D2 r# b5 d
2 B3 p7 }9 V$ s: N% C$ @
★㈣设置取值范围(IPM_SETRANGE)★1 S" Q: f3 P' Z: U1 ]
SendMessage (hIpEdit, IPM_SETRANGE, 0, 200<<8|100);0 v' l* Y2 [# X. w. O/ S
此语句将IP控件的第一部分的范围限制为100~200。在IPM_SETRANGE消息中,Wparam指明要设置的字段, 而lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。$ L8 z5 @' a* b1 j1 ~

# d5 ?. d4 l) d8 m) l7 Q! p★㈤设置输入焦点(IPM_SETFOCUS)★/ e( c, V) R5 ^# q
SendMessage(hIpEdit,IPM_SETFOCUS,3,0);( c% V) m+ z) k  `. q" W  A2 G
//将输入焦点设在IP控件的第四部分。# s" q+ J* B& c$ O
- p. ^% f1 ?8 i  b( p& g" @
㈥判断IP串是否为空(IPM_ISBLANK)) {, F& l; |" S9 @6 f1 _5 b& M1 }2 B' j
if(!SendMessage(hIpEdit,IPM_ISBLANK,0,0))
& o. D+ g3 {1 l5 t; O: n{% t" E+ ]( L; P
    //IP控件中的IP串为空* R. v0 T1 E, w8 Q2 I3 V
}
7 ^# c6 w( L3 ]else
: ]! P0 [% b2 M( O4 d6 g{
2 e& ]( `/ K* [& i    //IP控件中的IP串至少有一部分不是空的4 d$ u) X  f2 q9 z
}
- p: G2 K( P9 t
1 [" X5 h: I  u. @0 @, p●IP控件的通知消息●
2 b4 |2 g  d7 e( S* ]当IP串被改动后或者输入焦点发生了转移,IP控件就会向它的父窗口发送通知消息IPN_FIELDCHANGED。在大多数情况下,我们都可以忽略此通知消息。以下是处理通知消息IPN_FIELDCHANGED的一个示例:
% L) M6 K2 g( ?/ ~+ s& v' Z# G' \+ l9 L6 d( o& U
void __fastcall TForm1::WndProc(TMessage &Msg)
. X/ L4 s8 p: I  D{7 j: T, F  ~/ s; ^5 K$ G
    LPNMHDR p=(LPNMHDR)Msg.LParam;+ u9 w8 Z! w4 Y3 v
    if(Msg.Msg==WM_NOTIFY)1 a, o" w& ^% g' r1 V
    {& s8 H2 [4 E7 l: g! ~2 X
        if(p->code==IPN_FIELDCHANGED)
) N" W8 l- G& b+ l0 U1 O5 W/ w        {+ G$ A/ Z# S7 V! \( @
            //处理IP控件的IPN_FIELDCHANGED通知消息; W: O) z8 I: r6 T: H# A% J& @
        }/ j2 X6 z, X) C/ E# R: Q/ s
    }
+ J- c1 @/ e" }& h    TForm::WndProc(Msg);
; F$ g! [7 z+ O$ |& N+ j1 P}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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