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

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

[复制链接]
发表于 2004-2-15 13:42:14 | 显示全部楼层 |阅读模式
作者: ccrun ,如转载请保证本文档的完整性,并注明出处。2 r$ z& F7 l) y: H
欢迎光临 C++ Builder 研究,http://www.ccrun.com/doc/go.asp?id=5923 i4 s) Q( S( g5 S, [
本文是ccrun(老妖)根据偶然间看到的一篇文章略作修改而成。参考资料:- p5 V' {5 r/ e/ F3 y+ B
标题:在Delphi中使用IP控件0 f9 w9 L" A1 D* E: h6 E
作者:西安交通大学9649# 刘明华5 y) P" A- x8 i2 @
在些对原作者的无私奉献表示感谢!如欲转载请保留完整版权信息。: t4 w0 A1 `$ ^0 e& Y& K
如果这篇文章侵犯了您的版权,请来信告诉我们:info@ccrun.com
2 N: H! r9 X% A: Fccrun(老妖)(www.ccrun.com)  2003.10.29/ q+ Z" u  S9 U! M
+ l' D9 n  y9 `5 @9 r
在网络程序中,我们常常碰到需要用户输入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 ?  t6 A4 e# v! S% C' ?
# X* t2 r  q/ M5 C6 gWindows中有两个非常重要的动态联结库:commctrl.dll和comctl32.dll,它们是Windows的自定义控制库(Windows Common Controls)。自定义控制库中包含了许多常用的Windows控件,如Statusbar,Coolbar,HotKey等;在C++ Builder中,这些控件大多数都已被包装成可视化控件了。在Microsoft推出Internet Explorer 3之后,自定义控制库中新增了一些控件,其中就包括Windows的IP控件(IP Address edit control)。
: v* T! m7 W, {" q3 x/ ~/ v6 c
) R* J0 Z1 b& x! C6 s" G6 ~( e●初始化Windows自定义控制库●% w/ P- w- j; g. r
Windows提供了两个API函数,InitCommonControls和InitCommonControlsEx,用来初始化自定义控制库。从名字我们不难看出这两个API函数的关系:后者是前者的增强。如果你希望在程序中使用IP控件,你必须用InitCommonControlsEx来完成对自定义控制库以及类的初始化。函数InitCommonControlsEx的原型如下:
+ r5 e: J9 E! a  k, Q' f1 r6 O6 ?3 u* E
typedef struct tagINITCOMMONCONTROLSEX {$ f6 t/ \6 a' X. M; k
    DWORD dwSize;             // size of this structure9 a8 ?. I, Y& a3 Q5 q
    DWORD dwICC;              // flags indicating which classes to be initialized
6 u  \5 M: k! D} INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;( L4 R# D  y* c* L% k% w( n

5 {9 R, B. s. z1 X! s( r) vWINCOMMCTRLAPI BOOL WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX);% X! Z: _: {/ W: ]0 {- d8 C
% ^/ X" Q  g- O- ]+ x  }
IP控件属于ICC_INTERNET_CLASSES类别的控件,如果要使用该控件,你应该在程序中包含如下的初始化代码:3 ?+ [& |' c' C/ `# B3 @  q5 o

" I% T6 w6 P- D8 RTInitCommonControlsEx ICC;. F* c) t& l' {9 Y% `0 S" i
ICC.dwSize = sizeof(TInitCommonControlsEx);
6 U% ^0 ?3 k, I4 ]ICC.dwICC  = ICC_INTERNET_CLASSES;
4 F) g2 D3 D5 h7 \, {if(!InitCommonControlsEx(&ICC))4 k' z% b' N/ E* k# z6 d" a3 Y+ C
    return;  //初始化组件失败
  B8 s6 j" J1 Z3 o& W9 _2 m2 Y* v5 d! L% d  [3 B# [+ z
●创建IP控件●
" ?, Y* A: Z1 {Windows API函数CreateWindow或者CreateWindowEx都可以用来创建一个IP控件实例。IP控件的窗口类名为"SysIPAddress32",C++ Builder的commctrl.pas单元为其定义了一个符号常量WC_IPADDRESS。下面这条语句将在Form1上创建一个IP控件。8 W7 V0 V& g3 X! U$ ?( {
, t, y+ z, f+ q
HWND hIpEdit = CreateWindow(WC_IPADDRESS,NULL,WS_CHILD|WS_VISIBLE,10,10,135,47,Handle,0,HInstance,NULL);- N( ]& q, q0 y$ N! v

+ g2 l; }3 V. i& d- q●使用IP控件●
) k2 _3 a( J- o% \/ I3 k6 W在程序中,我们通过向IP控件发送消息来与它通讯。IP控件可以响应的消息有以下6个,这些消息及它们的含义见下表:
3 I" ~0 E. ~' g& f* s+ m) i
7 n' F  }+ ]. l消息常量            消息值         作用                                      参数及返回值
" @, f# \- a$ N- PIPM_CLEARADDRESS    WM_USER+100    清除IP控件中的IP串                        参数无+ X5 X) q0 h6 R* p
IPM_SETADDRESS      WM_USER+101    设置IP控件的IP串                          Lparam为32位的IP值- y4 j3 i& B' s5 l3 d
IPM_GETADDRESS      WM_USER+102    获取IP控件中的IP串所对应的IP值(32位整数)  Lparam为一个指向Integer变量的指针。返回值等于IP控件中非控的字段数目;获取到的IP值存放在lparam 所指向的Integer变量中。  
4 {! X/ s" f) w9 u4 ]% C" }3 jIPM_SETRANGE        WM_USER+103    设置IP控件4个部分的其中一个的IP取值范围   Wparam指明要设置取值范围的部分;lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。9 x% e9 w( o: }9 e6 d5 _1 P
IPM_SETFOCUS        WM_USER+104    设输入焦点                                Wparam指明哪个部分获取焦点
6 {, p, ?) y3 G/ @9 t7 hIPM_ISBLANK         WM_USER+105    IP串是否为空                              参数无。返回值:若为空,返回非0;不为空,返回0; F7 l8 l7 e, ]7 S" Y

& L  e( @; `. n  e# _★㈠清空IP串(IPM_CLEARADDRESS)★
4 M# K7 U& k7 V# d3 @# LSendMessage(hIpEdit,IPM_CLEARADDRESS,0,0);
! f- C9 a  s( H9 L
1 G) T9 p& s+ {) h& R% g, M★㈡设置IP串(IPM_SETADDRESS)★
, G* v8 u2 {" T; p5 K6 dint nIP;' Y2 ~, [3 D3 U
nIP=MAKEIPADDRESS(192,168,0,1);
+ J  H1 [  f/ W7 L+ S/ t8 LSendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);9 x) B& T, R. g
: [- {7 q$ a+ v9 x$ F
此例将IP控件的内容设为"192.168.0.1",其中MAKEIPADDRESS是一个Win32宏,定义在commctrl.h头文件中,它用来合成一个32位的IP值:
+ U8 E& W" x1 X#define MAKEIPADDRESS(b1,b2,b3,b4)
9 M  o) X- i4 T$ N/ A((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4))))3 m" \; k$ w$ s) s7 R

. T7 ~- u# l. w" A★㈢获取IP值(IPM_GETADDRESS)★
5 c; x; I& D& G" i  M' i, D4 P, E8 o0 M# iint nIP;
% z3 K6 t' E, P3 t1 NSendMessage(hIpEdit,IPM_GETADDRESS,0,int(&nIP));
' h$ h) [# y* n2 c7 X$ D//nIP++;: G9 F. Q* w2 Y9 R
//SendMessage(hIpEdit,IPM_SETADDRESS,0,nIP);   //将IP加1再赋给IP控件。! Q) U/ g1 w9 k- R2 y+ k
$ x4 f% E7 |$ n/ a: Q
若想要获取IP控件中IP串所对应的IP值,你应该向IP控件发送IPM_GETADDRESS消息,并且需要把一个32位整数的地址作为SendMessage的最后一个参数。
- j6 z) ?  |0 v0 c/ [9 t! ^) {' C0 F" K' F
★㈣设置取值范围(IPM_SETRANGE)★
4 P# q6 X% ^# r( |" ^: ASendMessage (hIpEdit, IPM_SETRANGE, 0, 200<<8|100);
0 l8 r$ z- a5 u$ ]( i* ?, A此语句将IP控件的第一部分的范围限制为100~200。在IPM_SETRANGE消息中,Wparam指明要设置的字段, 而lparam的低16位字为该字段的范围:高字节为上限,低字节为下限。
1 ^# f! p( C* r! z) r9 ?% y+ P: D+ [+ M' K0 }  Q2 {
★㈤设置输入焦点(IPM_SETFOCUS)★
4 ]& M+ p5 I! `6 c- v0 ^. `6 ZSendMessage(hIpEdit,IPM_SETFOCUS,3,0);
. m5 \4 U4 F9 Z+ L//将输入焦点设在IP控件的第四部分。
& l+ J7 M( N9 E0 l4 Q" U2 I: Q, E  `* }! m% E
㈥判断IP串是否为空(IPM_ISBLANK)1 [+ m! n" h9 B) |2 G/ Z7 @9 x$ @
if(!SendMessage(hIpEdit,IPM_ISBLANK,0,0)) 0 v1 E, e5 k% P3 r
{4 \* U2 `$ S8 R# d: a1 b9 d
    //IP控件中的IP串为空0 O& l1 Y6 @- C; X4 Q2 F
}0 {! @- l  b$ C! S0 k& n
else
. L& h; Q. t9 R" e4 a3 q- `{* ^5 y% l. M  j9 X) B6 y" g* }) L0 V
    //IP控件中的IP串至少有一部分不是空的
5 Q! |- O9 ]- p# f5 @; C/ z}
  `8 v) ~/ O4 T9 M
: p; I8 G3 m/ d1 L. v●IP控件的通知消息●
  N' x, |: Q) o* |" p当IP串被改动后或者输入焦点发生了转移,IP控件就会向它的父窗口发送通知消息IPN_FIELDCHANGED。在大多数情况下,我们都可以忽略此通知消息。以下是处理通知消息IPN_FIELDCHANGED的一个示例:+ O9 @, _0 @" y
7 D7 J7 F4 V+ i5 A
void __fastcall TForm1::WndProc(TMessage &Msg)
8 A6 _, C" w; U5 e* K8 j{/ x9 Y+ E2 X5 n3 e
    LPNMHDR p=(LPNMHDR)Msg.LParam;
& C) d( W) ^8 Z3 Q/ o9 J    if(Msg.Msg==WM_NOTIFY): Y) f! K6 i, Y7 j+ A  l7 U
    {
- {; N+ n; c# D) q2 j        if(p->code==IPN_FIELDCHANGED)& g. ^6 q" E9 Y6 A7 @
        {
9 v, M4 u& m" l' V' x  L: r, ?            //处理IP控件的IPN_FIELDCHANGED通知消息' U3 _4 I( E0 L
        }
5 o/ u% F; E" h, b8 j    }' t$ D+ J9 y& a1 P% [% P9 C
    TForm::WndProc(Msg);
+ D, }. a. @% Z2 {  W/ N}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-15 11:52 , Processed in 0.018594 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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