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

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

[复制链接]
发表于 2004-2-15 13:42:14 | 显示全部楼层 |阅读模式
作者: ccrun ,如转载请保证本文档的完整性,并注明出处。
) }; Y' l* K+ V, H3 y! o欢迎光临 C++ Builder 研究,http://www.ccrun.com/doc/go.asp?id=5921 f8 g0 Y  T* Z. F+ s0 y" Y
本文是ccrun(老妖)根据偶然间看到的一篇文章略作修改而成。参考资料:7 [0 @; A" a) U5 O, S4 v
标题:在Delphi中使用IP控件
! B1 K+ N; S* ~  D3 t5 S作者:西安交通大学9649# 刘明华* T' h+ _; S% k  G5 f
在些对原作者的无私奉献表示感谢!如欲转载请保留完整版权信息。& p* k  I$ m. e7 ~
如果这篇文章侵犯了您的版权,请来信告诉我们:info@ccrun.com
9 f6 M; x6 t% V7 _1 bccrun(老妖)(www.ccrun.com)  2003.10.293 l# y8 S; q% V
7 c5 |5 Z# Q; a- P4 Z+ b. `3 h: f
在网络程序中,我们常常碰到需要用户输入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控件。
7 T) w# x% n1 B& R7 B2 N; D$ y) r* y$ X
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 B3 b( S0 O- _* T5 b+ T0 k9 D$ `0 a8 u1 u9 E8 o
●初始化Windows自定义控制库●
2 A9 Y) B" X) XWindows提供了两个API函数,InitCommonControls和InitCommonControlsEx,用来初始化自定义控制库。从名字我们不难看出这两个API函数的关系:后者是前者的增强。如果你希望在程序中使用IP控件,你必须用InitCommonControlsEx来完成对自定义控制库以及类的初始化。函数InitCommonControlsEx的原型如下:8 L- p7 J8 `$ k) z) B
! w8 K0 R8 n" B, v2 u# V) H
typedef struct tagINITCOMMONCONTROLSEX {
2 R, ]9 Z! r& G) ]5 r% l    DWORD dwSize;             // size of this structure) y( H/ J' x' f1 g
    DWORD dwICC;              // flags indicating which classes to be initialized8 C' \" O- ?2 N8 M! ]2 }
} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;
  X! ]5 D) z$ |8 W" k. U" }2 h0 [8 [
4 S0 m& D6 I4 Y" G$ T9 yWINCOMMCTRLAPI BOOL WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX);
5 G  |0 A, q& \; ]' A7 ?  i( o. x
IP控件属于ICC_INTERNET_CLASSES类别的控件,如果要使用该控件,你应该在程序中包含如下的初始化代码:$ C" R3 g' G; `, n: S( v# W5 [

9 r* Q8 G0 c+ S6 u+ ~TInitCommonControlsEx ICC;
3 G: w% D. t. |) S5 x; e  x( tICC.dwSize = sizeof(TInitCommonControlsEx);& P/ y8 K% w# @
ICC.dwICC  = ICC_INTERNET_CLASSES;
- h, [, m- h( G! Qif(!InitCommonControlsEx(&ICC))0 q0 K# C& Q/ d  |$ \
    return;  //初始化组件失败
4 T+ D4 j% T" b" r8 V4 c2 \5 D
" Q9 b9 S2 \: r5 G9 g% S7 i●创建IP控件●: K: \$ m0 w) T6 G& D, ~6 I- @, g
Windows API函数CreateWindow或者CreateWindowEx都可以用来创建一个IP控件实例。IP控件的窗口类名为"SysIPAddress32",C++ Builder的commctrl.pas单元为其定义了一个符号常量WC_IPADDRESS。下面这条语句将在Form1上创建一个IP控件。. A. B2 ~8 |4 ^+ p

. |% Q$ M5 B) |  U) D& jHWND hIpEdit = CreateWindow(WC_IPADDRESS,NULL,WS_CHILD|WS_VISIBLE,10,10,135,47,Handle,0,HInstance,NULL);; A6 \) O, Z2 h8 E
% p6 @- v! |% D* g% k1 l) S7 t: y
●使用IP控件●
% U* h! @$ Z8 k4 }# L在程序中,我们通过向IP控件发送消息来与它通讯。IP控件可以响应的消息有以下6个,这些消息及它们的含义见下表:: T1 y* W1 X# M% o; R
+ `+ `0 _1 u5 S+ z
消息常量            消息值         作用                                      参数及返回值
. a& d( ^7 V( g1 h7 H( d" RIPM_CLEARADDRESS    WM_USER+100    清除IP控件中的IP串                        参数无& t/ a/ s# X5 F# h
IPM_SETADDRESS      WM_USER+101    设置IP控件的IP串                          Lparam为32位的IP值' @3 m3 X2 Z. C+ g# c
IPM_GETADDRESS      WM_USER+102    获取IP控件中的IP串所对应的IP值(32位整数)  Lparam为一个指向Integer变量的指针。返回值等于IP控件中非控的字段数目;获取到的IP值存放在lparam 所指向的Integer变量中。  
* k% v* p1 }0 E8 G! \2 HIPM_SETRANGE        WM_USER+103    设置IP控件4个部分的其中一个的IP取值范围   Wparam指明要设置取值范围的部分;lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。# ]9 a4 _2 n" Q) G- O! J8 h& R
IPM_SETFOCUS        WM_USER+104    设输入焦点                                Wparam指明哪个部分获取焦点* |5 O1 T  o3 a* A/ Z1 T- A
IPM_ISBLANK         WM_USER+105    IP串是否为空                              参数无。返回值:若为空,返回非0;不为空,返回0
* R- E" m2 M4 m
5 G( s; i4 T* B$ _★㈠清空IP串(IPM_CLEARADDRESS)★2 N$ y2 O& ?* E9 G1 y5 W
SendMessage(hIpEdit,IPM_CLEARADDRESS,0,0);
0 s  g+ z1 t% k1 a+ Q0 B% A$ E
# c+ s6 _" X  I# P4 V! A8 c' V★㈡设置IP串(IPM_SETADDRESS)★
  h! Q8 ~8 R( h4 F& t, Mint nIP;
$ b8 {0 ]4 U: x! _" hnIP=MAKEIPADDRESS(192,168,0,1);
. L8 I5 C3 P5 F/ i" T- Q  s0 DSendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);
' Z5 U1 Q$ S" R5 w6 v3 b0 s9 X/ D+ c5 R- ^! T
此例将IP控件的内容设为"192.168.0.1",其中MAKEIPADDRESS是一个Win32宏,定义在commctrl.h头文件中,它用来合成一个32位的IP值:- k$ F5 R- o' W& K8 H3 z% Q
#define MAKEIPADDRESS(b1,b2,b3,b4)
2 R0 r. B. l7 R% b) o((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4)))): W9 Y* B' G/ R3 N/ {% j  |" v6 p$ R

, H3 E7 h, w6 k9 `7 ~4 e: k" K8 i% n/ D★㈢获取IP值(IPM_GETADDRESS)★
: A. ?% ?1 ~6 G& jint nIP;5 I& t' p1 |! Q9 B; F5 W
SendMessage(hIpEdit,IPM_GETADDRESS,0,int(&nIP));
" V3 {6 k. `. f5 u//nIP++;
7 A& g) e/ M; L//SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);   //将IP加1再赋给IP控件。
! k6 `7 f! B" p  G) A9 z7 ?( R4 X; A5 o5 |* W; `! @
若想要获取IP控件中IP串所对应的IP值,你应该向IP控件发送IPM_GETADDRESS消息,并且需要把一个32位整数的地址作为SendMessage的最后一个参数。. ~' ^8 X8 a2 A
+ i( O1 @9 @8 |, e% _" M
★㈣设置取值范围(IPM_SETRANGE)★% g( e0 b1 F) f  h2 H0 w. d
SendMessage (hIpEdit, IPM_SETRANGE, 0, 200<<8|100);
: x- {/ Z/ H4 ^. M. v此语句将IP控件的第一部分的范围限制为100~200。在IPM_SETRANGE消息中,Wparam指明要设置的字段, 而lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。; s* m& Y8 s7 s4 B. p

3 M. L+ D0 f5 b0 p. M3 `9 s+ T1 U★㈤设置输入焦点(IPM_SETFOCUS)★. q( Q  l, S6 m# S+ p
SendMessage(hIpEdit,IPM_SETFOCUS,3,0);
: x7 f  m& a% {# ?//将输入焦点设在IP控件的第四部分。6 A# h, h8 s4 T6 I+ C
% ~( l4 W6 p" Q5 e2 I
㈥判断IP串是否为空(IPM_ISBLANK)* m) w# @' |' @4 Y' r
if(!SendMessage(hIpEdit,IPM_ISBLANK,0,0))   o  i( ]8 j. q' N
{' c& U( E. d! R
    //IP控件中的IP串为空7 }" H1 F0 x2 m$ X# s" Q- k6 q" d
}6 w* g1 z0 c1 o! t2 }7 I- [
else+ o6 v, ~& z0 n0 e* h; Z3 T( w  U5 S
{! S5 _7 g( M9 g2 T. L* Y8 G8 C# t
    //IP控件中的IP串至少有一部分不是空的
0 ^* g8 K: l8 `* q$ @+ e}/ K3 U; P. M0 u) R+ w, Q& K
; J9 }3 ^5 m, |& K2 T9 u4 H( a
●IP控件的通知消息●, y# v( A. ]7 \; \
当IP串被改动后或者输入焦点发生了转移,IP控件就会向它的父窗口发送通知消息IPN_FIELDCHANGED。在大多数情况下,我们都可以忽略此通知消息。以下是处理通知消息IPN_FIELDCHANGED的一个示例:
* U; S" `3 f# b" |5 V4 w7 D& S+ F' o* x% ]; x% |
void __fastcall TForm1::WndProc(TMessage &Msg)
) b) U- |8 i7 {! d5 y{! ^5 k! u5 R( r' U; c2 \
    LPNMHDR p=(LPNMHDR)Msg.LParam;7 `; ^2 \. D# U
    if(Msg.Msg==WM_NOTIFY)+ V0 L; Z6 W( h* u8 N6 s" ^, m
    {5 ?) i: Z& s8 \+ [0 c: M/ ?$ E/ V
        if(p->code==IPN_FIELDCHANGED). {' V% {8 N+ r& C
        {
( p; b- A; ]" ~- j0 z# J            //处理IP控件的IPN_FIELDCHANGED通知消息
$ i! ]6 l* {% t. ?$ N: H        }
3 u8 y) c! W1 @& [* B( W- B    }
6 X9 L4 `+ p1 R/ I3 G3 P! R' D    TForm::WndProc(Msg);( i$ |3 X9 i7 Q2 V
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-9 01:37 , Processed in 0.035047 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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