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

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

[复制链接]
发表于 2004-2-15 13:39:03 | 显示全部楼层 |阅读模式
作者: ccrun ,如转载请保证本文档的完整性,并注明出处。
2 f4 x, Q6 {8 m5 k2 f0 Y& S欢迎光临 C++ Builder 研究,http://www.ccrun.com/doc/go.asp?id=592( K! B9 `+ ^, c$ N; J( [& m
本文是ccrun(老妖)根据偶然间看到的一篇文章略作修改而成。参考资料:" k! d3 M( n* `) k) X
标题:在Delphi中使用IP控件
; e+ O2 x6 t2 I* O+ e' ]" A作者:西安交通大学9649# 刘明华; }5 v) C" o! M; c9 d' P, L
在些对原作者的无私奉献表示感谢!如欲转载请保留完整版权信息。
8 S. }; b0 f$ v+ `' w" g% I如果这篇文章侵犯了您的版权,请来信告诉我们:info@ccrun.com5 @6 f9 Z1 D* z0 E4 K& i2 {5 g/ n
ccrun(老妖)(www.ccrun.com)  2003.10.29! q  {2 D+ E; ~' u
/ a( W5 w4 s. I4 @
在网络程序中,我们常常碰到需要用户输入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 b: g  @% y4 q& a

9 {" f; C- I) Q5 ?1 AWindows中有两个非常重要的动态联结库:commctrl.dll和comctl32.dll,它们是Windows的自定义控制库(Windows Common Controls)。自定义控制库中包含了许多常用的Windows控件,如Statusbar,Coolbar,HotKey等;在C++ Builder中,这些控件大多数都已被包装成可视化控件了。在Microsoft推出Internet Explorer 3之后,自定义控制库中新增了一些控件,其中就包括Windows的IP控件(IP Address edit control)。/ W) j% H- A" [" O8 ]" E

6 Q) `0 I! y4 F: b' m# a/ ?●初始化Windows自定义控制库●
  i- E. u, V2 A; W3 q9 E* lWindows提供了两个API函数,InitCommonControls和InitCommonControlsEx,用来初始化自定义控制库。从名字我们不难看出这两个API函数的关系:后者是前者的增强。如果你希望在程序中使用IP控件,你必须用InitCommonControlsEx来完成对自定义控制库以及类的初始化。函数InitCommonControlsEx的原型如下:
3 ~) b  c5 N1 s! j1 |: H! q8 @& O+ a
1 ~9 y: b3 t# P+ N/ K- I9 ?6 _typedef struct tagINITCOMMONCONTROLSEX {/ R% w0 J2 G6 _4 P8 Q# z" _) q
    DWORD dwSize;             // size of this structure
- a5 x* S* T* E    DWORD dwICC;              // flags indicating which classes to be initialized
6 \9 a4 z0 d& q} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;
6 `0 R1 j- h4 x9 g8 E) v$ r1 H* {; {+ G5 j5 }$ u2 y5 ?' ^1 s
WINCOMMCTRLAPI BOOL WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX);% d; q8 Z) ^; A' s3 _3 Q8 L
9 k1 ~+ k/ V2 d9 A3 S
IP控件属于ICC_INTERNET_CLASSES类别的控件,如果要使用该控件,你应该在程序中包含如下的初始化代码:
0 j3 U) ?: c% Q& {! Z) z
: i6 j: ^2 z+ S7 I8 O* Q8 RTInitCommonControlsEx ICC;. g0 d4 q- T- Q1 q
ICC.dwSize = sizeof(TInitCommonControlsEx);
; @) c% [' e$ m) N. W2 _ICC.dwICC  = ICC_INTERNET_CLASSES;
. x4 x  h" P; p. m+ ~if(!InitCommonControlsEx(&ICC))
) l) ]7 |! w% |$ r0 s6 {. o    return;  //初始化组件失败3 o5 p, e* c9 ?6 F6 b5 A& W

( `8 O& B7 }1 {4 c0 R4 X●创建IP控件●3 C" ?: a& P; X6 m4 W! v
Windows API函数CreateWindow或者CreateWindowEx都可以用来创建一个IP控件实例。IP控件的窗口类名为"SysIPAddress32",C++ Builder的commctrl.pas单元为其定义了一个符号常量WC_IPADDRESS。下面这条语句将在Form1上创建一个IP控件。
- }6 S: w" \' n6 _9 s; ~/ P9 Y8 c, ^0 n1 W
HWND hIpEdit = CreateWindow(WC_IPADDRESS,NULL,WS_CHILD|WS_VISIBLE,10,10,135,47,Handle,0,HInstance,NULL);) T' A- u) m9 H, k

2 Q( d+ J8 _' |/ W9 e& ~●使用IP控件●
4 w& R4 ?  \0 C5 t  a" {在程序中,我们通过向IP控件发送消息来与它通讯。IP控件可以响应的消息有以下6个,这些消息及它们的含义见下表:$ R. Q5 q* ]. I( h( y/ v

3 E; k2 k# Q- |1 ^% L( D: t; k: s消息常量            消息值         作用                                      参数及返回值# a; t- X* v- Z
IPM_CLEARADDRESS    WM_USER+100    清除IP控件中的IP串                        参数无; ~- }, [+ E8 o/ [' W4 v; \
IPM_SETADDRESS      WM_USER+101    设置IP控件的IP串                          Lparam为32位的IP值
& A8 q* [- e* E0 n& yIPM_GETADDRESS      WM_USER+102    获取IP控件中的IP串所对应的IP值(32位整数)  Lparam为一个指向Integer变量的指针。返回值等于IP控件中非控的字段数目;获取到的IP值存放在lparam 所指向的Integer变量中。  
7 F, p+ q. @, ^IPM_SETRANGE        WM_USER+103    设置IP控件4个部分的其中一个的IP取值范围   Wparam指明要设置取值范围的部分;lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。
$ l/ E- i2 l# r% S4 \: a/ bIPM_SETFOCUS        WM_USER+104    设输入焦点                                Wparam指明哪个部分获取焦点
7 \" I+ ]# A( e1 z, C5 w. `( t7 m3 VIPM_ISBLANK         WM_USER+105    IP串是否为空                              参数无。返回值:若为空,返回非0;不为空,返回0. j7 u- T7 i+ M4 m! p; l, T

( ^- D4 ]9 K9 U★㈠清空IP串(IPM_CLEARADDRESS)★
. f6 g1 y& |. o+ {. ^SendMessage(hIpEdit,IPM_CLEARADDRESS,0,0);. @+ \. j6 ?3 M% N) q

# G/ `* E! }1 Z0 Y( w. \/ B★㈡设置IP串(IPM_SETADDRESS)★2 e# J% o. A* u- Y; G+ K. B# _  q6 J
int nIP;
7 \1 v" G; P/ p" a  ]" h/ S: dnIP=MAKEIPADDRESS(192,168,0,1); * a; Q) r) }& E8 Q2 j/ ^# d/ I
SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);# ]' {8 z6 f# ?9 t5 P$ L# u
* J9 @* _6 l  Y1 j, }
此例将IP控件的内容设为"192.168.0.1",其中MAKEIPADDRESS是一个Win32宏,定义在commctrl.h头文件中,它用来合成一个32位的IP值:
0 H9 Z8 E4 o3 B: X- W#define MAKEIPADDRESS(b1,b2,b3,b4)
( @+ w' p+ M9 C; d2 \+ q((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4))))
3 q# n3 `4 C- C& c8 P( z, c
# c1 h: d; ^5 C★㈢获取IP值(IPM_GETADDRESS)★
! y5 c: Y) x- Q* m7 bint nIP;
+ Q3 @" K9 m& L! J7 r$ bSendMessage(hIpEdit,IPM_GETADDRESS,0,int(&nIP));
: ~- Q- E; v( a" y: c  K//nIP++;
% |1 M! r7 `, c//SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);   //将IP加1再赋给IP控件。
& [, E  Q. h% F) |) D; y4 g" t+ N4 L
若想要获取IP控件中IP串所对应的IP值,你应该向IP控件发送IPM_GETADDRESS消息,并且需要把一个32位整数的地址作为SendMessage的最后一个参数。
2 r% ]- l( _4 e0 K3 V" ]; X( R" z% J( H& z
★㈣设置取值范围(IPM_SETRANGE)★
( N) r2 S7 k+ D3 f# P! n' n) Y) sSendMessage (hIpEdit, IPM_SETRANGE, 0, 200<<8|100);
, @4 s8 [. W/ F* M+ r此语句将IP控件的第一部分的范围限制为100~200。在IPM_SETRANGE消息中,Wparam指明要设置的字段, 而lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。; L# Y! \8 r- S% O, P$ O0 ~0 k
7 @* M$ |7 F0 V# F6 N+ g* N; m
★㈤设置输入焦点(IPM_SETFOCUS)★
5 M, F9 G' R# o2 RSendMessage(hIpEdit,IPM_SETFOCUS,3,0);% X* U; n, `6 x. \% A
//将输入焦点设在IP控件的第四部分。
6 Z% G3 @9 O9 b0 z. w& S! k5 u! V8 V6 e! z' ]
㈥判断IP串是否为空(IPM_ISBLANK)" P8 _5 N2 h2 j+ \
if(!SendMessage(hIpEdit,IPM_ISBLANK,0,0)) . }! |  ?: X. o4 i/ Y7 f! R; r# C
{! w* u  S% H! e" f7 {; |8 d
    //IP控件中的IP串为空
) h' p" Y, u2 u8 Y$ r}
3 E8 s6 s+ x9 j* x; S6 I; velse
. \; Q) v! S9 Y( e$ A{. p$ ?0 d- F; n- S7 b) y6 Z
    //IP控件中的IP串至少有一部分不是空的
; t) {+ P! Z2 _& j+ o$ u}' A$ ^/ W8 e/ K. v6 Q, d! {% R% W' l( |

8 Q0 [2 E( m3 ?2 Z5 w5 j, d& ^: p●IP控件的通知消息●& m: p/ T+ B) V; l# `; g; g$ ^1 i
当IP串被改动后或者输入焦点发生了转移,IP控件就会向它的父窗口发送通知消息IPN_FIELDCHANGED。在大多数情况下,我们都可以忽略此通知消息。以下是处理通知消息IPN_FIELDCHANGED的一个示例:
7 {" V+ K1 {- Z0 n5 |$ @, ]6 [8 p. }+ J' A7 L7 b
void __fastcall TForm1::WndProc(TMessage &Msg)
1 K0 b9 C7 T; Q{% t$ r7 @% \& y) [; z. Z) g
    LPNMHDR p=(LPNMHDR)Msg.LParam;
8 ~+ w5 z  ?. l2 o    if(Msg.Msg==WM_NOTIFY)( I* p* \& V& e' U- o  j3 O
    {* M* n& l0 D7 b6 {4 A5 N
        if(p->code==IPN_FIELDCHANGED)
" x9 J& H' s" A3 i* H1 Y        {/ x1 r+ k- I( l8 A+ P
            //处理IP控件的IPN_FIELDCHANGED通知消息
6 j8 A0 a. b0 s) D9 k7 l        }. |/ t/ {) F$ K3 O! k' L
    }* E, P* O+ e( G+ b
    TForm::WndProc(Msg);9 n" N( j3 H% P% l) y) Y7 p# H
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 09:03 , Processed in 0.018041 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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