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

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

[复制链接]
发表于 2004-2-15 13:39:03 | 显示全部楼层 |阅读模式
作者: ccrun ,如转载请保证本文档的完整性,并注明出处。* ~/ L. \% r0 f, ?" F1 h' q) u$ w
欢迎光临 C++ Builder 研究,http://www.ccrun.com/doc/go.asp?id=592
7 H/ ]- X% W% w; e; q4 u本文是ccrun(老妖)根据偶然间看到的一篇文章略作修改而成。参考资料:
' R% K/ `( y6 R% f  _标题:在Delphi中使用IP控件
" ~& V2 r/ e: r$ A# I" w作者:西安交通大学9649# 刘明华
. P2 m% e9 ^( ]5 [# {在些对原作者的无私奉献表示感谢!如欲转载请保留完整版权信息。$ d: G+ P0 k0 ?  K$ r1 l
如果这篇文章侵犯了您的版权,请来信告诉我们:info@ccrun.com
; ]6 H/ g2 K+ ^8 W2 l/ Y+ D" zccrun(老妖)(www.ccrun.com)  2003.10.29# M  \0 @/ {# _' w3 w/ V
$ N* {9 n5 z  Z5 _; |& X
在网络程序中,我们常常碰到需要用户输入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控件。; n2 n$ c& g5 `0 c) Z$ ^

( M4 d  d& J5 Z& B. F( Y# PWindows中有两个非常重要的动态联结库:commctrl.dll和comctl32.dll,它们是Windows的自定义控制库(Windows Common Controls)。自定义控制库中包含了许多常用的Windows控件,如Statusbar,Coolbar,HotKey等;在C++ Builder中,这些控件大多数都已被包装成可视化控件了。在Microsoft推出Internet Explorer 3之后,自定义控制库中新增了一些控件,其中就包括Windows的IP控件(IP Address edit control)。! ^' U$ d9 Z5 Q; w5 I3 B& ~
1 b  i2 Z3 z6 B# ~
●初始化Windows自定义控制库●5 G5 S3 C! O  M
Windows提供了两个API函数,InitCommonControls和InitCommonControlsEx,用来初始化自定义控制库。从名字我们不难看出这两个API函数的关系:后者是前者的增强。如果你希望在程序中使用IP控件,你必须用InitCommonControlsEx来完成对自定义控制库以及类的初始化。函数InitCommonControlsEx的原型如下:% e& l% X3 H% _9 [! _8 ^
1 g6 T: [/ x9 J& E
typedef struct tagINITCOMMONCONTROLSEX {
  v# \  T6 g- u* ~$ L, o    DWORD dwSize;             // size of this structure8 C" @+ a/ \) J5 |8 D2 F
    DWORD dwICC;              // flags indicating which classes to be initialized
5 w/ T& e5 r& W$ c4 B} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;. I5 P: A7 c  ?0 P8 d
: Y9 G. p1 G% P" F9 B+ G
WINCOMMCTRLAPI BOOL WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX);, |$ e& w3 e& |# k5 u, t6 w
% z/ S2 |6 T: ~! D& s# y
IP控件属于ICC_INTERNET_CLASSES类别的控件,如果要使用该控件,你应该在程序中包含如下的初始化代码:
* A, |4 e6 z8 e2 i1 K, C' y% J  B7 N9 w9 U, M
TInitCommonControlsEx ICC;+ e5 R( {2 B! E3 |0 M+ @0 M
ICC.dwSize = sizeof(TInitCommonControlsEx);- ^. M! d7 M, L' `; `
ICC.dwICC  = ICC_INTERNET_CLASSES;
! o0 y0 Z& a2 ?) U3 lif(!InitCommonControlsEx(&ICC))) C  ^1 Y6 ^, [5 Z
    return;  //初始化组件失败6 m) }2 t' F$ Q, }# Y0 c

, \7 i$ G7 h; J; i( v●创建IP控件●
3 h7 K7 ~8 X% ~3 E3 hWindows API函数CreateWindow或者CreateWindowEx都可以用来创建一个IP控件实例。IP控件的窗口类名为"SysIPAddress32",C++ Builder的commctrl.pas单元为其定义了一个符号常量WC_IPADDRESS。下面这条语句将在Form1上创建一个IP控件。
3 m/ M; G( X; f' Q0 D. a
+ M- c# n- d- t; o- u$ I+ }$ IHWND hIpEdit = CreateWindow(WC_IPADDRESS,NULL,WS_CHILD|WS_VISIBLE,10,10,135,47,Handle,0,HInstance,NULL);+ @, F4 }4 Q- [# x8 j$ ?
. |* y6 N9 D" g0 r& r6 g
●使用IP控件●/ K' r+ r- E8 C9 `) R, [/ {
在程序中,我们通过向IP控件发送消息来与它通讯。IP控件可以响应的消息有以下6个,这些消息及它们的含义见下表:
' J+ a0 a. H5 e* Y0 z* F! |
' p1 h( J; W# K$ Q消息常量            消息值         作用                                      参数及返回值6 a! \7 U. q. }0 n( {% A  E
IPM_CLEARADDRESS    WM_USER+100    清除IP控件中的IP串                        参数无
- [# }0 o( x& v& [2 }IPM_SETADDRESS      WM_USER+101    设置IP控件的IP串                          Lparam为32位的IP值
0 L7 V" o& J% x  xIPM_GETADDRESS      WM_USER+102    获取IP控件中的IP串所对应的IP值(32位整数)  Lparam为一个指向Integer变量的指针。返回值等于IP控件中非控的字段数目;获取到的IP值存放在lparam 所指向的Integer变量中。  
: G) M6 E) X7 x/ k" \" Z7 xIPM_SETRANGE        WM_USER+103    设置IP控件4个部分的其中一个的IP取值范围   Wparam指明要设置取值范围的部分;lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。. B# K# l( U; O9 e0 Q; K+ p
IPM_SETFOCUS        WM_USER+104    设输入焦点                                Wparam指明哪个部分获取焦点
1 ]+ u; k- S2 q4 i; z' AIPM_ISBLANK         WM_USER+105    IP串是否为空                              参数无。返回值:若为空,返回非0;不为空,返回0# w7 c) w8 E' ^, b' P  |5 X
- l, P$ k9 m, ~/ \( Y5 c# e
★㈠清空IP串(IPM_CLEARADDRESS)★
" l' ?6 ?2 ^  p& rSendMessage(hIpEdit,IPM_CLEARADDRESS,0,0);
! u  U, _. z3 G: ]; J7 o
0 S; L# {) H$ d) b6 F$ g( J★㈡设置IP串(IPM_SETADDRESS)★
9 W/ M' m7 a9 {- nint nIP;
" @& q: ]$ L& F- Y# qnIP=MAKEIPADDRESS(192,168,0,1); ! ~0 k  U' v/ |. y* U5 \; V$ t
SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);
: j" ?' D, y2 T! k+ r4 {6 [! X" ?0 ~4 q3 y& |+ p+ h7 c& J
此例将IP控件的内容设为"192.168.0.1",其中MAKEIPADDRESS是一个Win32宏,定义在commctrl.h头文件中,它用来合成一个32位的IP值:
% E( L* T: O  X#define MAKEIPADDRESS(b1,b2,b3,b4)4 x$ H* t% m; u9 ~: }3 ]! x9 S
((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4))))
8 t- y8 D1 g/ V  O! F2 N2 C
! i) E" P$ R2 z: Y5 Q★㈢获取IP值(IPM_GETADDRESS)★
2 J% k+ v' b# w; Xint nIP;
: N: u( e( L" hSendMessage(hIpEdit,IPM_GETADDRESS,0,int(&nIP));
; I& _5 Z, q/ `6 n: S3 t//nIP++;: f6 t. d' L# k1 ^. x2 w1 R
//SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);   //将IP加1再赋给IP控件。4 _0 m0 A4 r( B, z% U

' G) m: |" }+ q% c若想要获取IP控件中IP串所对应的IP值,你应该向IP控件发送IPM_GETADDRESS消息,并且需要把一个32位整数的地址作为SendMessage的最后一个参数。! |5 o& K5 E2 l" P+ @: Q# N
2 c5 ~3 i4 u# e+ z7 @
★㈣设置取值范围(IPM_SETRANGE)★3 T' V4 H1 x2 q2 G7 u- r
SendMessage (hIpEdit, IPM_SETRANGE, 0, 200<<8|100);
7 R* s( ~. @" I& s此语句将IP控件的第一部分的范围限制为100~200。在IPM_SETRANGE消息中,Wparam指明要设置的字段, 而lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。
( f- f) l* k1 _3 D- V/ R
7 C: p' _- @4 D5 r2 k" I★㈤设置输入焦点(IPM_SETFOCUS)★) ^" v. m8 ]% m. r
SendMessage(hIpEdit,IPM_SETFOCUS,3,0);2 N. {3 R* [7 x" m3 t
//将输入焦点设在IP控件的第四部分。
$ k9 g* C4 X1 Q  a, |; i4 t
4 i1 x4 Z' o) z㈥判断IP串是否为空(IPM_ISBLANK)" n. z8 M; P$ z3 Z% B+ f* ]- w
if(!SendMessage(hIpEdit,IPM_ISBLANK,0,0)) - H! a" P# }5 X* {, T; X
{% j8 M8 u' E/ I1 W# y! j
    //IP控件中的IP串为空
+ P) W, G/ ]4 m& U0 B& g* l}
+ F( A1 n( y! d5 }5 N+ N2 [else9 z4 \( E; V7 R7 b! v
{
1 _/ `9 X9 Y5 K% S  ^  }    //IP控件中的IP串至少有一部分不是空的
2 U4 q. k, e+ {4 I}
/ l+ K) Q/ |9 _$ z' g, B- g/ ~- O1 c% w8 K9 j" f
●IP控件的通知消息●
. j$ }' \) j1 N. [1 H0 n5 c当IP串被改动后或者输入焦点发生了转移,IP控件就会向它的父窗口发送通知消息IPN_FIELDCHANGED。在大多数情况下,我们都可以忽略此通知消息。以下是处理通知消息IPN_FIELDCHANGED的一个示例:& @: ?; |! k& P# F! `- D/ |0 j
- Y* z0 D# _+ }* y
void __fastcall TForm1::WndProc(TMessage &Msg)$ Q3 K. \# I# d2 x/ r
{6 Y! `; s9 g3 I& W% H# l
    LPNMHDR p=(LPNMHDR)Msg.LParam;$ o1 u/ ], g3 f1 |
    if(Msg.Msg==WM_NOTIFY)5 g2 `8 j2 }7 E6 Y6 u- k
    {9 K; N- |4 g3 {% H  i. {
        if(p->code==IPN_FIELDCHANGED)
- L' P/ B2 c0 m9 g+ r( I+ h' V4 }        {
9 O1 i# _8 d: S            //处理IP控件的IPN_FIELDCHANGED通知消息
! ]0 L! Z+ u+ o% L! G        }. v9 D3 j) d) c. u( F0 T! Q
    }
- l; L5 g2 J% b- @    TForm::WndProc(Msg);. }% I+ C) U! A7 O" t3 b
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 20:02 , Processed in 0.018775 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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