最近需要用一个IP输入控件,网上找了几个,都不符合效果,有些还有一些奇怪的Bug。后来发现原来系统已经提供了IP地址编辑控件,只是系统提供的控件不能设置只读效果。网上找了下资料,封装了一下,自己迂回一下实现了只读效果。

源码下载

  1. unit ueIPEdit;
  2. interface
  3. uses
  4. System.SysUtils, System.Classes, Vcl.Controls, Winapi.Windows, Winapi.Messages,
  5. Vcl.ComCtrls, Winapi.CommCtrl;
  6. type
  7. TFieldChangeEvent = procedure(Sender: TObject; OldField, OldValue: Byte) of object;
  8. TUeIPEdit = class(TWinControl)
  9. private
  10. FState: Integer; //Internal use
  11. FBakIP: Longint; //Internal use
  12. FMinIP: Longint;
  13. FMaxIP: Longint;
  14. FOnChange: TNotifyEvent;
  15. FOnFieldChange: TFieldChangeEvent;
  16. procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
  17. procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
  18. protected
  19. procedure CreateParams(var Params: TCreateParams); override;
  20. function  GetMinIP: String;
  21. function  GetMaxIP: String;
  22. procedure SetMinIP(const Value: String);
  23. procedure SetMaxIP(const Value: String);
  24. procedure UpdateRange;
  25. function  GetIP: String;
  26. procedure SetIP(const Value: String);
  27. function  GetEmpty: Boolean;
  28. function GetReadOnly: Boolean;
  29. procedure SetReadOnly(Value: Boolean);
  30. function IPToString(const AIp: Longint): String;
  31. function StringToIP(const Value: String): Longint;
  32. public
  33. constructor Create(AOwner: TComponent); override;
  34. procedure Clear;
  35. procedure SetActiveField(const Value: Integer);
  36. property Empty: Boolean read GetEmpty;
  37. property ReadOnly: Boolean read GetReadOnly write SetReadOnly;
  38. property IP: String read GetIP write SetIP;
  39. property MinIP: String read GetMinIP write SetMinIP;
  40. property MaxIP: String read GetMaxIP write SetMaxIP;
  41. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  42. property OnIPFieldChange: TFieldChangeEvent read FOnFieldChange write FOnFieldChange;
  43. property Font;
  44. property ParentColor;
  45. property ParentFont;
  46. property ParentShowHint;
  47. property PopupMenu;
  48. property ShowHint;
  49. property TabOrder;
  50. property TabStop;
  51. property Tag;
  52. property DragCursor;
  53. property DragMode;
  54. property HelpContext;
  55. end;
  56. implementation
  57. uses Vcl.Graphics;
  58. constructor TUeIPEdit.Create(AOwner: TComponent);
  59. const
  60. EditStyle = [csClickEvents, csSetCaption, csDoubleClicks, csFixedHeight, csPannable];
  61. begin
  62. inherited Create(AOwner);
  63. if NewStyleControls then
  64. ControlStyle := EditStyle else
  65. ControlStyle := EditStyle + [csFramed];
  66. ParentColor := False;
  67. Color := clWindow;
  68. Width:= 130;
  69. Height:= 20;
  70. TabStop:= True;
  71. FState := 0;
  72. FBakIP := -1;
  73. FMinIP:= 0;
  74. FMaxIP:= $0FFFFFFFF;
  75. FOnChange:= nil;
  76. FOnFieldChange:= nil;
  77. end;
  78. procedure TUeIPEdit.CreateParams(var Params: TCreateParams);
  79. begin
  80. InitCommonControl(ICC_INTERNET_CLASSES);
  81. inherited CreateParams(Params);
  82. CreateSubClass(Params, WC_IPADDRESS);
  83. with Params do
  84. begin
  85. Style := WS_VISIBLE or WS_BORDER or WS_CHILD;
  86. if NewStyleControls and Ctl3D then
  87. begin
  88. Style := Style and not WS_BORDER;
  89. ExStyle := ExStyle or WS_EX_CLIENTEDGE;
  90. end;
  91. end;
  92. end;
  93. procedure TUeIPEdit.CNNotify(var Message: TWMNotify);
  94. begin
  95. if (FState=0) and Assigned(FOnFieldChange) and
  96. (Message.NMHdr^.code=IPN_FIELDCHANGED) then
  97. FOnFieldChange(Self, PNMIPAddress(Message.NMHdr)^.iField,
  98. PNMIPAddress(Message.NMHdr)^.iValue);
  99. end;
  100. procedure TUeIPEdit.CNCommand(var Message: TWMCommand);
  101. begin
  102. if (Message.NotifyCode = EN_CHANGE) then
  103. begin
  104. case FState of
  105. 0: if Assigned(FOnChange) then FOnChange(Self);
  106. 1: begin
  107. FState := 2;
  108. PostMessage(Handle, IPM_SETADDRESS, 0, FBakIP);
  109. end;
  110. 2: FState := 1;
  111. end;
  112. end;
  113. end;
  114. function TUeIPEdit.IPToString(const AIp: Longint): String;
  115. begin
  116. Result:= Format('%d.%d.%d.%d',[FIRST_IPADDRESS(AIp),SECOND_IPADDRESS(AIp),
  117. THIRD_IPADDRESS(AIp),FOURTH_IPADDRESS(AIp)]);
  118. end;
  119. function TUeIPEdit.StringToIp(const Value: String): Longint;
  120. var
  121. B: array[0..3] of Byte;
  122. Strs: TArray<string>;
  123. i, Cnt : Integer;
  124. begin
  125. B[0]:= 0;
  126. B[1]:= 0;
  127. B[2]:= 0;
  128. B[3]:= 0;
  129. if Value<>'' then
  130. begin
  131. Strs := Value.Split(['.'],TStringSplitOptions.ExcludeEmpty);
  132. try
  133. Cnt := Length(Strs);
  134. if Cnt>4 then Cnt := 4;
  135. for i := 0 to Cnt-1 do
  136. B[i] := StrToInt(Strs[i]);
  137. finally
  138. Strs := nil;
  139. end;
  140. end;
  141. Result:= MakeIPAddress(b[0], b[1], b[2], b[3]);
  142. end;
  143. function TUeIPEdit.GetIP: String;
  144. var
  145. AIp: Longint;
  146. begin
  147. SendMessage(Handle, IPM_GETADDRESS, 0, Longint(@AIp));
  148. Result:= IPToString(AIp);
  149. end;
  150. procedure TUeIPEdit.SetIP(const Value: String);
  151. begin
  152. SendMessage(Handle, IPM_SETADDRESS, 0, StringToIp(Value));
  153. end;
  154. function TUeIPEdit.GetMinIP: String;
  155. begin
  156. Result:= IPToString(FMinIP);
  157. end;
  158. procedure TUeIPEdit.SetMinIP(const Value: String);
  159. var
  160. AMin: LongInt;
  161. begin
  162. AMin := StringToIp(Value);
  163. if FMinIP<>AMin then
  164. begin
  165. FMinIP := AMin;
  166. UpdateRange;
  167. end;
  168. end;
  169. procedure TUeIPEdit.UpdateRange;
  170. begin
  171. SendMessage(Handle, IPM_SETRANGE, 0, MAKEIPRANGE(FIRST_IPADDRESS(FMinIP), FIRST_IPADDRESS(FMaxIP)));
  172. SendMessage(Handle, IPM_SETRANGE, 1, MAKEIPRANGE(SECOND_IPADDRESS(FMinIP), SECOND_IPADDRESS(FMaxIP)));
  173. SendMessage(Handle, IPM_SETRANGE, 2, MAKEIPRANGE(THIRD_IPADDRESS(FMinIP), THIRD_IPADDRESS(FMaxIP)));
  174. SendMessage(Handle, IPM_SETRANGE, 3, MAKEIPRANGE(FOURTH_IPADDRESS(FMinIP), FOURTH_IPADDRESS(FMaxIP)));
  175. end;
  176. procedure TUeIPEdit.SetMaxIP(const Value: String);
  177. var
  178. AMax: LongInt;
  179. begin
  180. AMax := StringToIp(Value);
  181. if FMaxIP<>AMax then
  182. begin
  183. FMaxIP := AMax;
  184. UpdateRange;
  185. end;
  186. end;
  187. function TUeIPEdit.GetMaxIP: String;
  188. begin
  189. Result:= IPToString(FMaxIP);
  190. end;
  191. function TUeIPEdit.GetReadOnly: Boolean;
  192. begin
  193. Result := FState<>0;
  194. end;
  195. procedure TUeIPEdit.SetReadOnly(Value: Boolean);
  196. begin
  197. if Value <> GetReadOnly then
  198. begin
  199. if Value then
  200. begin
  201. SendMessage(Handle, IPM_GETADDRESS, 0, Longint(@FBakIP));
  202. FState := 1;
  203. end else begin
  204. FState := 0;
  205. end;
  206. end;
  207. end;
  208. function TUeIPEdit.GetEmpty: Boolean;
  209. begin
  210. Result:= Boolean(SendMessage(Handle, IPM_ISBLANK, 0, 0));
  211. end;
  212. procedure TUeIPEdit.Clear;
  213. begin
  214. SendMessage(Handle, IPM_CLEARADDRESS, 0, 0);
  215. end;
  216. procedure TUeIPEdit.SetActiveField(const Value: Integer);
  217. begin
  218. if (Value < 4) then
  219. begin
  220. SendMessage(Handle, IPM_SETFOCUS, wParam(Value), 0);
  221. end;
  222. end;
  223. end.

http://blog.csdn.net/tht2009/article/details/50623816

IP编辑控件(因为封装的是系统自带控件,所以也使用了CreateSubClass,不过为啥要封装CN_COMMAND和CN_NOTIFY不是很明白)的更多相关文章

  1. 基于wke封装的duilib的webkit浏览器控件,可以c++与js互交,源码及demo下载地址

    转载请说明原出处,谢谢~~ 前些日子用wke内核封装了duilib的webkit浏览器控件,好多群里朋友私聊我希望可以我公布源码,今天把这个控件的源码和使用demo公布.其实这个控件封装起来没什么难度 ...

  2. 示例:WPF中Slider控件封装的缓冲播放进度条控件

    原文:示例:WPF中Slider控件封装的缓冲播放进度条控件 一.目的:模仿播放器播放进度条,支持缓冲任务功能 二.进度: 实现类似播放器中带缓存的播放样式(播放区域.缓冲区域.全部区域等样式) 实现 ...

  3. 使用 WebView2 封装一个生成 PDF 的 WPF 控件

    使用 WebView2 封装一个生成 PDF 的 WPF 控件 最近在迁移项目到 .net6,发现项目中用的 PDF 库不支持 .net6,于是想着换一个库.结果找了一大圈,发现不是版本不支持,就是收 ...

  4. Winform----自定义控件之半透明遮罩(蒙版遮盖指定控件)

    先贴运行效果图,源码点击这里下载 1.新建自定义控件 2.实现功能   namespace UserControlLib   {   [ToolboxBitmap(typeof(ZhLoading)) ...

  5. 《ASP.NET1200例》解决母版页报错“内容控件必须是内容页中的顶级控件,或是引用母版页的嵌套母版页。”

    VS2005下,添加了母版页这个控件,我们可以讲N个页面中共同的部分放在母版页来实现,并让WEB窗体集成自我们的母版页,就可以让我们的站点具有统一的风格了.在VS2005SP1之前的版本中,我们只能创 ...

  6. <Win32_14>__win32控件(2)__教你自学掌握所有控件的玩法

    学习win32 API 编程,我们应该善于利用微软给我们提供的一些辅助工具,例如大家都知道的MSDN.SPY++等等. 今天在讲述之前呢,先给大家介绍一个很有用的工具——Control Spy——它的 ...

  7. android 给LinearLayout中添加一定数量的控件,并让着一定数量的控件从右到左移动,每隔若干秒停顿一下,最后一个view链接第一个view,然后继续移动循环往复,形成一个死循环简单动画效果

    主类:IndexAnimationLinearLayout.java package com.yw.sortlistview; import java.util.ArrayList; import j ...

  8. FileUpload控件实现单按钮图片自动上传并带预览显示

    FileUpload控件实现单按钮图片自动上传并带预览显示 1.实现原理:   FileUpload控件默认不支持服务端的ONCHANGE事件,此时用一种变通的方法借用客户端的onchange事件,调 ...

  9. Android系统UI交互控件Action Bar初探

    过年期间,Google正式宣布取消Android系统中MENU键的使用,也就是基于Android 4.0系统的手机都应没有MENU这一固定按键.这无疑是个变革性的改动,在我眼中,这似乎把Android ...

随机推荐

  1. ASP.NET jQuery 随笔 在TextBox里面阻止复制、剪切和粘贴事件

    当用户要输入一些密码.信用卡信息和银行账号等敏感信息,用户更希望手工通过键盘敲入数据,而好过通过剪贴板复制粘贴. 我们先来看下实现后的效果: <%@ Page Language="C# ...

  2. MVC项目中如何判断用户是在用什么设备进行访问

    使用UAParser在C#MVC项目中如何判断用户是在用什么设备进行访问(手机,平板还是普通的电脑) 现在我们开发的很多web应用都要支持手机等移动设备.为了让手机用户能有更加好的用户体验,我们经常为 ...

  3. perl学习(5) 输入和输出

    1.1. 从标准输入设备输入 <STDIN> 行输入操作在到达文件的结尾时将返回undef,在while循环的条件中不能使用chomp: while (defined($line = &l ...

  4. 基于visual Studio2013解决C语言竞赛题之0405阶乘求和

      题目 解决代码及点评 这道题和上一道题类似,第n个累加项 = n-1累加项的n倍 由于有这个规律,我们可以用一个for循环实现 但是例子代码并没有这么做,大家可以回去修改下代码,使得代码更 ...

  5. 高屋建瓴 cocos2d-x-3.0架构设计 Cocos2d (v.3.0) rendering pipeline roadmap(原文)

    Cocos2d (v.3.0) rendering pipeline roadmap Why (the vision) The way currently Cocos2d does rendering ...

  6. (step5.1.3)hdu 1213( How Many Tables——1213)

    题目大意:输入两个整数n,m.分别表示点数.对点的操作的次数.在接下来的m行中,每行有两个整数a,b.表示a和b是好朋友.(不是好朋友的不能坐在同一个桌子上) .求需要多少张桌子 解题思路:并查集 1 ...

  7. 设置outlook自动回复

    当有同事需要出差时,或者不能即时回复邮件时,可用此功能. 下面列出设置步骤: 1.  首先,在桌面新建一个用以保存模板的文件夹,例如:emaii. 2.  新建一封邮件,输入你要自动回复的内容.另存为 ...

  8. [Swust OJ 352]--合并果子(贪心+队列模拟)

    题目链接:http://acm.swust.edu.cn/problem/352/ Time limit(ms): 1000 Memory limit(kb): 65535   Description ...

  9. JVM -- 类的初始化

    <深入理解Java虚拟机> 第二版中介绍到了类的加载过程. 一个类从加载入内存到卸载出内存为止,整个生命周期包括: Loading(加载)-----Verification(验证)---- ...

  10. 部署ASP.NET MVC项目

    目标:了解部署过程,掌握部署中出现问题该如何处理. 部署网站往往是一件麻烦事,因为在安装部署的过程中,经常有许多步骤要运行,对于许多不太熟悉IIS/SQL的新手来说,部署网站编程一件非常困难且危险的事 ...