|
|
作者: ccrun ,如转载请保证本文档的完整性,并注明出处。, ^0 Q+ W" M5 a7 `, H* T8 R
欢迎光临 C++ Builder 研究,http://www.ccrun.com/doc/go.asp?id=592
6 _" a6 i$ t! f本文是ccrun(老妖)根据偶然间看到的一篇文章略作修改而成。参考资料:1 B; t3 c2 }. e# x4 t) l
标题:在Delphi中使用IP控件
4 W# ?" \! R" R/ {作者:西安交通大学9649# 刘明华+ ~- Y' i# K. ]! v3 Y9 U
在些对原作者的无私奉献表示感谢!如欲转载请保留完整版权信息。: S' k6 u) }, A. ?5 c
如果这篇文章侵犯了您的版权,请来信告诉我们:info@ccrun.com
9 c9 J8 F* s" y4 ~ccrun(老妖)(www.ccrun.com) 2003.10.29
+ n- W$ F3 _) r% j! W& ^; U# d3 g& r7 c7 h7 ]# Q 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控件。
* C# V7 O! k4 Y2 K- z+ e# }& z: Q$ ?- J; O: y% ~& l
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& U3 y+ w, h3 z9 L$ m( Y# B8 p" t& {
9 N/ {+ F0 n# Y. J5 x( w●初始化Windows自定义控制库●
2 W. P" i/ `! w/ R: lWindows提供了两个API函数,InitCommonControls和InitCommonControlsEx,用来初始化自定义控制库。从名字我们不难看出这两个API函数的关系:后者是前者的增强。如果你希望在程序中使用IP控件,你必须用InitCommonControlsEx来完成对自定义控制库以及类的初始化。函数InitCommonControlsEx的原型如下:0 h$ i* n( B0 c1 r* J/ v/ E5 f
k8 {* X. F5 b1 T3 S3 n
typedef struct tagINITCOMMONCONTROLSEX {$ S! M+ F/ e2 |3 q6 K0 w
DWORD dwSize; // size of this structure( D; d( u3 i- \. _$ t/ e
DWORD dwICC; // flags indicating which classes to be initialized
; y0 {" m# F4 A( e+ r |& h} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;, `; k( R) d# `& F
: G0 p0 u# r$ ~; Y s) AWINCOMMCTRLAPI BOOL WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX);4 V% J: M b; F5 u
9 @& o$ O) K3 H' ?' R
IP控件属于ICC_INTERNET_CLASSES类别的控件,如果要使用该控件,你应该在程序中包含如下的初始化代码:1 @ _! p# l0 Y$ Q
% H q" t/ e% I1 j# _! D8 t" rTInitCommonControlsEx ICC;# s' f. ]! i+ D$ ? [' q' l+ l/ z
ICC.dwSize = sizeof(TInitCommonControlsEx);0 n8 Q7 S; ~ y
ICC.dwICC = ICC_INTERNET_CLASSES;
; |9 o" \- r3 Q+ v' ^if(!InitCommonControlsEx(&ICC))
4 ^) A) s* X" L' o# d2 N return; //初始化组件失败
- g" x" W- ]3 Z/ k; [0 S' ^% W" t4 y$ v+ V. Z: w: T3 ~
●创建IP控件●
) W) R# F7 \- n3 s- lWindows API函数CreateWindow或者CreateWindowEx都可以用来创建一个IP控件实例。IP控件的窗口类名为"SysIPAddress32",C++ Builder的commctrl.pas单元为其定义了一个符号常量WC_IPADDRESS。下面这条语句将在Form1上创建一个IP控件。+ n7 S0 |3 E- ?( f* n# {
" K, D( t! l& E7 z* o' }1 b4 `& ]HWND hIpEdit = CreateWindow(WC_IPADDRESS,NULL,WS_CHILD|WS_VISIBLE,10,10,135,47,Handle,0,HInstance,NULL);
$ F& d/ D" f, l; b" [" ]; X* N( C2 i3 z7 g1 u
●使用IP控件●) z6 d" V& B4 O- m$ G4 }
在程序中,我们通过向IP控件发送消息来与它通讯。IP控件可以响应的消息有以下6个,这些消息及它们的含义见下表:# L! c" C5 Q1 @* R8 C4 N! o4 I
5 y- p P, A% K* N( }消息常量 消息值 作用 参数及返回值
3 ]# H9 S" @; cIPM_CLEARADDRESS WM_USER+100 清除IP控件中的IP串 参数无
( H7 Q1 T( j; H- f ^6 P' eIPM_SETADDRESS WM_USER+101 设置IP控件的IP串 Lparam为32位的IP值
. O- q" S ]' Q/ f( t" R# }1 {% G; tIPM_GETADDRESS WM_USER+102 获取IP控件中的IP串所对应的IP值(32位整数) Lparam为一个指向Integer变量的指针。返回值等于IP控件中非控的字段数目;获取到的IP值存放在lparam 所指向的Integer变量中。
" d" A5 R& p+ R9 Q2 t" q& U% o% VIPM_SETRANGE WM_USER+103 设置IP控件4个部分的其中一个的IP取值范围 Wparam指明要设置取值范围的部分;lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。
+ O* i; {! B2 m# XIPM_SETFOCUS WM_USER+104 设输入焦点 Wparam指明哪个部分获取焦点& \) e( g! ?* D
IPM_ISBLANK WM_USER+105 IP串是否为空 参数无。返回值:若为空,返回非0;不为空,返回0
. ^$ i( m. ^! z4 c' \( p: ]5 r* ]) i0 l/ G; u# Y9 |4 N- P' ]& X
★㈠清空IP串(IPM_CLEARADDRESS)★/ T# j4 u6 Q6 Z3 e. h
SendMessage(hIpEdit,IPM_CLEARADDRESS,0,0);" |+ T7 t2 E# y$ O3 m1 C0 R
" b9 p8 R5 q: N$ m! b3 j0 Q; c2 K★㈡设置IP串(IPM_SETADDRESS)★
- f* K7 H. ?& U$ H1 t! @int nIP;7 N6 N# f. I! R- ^; ~+ p% u
nIP=MAKEIPADDRESS(192,168,0,1); & U' n% O4 J7 o0 R$ [3 _" g
SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);6 E6 v6 i% |9 z ^0 p2 A4 l' z
/ E# Y- I9 E8 s& F! n此例将IP控件的内容设为"192.168.0.1",其中MAKEIPADDRESS是一个Win32宏,定义在commctrl.h头文件中,它用来合成一个32位的IP值:* j$ K/ O- S" G: @/ I
#define MAKEIPADDRESS(b1,b2,b3,b4)
4 h0 b! P9 L/ E, r( |7 k- |, d) ]((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4)))) @0 `+ E( L5 M+ z/ S g" z% q
- j- o: K: N% `9 }. G4 t( d
★㈢获取IP值(IPM_GETADDRESS)★! g. ^4 Z, J; C/ o+ }( G8 H) W
int nIP;
% [7 W7 W, b* N7 T. H$ d6 l# e; zSendMessage(hIpEdit,IPM_GETADDRESS,0,int(&nIP));0 \" ]) d* b2 M# U( F
//nIP++;( b( R) G% Z& S+ I, f8 M
//SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP); //将IP加1再赋给IP控件。
- M M2 a; ~$ i
7 s9 T- w6 K8 j$ z+ e6 F* k若想要获取IP控件中IP串所对应的IP值,你应该向IP控件发送IPM_GETADDRESS消息,并且需要把一个32位整数的地址作为SendMessage的最后一个参数。
5 W% c. z% i$ E6 _; A* p/ I: C2 k5 I6 c% b- [
★㈣设置取值范围(IPM_SETRANGE)★
" d5 V; S3 m7 H5 JSendMessage (hIpEdit, IPM_SETRANGE, 0, 200<<8|100);; l' p! v4 T6 n x& d: u/ r
此语句将IP控件的第一部分的范围限制为100~200。在IPM_SETRANGE消息中,Wparam指明要设置的字段, 而lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。& X$ f# p$ P6 z) n& V. R7 m# I
& h; p$ j1 `, y% }, e2 j( T* h★㈤设置输入焦点(IPM_SETFOCUS)★
" Q3 v& O8 e3 {3 R. ^SendMessage(hIpEdit,IPM_SETFOCUS,3,0);$ i- z4 y1 R! s0 r" ^& _2 b
//将输入焦点设在IP控件的第四部分。9 o& z" A6 f3 o3 D9 c+ d0 H& _9 U$ l+ d
2 I4 \! P; W" V. K) L4 p1 u㈥判断IP串是否为空(IPM_ISBLANK)
: {8 {% f2 c @+ h0 Gif(!SendMessage(hIpEdit,IPM_ISBLANK,0,0))
3 u: p) q$ D" J; S0 O" x0 E5 n; \9 e{. J. _2 }2 W1 {& q2 s
//IP控件中的IP串为空
$ S+ g J( S% M; _. G6 \}
! g$ Z$ U% g; e# a& e! b1 velse4 A9 b0 M3 w5 g% O1 {9 l( ?
{
4 _' v( q: y7 k* D3 u //IP控件中的IP串至少有一部分不是空的1 c# O S4 c9 U: \4 g
}
# {' E6 N2 \+ u5 [. q' Z! r k* e. \0 x8 r; c- T0 j( ~
●IP控件的通知消息●
N& `9 t, H% P$ r0 m1 D( O当IP串被改动后或者输入焦点发生了转移,IP控件就会向它的父窗口发送通知消息IPN_FIELDCHANGED。在大多数情况下,我们都可以忽略此通知消息。以下是处理通知消息IPN_FIELDCHANGED的一个示例: Q" R, z2 F0 s" I: E
~. t9 A' Z# `0 s! `, M2 l+ h" J; K
void __fastcall TForm1::WndProc(TMessage &Msg)$ `- K+ n% F4 ^) P
{9 o) y5 C" u6 X0 N( P0 }, Q
LPNMHDR p=(LPNMHDR)Msg.LParam;
% B8 [( Z& H/ c+ L' h! f; W- l: f0 r3 t if(Msg.Msg==WM_NOTIFY): _5 A }1 n! }. z. a( g5 N, I
{
1 r/ s$ d+ L% i" h: v if(p->code==IPN_FIELDCHANGED)- i% `1 E5 {' `& T) Y
{
# o7 X1 Z0 e7 O& }, K //处理IP控件的IPN_FIELDCHANGED通知消息9 e9 V3 s1 l z( a; y, Z' v2 [
}
8 [2 t: X2 }. A' d }
! F: b( |6 i5 Q2 A K TForm::WndProc(Msg);7 }- F$ l! U+ g3 h; m
} |
|