找回密码
 注册
查看: 4206|回复: 0

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

[复制链接]
发表于 2004-2-15 13:39:03 | 显示全部楼层 |阅读模式
作者: ccrun ,如转载请保证本文档的完整性,并注明出处。3 E6 b$ U7 r7 t3 u- |7 h& t
欢迎光临 C++ Builder 研究,http://www.ccrun.com/doc/go.asp?id=592
0 [; `- G3 V! `$ M' x8 F0 f本文是ccrun(老妖)根据偶然间看到的一篇文章略作修改而成。参考资料:2 s0 P8 n, }# K4 a
标题:在Delphi中使用IP控件1 q1 a+ R; m6 n
作者:西安交通大学9649# 刘明华4 U' y( j2 U$ P) y* \
在些对原作者的无私奉献表示感谢!如欲转载请保留完整版权信息。
3 u6 R7 f  O4 o: M7 Y如果这篇文章侵犯了您的版权,请来信告诉我们:info@ccrun.com
: t/ q/ Q) a- n$ `* D9 e0 j* N& kccrun(老妖)(www.ccrun.com)  2003.10.29# o" @% b/ N" V* B3 I8 Y
  I$ p$ ~+ A! l3 U& _9 M; ]  L
在网络程序中,我们常常碰到需要用户输入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控件。
$ R7 j- K5 g+ o0 }7 \4 {- H; p' t9 r5 k
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)。
5 O2 D; ?3 r/ [
* g0 E& V- Y" v  ~2 t●初始化Windows自定义控制库●
. d0 K6 A4 y  W1 _& z, `9 G+ \# i8 mWindows提供了两个API函数,InitCommonControls和InitCommonControlsEx,用来初始化自定义控制库。从名字我们不难看出这两个API函数的关系:后者是前者的增强。如果你希望在程序中使用IP控件,你必须用InitCommonControlsEx来完成对自定义控制库以及类的初始化。函数InitCommonControlsEx的原型如下:) Q+ \1 t1 j$ g& m" l
$ U' _  q1 e; b6 X: g
typedef struct tagINITCOMMONCONTROLSEX {5 E1 {0 G! E7 B4 U2 ~" K
    DWORD dwSize;             // size of this structure. F+ z! i' e. R
    DWORD dwICC;              // flags indicating which classes to be initialized4 s% U3 {9 d2 y  Q, Z1 |
} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;, O; C2 W( {4 U  b1 t
" i) v4 Y6 I' j3 e5 T( w3 k
WINCOMMCTRLAPI BOOL WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX);
4 l8 |, |" i3 Z9 H! }1 G
+ _; u* ^9 B8 k6 mIP控件属于ICC_INTERNET_CLASSES类别的控件,如果要使用该控件,你应该在程序中包含如下的初始化代码:8 M: I5 f/ |% k' W# H3 V! X/ h0 J

3 n0 A5 g7 k1 ?4 d7 l) S3 gTInitCommonControlsEx ICC;) L- P& m1 @  e: U1 j1 K
ICC.dwSize = sizeof(TInitCommonControlsEx);5 x0 ~- E5 K! r" }/ z3 K
ICC.dwICC  = ICC_INTERNET_CLASSES;
+ p( F% p7 C$ ~* vif(!InitCommonControlsEx(&ICC)): r0 r* U/ F, p6 a% g) S: m
    return;  //初始化组件失败
5 j" Y7 X. |+ x. _7 ?) _" H4 Q& d5 I3 ]* @8 Z
●创建IP控件●; D" H0 N* s7 V+ }3 I3 K
Windows API函数CreateWindow或者CreateWindowEx都可以用来创建一个IP控件实例。IP控件的窗口类名为"SysIPAddress32",C++ Builder的commctrl.pas单元为其定义了一个符号常量WC_IPADDRESS。下面这条语句将在Form1上创建一个IP控件。
3 p. U6 ^; y) R5 x' z2 v
8 u, @" Q# s# OHWND hIpEdit = CreateWindow(WC_IPADDRESS,NULL,WS_CHILD|WS_VISIBLE,10,10,135,47,Handle,0,HInstance,NULL);
4 M9 l; \' V: _* Q5 S
7 E, ?* }* N" {; u- w& w7 j●使用IP控件●
; f) f7 c( Z6 {* y1 f在程序中,我们通过向IP控件发送消息来与它通讯。IP控件可以响应的消息有以下6个,这些消息及它们的含义见下表:
8 v7 `# o5 E0 y. [$ e
0 _" R4 D! A' ^) {消息常量            消息值         作用                                      参数及返回值
% f  W  H$ O3 Y8 SIPM_CLEARADDRESS    WM_USER+100    清除IP控件中的IP串                        参数无( w# a6 N  {1 F& v8 L
IPM_SETADDRESS      WM_USER+101    设置IP控件的IP串                          Lparam为32位的IP值# _7 w4 Y& ~, I8 q8 |! R
IPM_GETADDRESS      WM_USER+102    获取IP控件中的IP串所对应的IP值(32位整数)  Lparam为一个指向Integer变量的指针。返回值等于IP控件中非控的字段数目;获取到的IP值存放在lparam 所指向的Integer变量中。  ' x! O- k, r5 x$ W0 X1 F+ n. f
IPM_SETRANGE        WM_USER+103    设置IP控件4个部分的其中一个的IP取值范围   Wparam指明要设置取值范围的部分;lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。% i# U- |# |  q9 e
IPM_SETFOCUS        WM_USER+104    设输入焦点                                Wparam指明哪个部分获取焦点5 ]8 b/ O/ S9 w" U0 e6 c
IPM_ISBLANK         WM_USER+105    IP串是否为空                              参数无。返回值:若为空,返回非0;不为空,返回0
3 @2 X7 {) ?$ }* b6 I: B8 K/ i9 R1 ?" c( H$ O
★㈠清空IP串(IPM_CLEARADDRESS)★. Z8 C( Y2 c8 {! J
SendMessage(hIpEdit,IPM_CLEARADDRESS,0,0);
! H+ j0 Q, f4 w2 ]7 T0 U3 l! r
! \; U0 v# q. t& B★㈡设置IP串(IPM_SETADDRESS)★
. M& K! p+ B# u& `, u2 Y  V" sint nIP;: o7 b: s: f( G' ^
nIP=MAKEIPADDRESS(192,168,0,1);
. m0 @: g& k: W( y* xSendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);2 h" d1 D3 V9 H3 m- o2 _
" m: G8 c1 h, s" }
此例将IP控件的内容设为"192.168.0.1",其中MAKEIPADDRESS是一个Win32宏,定义在commctrl.h头文件中,它用来合成一个32位的IP值:
, `9 Y, y# o$ ~: X#define MAKEIPADDRESS(b1,b2,b3,b4)
. ?7 n" k0 @- G4 E' v((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4))))
# I7 p& M9 M2 I9 g
2 N2 u" }1 I5 P, M3 \★㈢获取IP值(IPM_GETADDRESS)★" G. p2 q$ |$ T
int nIP;
- U. f! f4 F% P1 U' s4 e' o. Y- |SendMessage(hIpEdit,IPM_GETADDRESS,0,int(&nIP));
5 V4 t: J* S4 B! ]9 p, Z/ ]: K//nIP++;
. i% c2 R4 g  U. G# s8 M+ w//SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);   //将IP加1再赋给IP控件。
6 I8 e* u& l4 w$ R# Q5 f5 C
# n5 _# m" z+ g/ A若想要获取IP控件中IP串所对应的IP值,你应该向IP控件发送IPM_GETADDRESS消息,并且需要把一个32位整数的地址作为SendMessage的最后一个参数。
5 Y$ k& _& h4 A) l& I6 _0 _& v
- ]$ h( W5 m: ^1 B' Z3 X# p★㈣设置取值范围(IPM_SETRANGE)★
; y' a7 ^+ C# M5 B6 n& N& H3 LSendMessage (hIpEdit, IPM_SETRANGE, 0, 200<<8|100);
- `9 R3 G" d; x8 T7 U* z此语句将IP控件的第一部分的范围限制为100~200。在IPM_SETRANGE消息中,Wparam指明要设置的字段, 而lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。
) W# f# G! m  y/ }: A# `$ S( b4 K5 l' c9 V7 b
★㈤设置输入焦点(IPM_SETFOCUS)★
- ~2 h4 B  V) R, C. A. iSendMessage(hIpEdit,IPM_SETFOCUS,3,0);4 v9 b2 N5 q9 c( s/ O# v& O
//将输入焦点设在IP控件的第四部分。1 Y) G$ d! B7 J  K9 S9 M
' T9 W% P, V5 e" T4 v
㈥判断IP串是否为空(IPM_ISBLANK)4 f1 p; l; ]2 {
if(!SendMessage(hIpEdit,IPM_ISBLANK,0,0))
' M% S  J! C8 o0 u9 |0 L1 ^8 ^{9 a2 b9 T: ~+ e1 A' V
    //IP控件中的IP串为空
  J8 g$ r( n6 Z- z. l, N% v, r2 S}$ z9 F& c8 G5 @0 P
else
" O& R/ W7 V% n8 N7 J{
* ^! t+ a) o) A    //IP控件中的IP串至少有一部分不是空的  y5 l: d' k4 }5 j5 w+ a0 q) \
}
/ Q6 Z! N6 K8 x4 }6 R: z
  W( G+ b6 F1 D9 r* _4 _5 Y●IP控件的通知消息●
, j) S7 B  d2 r  B( I当IP串被改动后或者输入焦点发生了转移,IP控件就会向它的父窗口发送通知消息IPN_FIELDCHANGED。在大多数情况下,我们都可以忽略此通知消息。以下是处理通知消息IPN_FIELDCHANGED的一个示例:
" [" }' f) }1 @* A! M6 E  U2 v; i8 d
void __fastcall TForm1::WndProc(TMessage &Msg)
, D4 \: F0 u1 l& M! y5 g5 [3 B{
9 b9 N+ R5 v1 a/ i8 L    LPNMHDR p=(LPNMHDR)Msg.LParam;
% U5 H' _- U9 }* ]2 Y$ C! l    if(Msg.Msg==WM_NOTIFY)( @8 ?6 v; b- |6 d, W
    {
2 V" Z4 }/ c5 z9 I        if(p->code==IPN_FIELDCHANGED)
+ V0 H( f. Q0 b        {! s) ~' ]7 q8 R3 I; [) q
            //处理IP控件的IPN_FIELDCHANGED通知消息0 T7 r0 c1 e2 F5 P: [/ j
        }1 l; g+ J6 q  n" l: I& H
    }# f! g$ D& `# t1 \
    TForm::WndProc(Msg);
5 _1 Z) l; p& i4 _/ T, O}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-2 03:08 , Processed in 0.016261 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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