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

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

[复制链接]
发表于 2004-2-15 13:39:03 | 显示全部楼层 |阅读模式
作者: ccrun ,如转载请保证本文档的完整性,并注明出处。
' _4 o+ Y$ u$ J" g欢迎光临 C++ Builder 研究,http://www.ccrun.com/doc/go.asp?id=592! q3 S) E; {+ B# N' n. h
本文是ccrun(老妖)根据偶然间看到的一篇文章略作修改而成。参考资料:/ g/ ?6 M: J7 \! @7 @, M" L( j* d
标题:在Delphi中使用IP控件
7 I1 h" n% h( z- z& y5 o* c8 K8 F+ |作者:西安交通大学9649# 刘明华
& R9 {+ y' f+ Q& d% c$ u在些对原作者的无私奉献表示感谢!如欲转载请保留完整版权信息。
3 }# j5 s: [( G! L. B如果这篇文章侵犯了您的版权,请来信告诉我们:info@ccrun.com
5 o$ E1 \' N( h( W; eccrun(老妖)(www.ccrun.com)  2003.10.29
6 H% u( ]' t: q" \# K9 b  G: o" z4 M/ X% d
在网络程序中,我们常常碰到需要用户输入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控件。
0 Q' m0 r7 @+ T1 r
, ^  X1 X: i; x+ i- g" l. V  ^( }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)。
; T. N( u' ^; u" c( V
8 p0 I4 e! v8 L●初始化Windows自定义控制库●: k( L) A& s, h% `' \+ V0 m
Windows提供了两个API函数,InitCommonControls和InitCommonControlsEx,用来初始化自定义控制库。从名字我们不难看出这两个API函数的关系:后者是前者的增强。如果你希望在程序中使用IP控件,你必须用InitCommonControlsEx来完成对自定义控制库以及类的初始化。函数InitCommonControlsEx的原型如下:
0 s; V/ z- A! J* z0 v/ k( k; _4 h9 W2 X% D8 s- ]: c% Y
typedef struct tagINITCOMMONCONTROLSEX {+ _* W* i( ]' b6 P1 @
    DWORD dwSize;             // size of this structure3 l, ?  {- A5 s0 j3 ?) b
    DWORD dwICC;              // flags indicating which classes to be initialized9 g) `" N( X  C+ M# Z
} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;
6 L1 f# J) S7 r6 u* i- n7 r; |! ?8 ]; {3 M4 ~
WINCOMMCTRLAPI BOOL WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX);
. F- u; ]4 b& j" i  P
" n( R. ^) u+ E# T: gIP控件属于ICC_INTERNET_CLASSES类别的控件,如果要使用该控件,你应该在程序中包含如下的初始化代码:- t' \  h5 L# r4 x3 y/ B4 S
% s7 X' _  J# }6 U+ `- _. @
TInitCommonControlsEx ICC;
' d( W: ^1 h: Q! xICC.dwSize = sizeof(TInitCommonControlsEx);8 }$ _) V! w' d- A7 q. H: G
ICC.dwICC  = ICC_INTERNET_CLASSES;
# h; k8 [# {& `' x/ R5 ]if(!InitCommonControlsEx(&ICC))
6 m+ E" G. X9 k9 _( M6 h    return;  //初始化组件失败
! p0 H* J# h' x# L" _0 T$ @0 p/ R. Z3 L! o. `
●创建IP控件●% [/ H( ^) s2 U: W& M% A
Windows API函数CreateWindow或者CreateWindowEx都可以用来创建一个IP控件实例。IP控件的窗口类名为"SysIPAddress32",C++ Builder的commctrl.pas单元为其定义了一个符号常量WC_IPADDRESS。下面这条语句将在Form1上创建一个IP控件。% ^) N- |+ H9 P& V0 ^

6 d+ o& o* Z! f' d' u6 OHWND hIpEdit = CreateWindow(WC_IPADDRESS,NULL,WS_CHILD|WS_VISIBLE,10,10,135,47,Handle,0,HInstance,NULL);
1 P- D) I  u( F+ u) H
' W5 w5 L  {9 ~2 J* e5 E% q●使用IP控件●. N  \9 K+ K! s. @7 |  m7 k
在程序中,我们通过向IP控件发送消息来与它通讯。IP控件可以响应的消息有以下6个,这些消息及它们的含义见下表:0 U* g. {. V# M$ S( ~6 _
' a2 c9 w# V! t
消息常量            消息值         作用                                      参数及返回值
& U7 I7 q% U' w; b/ bIPM_CLEARADDRESS    WM_USER+100    清除IP控件中的IP串                        参数无7 u+ p4 F' Y# O2 }- l% u
IPM_SETADDRESS      WM_USER+101    设置IP控件的IP串                          Lparam为32位的IP值
1 k4 |* C1 W6 i- @IPM_GETADDRESS      WM_USER+102    获取IP控件中的IP串所对应的IP值(32位整数)  Lparam为一个指向Integer变量的指针。返回值等于IP控件中非控的字段数目;获取到的IP值存放在lparam 所指向的Integer变量中。  
& i1 T: D& x8 o8 m5 QIPM_SETRANGE        WM_USER+103    设置IP控件4个部分的其中一个的IP取值范围   Wparam指明要设置取值范围的部分;lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。+ D" S/ ?1 @9 B7 Z. T
IPM_SETFOCUS        WM_USER+104    设输入焦点                                Wparam指明哪个部分获取焦点9 b; r$ i" w+ v! @/ e# f
IPM_ISBLANK         WM_USER+105    IP串是否为空                              参数无。返回值:若为空,返回非0;不为空,返回03 h) r9 q4 u3 f

" o! i2 X/ F) |$ R$ }3 t" R★㈠清空IP串(IPM_CLEARADDRESS)★
/ _2 `, ?- z& H8 V! b$ mSendMessage(hIpEdit,IPM_CLEARADDRESS,0,0);/ {+ R8 u. w( c0 v4 J) g

. v' ~) F. d0 L+ V★㈡设置IP串(IPM_SETADDRESS)★7 u! T# J5 s. ^' D' W# s7 M
int nIP;8 s/ \: y( z5 Q$ c* D" v7 J+ X# F8 y
nIP=MAKEIPADDRESS(192,168,0,1);
/ g) u# c$ h9 \1 n& @7 e/ TSendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);
6 N( K# b  B1 L6 ]3 K* `) Z% [% ]- Y, W4 ]  J9 Q! s/ c& ?
此例将IP控件的内容设为"192.168.0.1",其中MAKEIPADDRESS是一个Win32宏,定义在commctrl.h头文件中,它用来合成一个32位的IP值:
) i% v. A$ T0 S% n7 w% t& A#define MAKEIPADDRESS(b1,b2,b3,b4)! [; @1 \$ t( ^1 a5 K% O1 X
((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4))))
. v/ @1 A$ p- L- Z9 }
- }) Y6 n3 `' M4 H★㈢获取IP值(IPM_GETADDRESS)★
7 p/ ~& |: s& O$ q6 a1 E- `int nIP;
% Y; C9 `/ U' C% B: w- y$ G- \SendMessage(hIpEdit,IPM_GETADDRESS,0,int(&nIP));( D8 T8 f  i, z& S1 g( |  |- y
//nIP++;. N7 I9 J) n6 W( z$ |* i8 G
//SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);   //将IP加1再赋给IP控件。4 Q+ O/ w" R4 b3 P3 s% d
: G8 z: R4 p( t' f! H2 Q
若想要获取IP控件中IP串所对应的IP值,你应该向IP控件发送IPM_GETADDRESS消息,并且需要把一个32位整数的地址作为SendMessage的最后一个参数。
- b: s) k1 z: |' F
# Q" K' N% w4 t5 E* n2 ]5 x8 B★㈣设置取值范围(IPM_SETRANGE)★5 }1 O9 q# L/ J; ]: D
SendMessage (hIpEdit, IPM_SETRANGE, 0, 200<<8|100);6 ], j2 ^' U- o3 f4 L7 i" G7 Y! R
此语句将IP控件的第一部分的范围限制为100~200。在IPM_SETRANGE消息中,Wparam指明要设置的字段, 而lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。
8 }9 Q6 R& \% y8 F2 [  Q2 f: n( X& h' I7 l- A
★㈤设置输入焦点(IPM_SETFOCUS)★
1 w4 A" a6 ?/ E8 _% |( z1 b9 K8 jSendMessage(hIpEdit,IPM_SETFOCUS,3,0);
: U9 J3 {2 w! s' ^* T5 d//将输入焦点设在IP控件的第四部分。$ r; q3 g8 D" g

2 ~# c9 B0 E3 ~( T$ A㈥判断IP串是否为空(IPM_ISBLANK)& z: M, d( n& V+ m. H
if(!SendMessage(hIpEdit,IPM_ISBLANK,0,0))
# w/ D+ N9 p' J! j9 x{9 U' ?, ^2 A% u/ \6 d# h
    //IP控件中的IP串为空: s9 M: t, W3 ]4 i2 p  ~
}1 p8 k& F& v- m' R
else1 i# r, k9 I- g- g
{
: M$ m6 W$ g6 r; A! g  B% C( a" c    //IP控件中的IP串至少有一部分不是空的2 A0 A; I' Z9 P0 {
}
( F: _  J# {* z( ]! d8 {7 u
' W+ N/ F* [, _5 b/ P1 ]●IP控件的通知消息●
1 F( h" M4 t( V3 P当IP串被改动后或者输入焦点发生了转移,IP控件就会向它的父窗口发送通知消息IPN_FIELDCHANGED。在大多数情况下,我们都可以忽略此通知消息。以下是处理通知消息IPN_FIELDCHANGED的一个示例:
$ a$ t$ ]8 \. u+ f' b) T+ Q. m. w1 T9 f' a
void __fastcall TForm1::WndProc(TMessage &Msg)" l' T3 @) g' k  T7 V& }) B3 z
{
9 R0 @% X# U$ t# d- k  v    LPNMHDR p=(LPNMHDR)Msg.LParam;
' q5 q; d; c( H; y, ]# R5 R    if(Msg.Msg==WM_NOTIFY)
$ F# l( j$ M% n  ?0 d; \9 P    {' _: m5 T' Y) i3 J* t& B. B9 w
        if(p->code==IPN_FIELDCHANGED)
* R' x$ x7 E. E        {
  w! ~# q, V1 |% X; a1 S4 P" A            //处理IP控件的IPN_FIELDCHANGED通知消息
5 ]' _8 ?7 S9 ~% T6 E. b- n- c        }
! x8 q4 H/ I- r/ q6 a1 y    }/ S5 A& e/ ]" q# ~& f% h- e
    TForm::WndProc(Msg);2 ?/ }2 n$ ]5 N: r6 Z3 V' o
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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