关于IP地址输入框的问题!!!

Slash 2009-02-13 04:36:00
使用CommCtrl显示WINDOWS标准IP地址输入框,发现一个很郁闷的问题,就是本地连接属性里面TCP/IP设置那个IP地址输入框可以用方向箭头键在4个项目之间移动,而通过CREATEWINDOW动态创建出来的就不行(直接失去焦点跑到别的控件去了),不知道该怎么解决

BTW:好久没来,实在没分,希望大家别介意:)
...全文
600 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
cranley 2009-03-05
  • 打赏
  • 举报
回复
IP控件窗口风格不一致的问题。。。

使用SPY++查一下两种的窗口风格有什么差异。。

This is too easy.
雷布斯尼亚 2009-03-05
  • 打赏
  • 举报
回复
mark
ajiwuweibin 2009-02-19
  • 打赏
  • 举报
回复
没分没人顶,有分就帮顶。
Slash 2009-02-19
  • 打赏
  • 举报
回复
还有个问题,虽然按这方法可以实现移动,但是跟TCP/IP属性里面的IP输入框还是不太一样,自己实现的是先全选,然后有几个数字就需要移动几次,相当于要按N+1次才会移动到下一段,而系统的是不会有选中这一次的
Slash 2009-02-19
  • 打赏
  • 举报
回复
第三个其实昨天回帖之后就自己解决了,不过发帖老说我我灌水,晕

关于第四个问题,我是这么考虑的,如果在TFRAME里面直接改变工程默认消息处理,万一工程的其他应用也要自定义消息处理,可能会存在冲突,所以我想能否直接在TFRAME内部拦截动态创建出来的IP控件按键消息,但是我子类化后并不能拦截到,估计又是DELPHI的消息处理机制引起的
Slash 2009-02-18
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 unsigned 的回复:]
大致看了一下,应该是Delphi的消息处理上面的问题。如果是一个由TWinControl继承下来的控件,并对某些消息做出响应应该就不会有这个问题了。
[/Quote]

如果派生自TWinControl,肯定不会有这样的问题了,但是通过SDK的方式来使用系统组件,应该也是需要的啊,在这方面M$就做的好多了
yc_8301 2009-02-18
  • 打赏
  • 举报
回复
顶一下。。学习
僵哥 2009-02-18
  • 打赏
  • 举报
回复
大致看了一下,应该是Delphi的消息处理上面的问题。如果是一个由TWinControl继承下来的控件,并对某些消息做出响应应该就不会有这个问题了。
Slash 2009-02-18
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 xiedewei 的回复:]
经过测试,5楼是乱说,其实'SysIPAddress32'本身是具有方向键控制功能的,而且与TCP/IP属性的是一样的。
但前提是窗体上没有别的能获得焦点的控件。
似乎用类似方法创建的其他控件也有类似问题,什么原因有待大家研究一下。
[/Quote]

这位朋友的意见跟我一致,我感觉是因为DELPHI的窗口消息机制处理方式于系统有冲突而引起的,哪怕是创建一个EDIT,也有类似问题,所以说这个应该是普遍性问题
genispan 2009-02-18
  • 打赏
  • 举报
回复
MARK
xiedewei 2009-02-18
  • 打赏
  • 举报
回复
1,3.
  if (GetParent(Msg.hwnd) = IPEdit) and (Msg.message = WM_KEYDOWN)
and (Msg.wParam in [VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN]) then
begin
case Msg.wParam of
VK_LEFT, VK_UP: D := -1;
VK_RIGHT, VK_DOWN: D := 1;
end;
SendMessage(Msg.hwnd, EM_GETSEL, WPARAM(@P1), 0);
SendMessage(Msg.hwnd, EM_SETSEL, P1 + D, P1 + D);
SendMessage(Msg.hwnd, EM_GETSEL, WPARAM(@P2), 0);
if P1 = P2 then
begin
GetWindowRect(IPEdit, R1);
GetWindowRect(Msg.hwnd, R2);
Inc(D, (R2.Left - R1.Left) div ((R1.Right - R1.Left) shr 2));
SendMessage(IPEdit, IPM_SETFOCUS, (D + 4) mod 4, 0);
end;
Handled := True;
end;

4.没问题
xiedewei 2009-02-18
  • 打赏
  • 举报
回复
我想用'SysIPAddress32'做成一个'TIPEdit'(参考TEdit),可是也不大好办,为什么delphi没有这样一个'TIPEdit'呢,可能也是这个原因吧。
xiedewei 2009-02-18
  • 打赏
  • 举报
回复
将SendMessage(IPEdit, IPM_SETFOCUS, D, 0);
改为SendMessage(IPEdit, IPM_SETFOCUS, (D + 4) mod 4, 0);
就可以左右循环移动了。
Slash 2009-02-18
  • 打赏
  • 举报
回复
第二个问题应该不是代码的问题,只要有数据,确实会存在多次按键才移动到下一段的情况
Slash 2009-02-18
  • 打赏
  • 举报
回复
感谢xiedewei,你的代码我试过可以实现,不过有几个问题想再了解下:

1、右移的时候当焦点在最后一段时会自动跳到第一段,而左移时当焦点在第一段时不会自动跳到最后一段,虽然是小问题,但是如果能解决就更好了;

2、我是用CB的,代码转过去后,移动时都需要按两次方向键才会生效,下面是代码,不知道问题出在哪里;

int P1,P2,D;
TRect R1,R2;

if (GetParent(Msg.hwnd) == hWndIPAddress && Msg.message == WM_KEYDOWN)
{
if (Msg.wParam == VK_LEFT || Msg.wParam == VK_RIGHT)
{
D = Msg.wParam - 38;
SendMessage(Msg.hwnd, EM_GETSEL, (WPARAM)&P1, 0);
SendMessage(Msg.hwnd, EM_SETSEL, P1 + D, P1 + D);
SendMessage(Msg.hwnd, EM_GETSEL, (WPARAM)&P2, 0);

if (P1 == P2)
{
GetWindowRect(hWndIPAddress, &R1);
GetWindowRect(Msg.hwnd, &R2);
D += (R2.Left - R1.Left) / ((R1.Right - R1.Left) >> 2);

SendMessage(hWndIPAddress, IPM_SETFOCUS, D, NULL);
}

Handled = true;
}
}

3、TCP/IP属性里的IP组件,四个方向键都能使用,左和上为左移,右和下为右移,你的代码通过虚拟键码减去38来判断左右方向键,要如何才能同时判断上下方向键呢;

4、我是在一个TFrame上动态创建IP控件,可能是多个Form上使用,你的代码是通过改变工程默认消息处理来实现,会有问题吗?
xiedewei 2009-02-17
  • 打赏
  • 举报
回复
用钩子试试吧
Slash 2009-02-17
  • 打赏
  • 举报
回复
动态创建的对象,要如何相应其消息,比如我要接收LPN_FIELDCHANGED
xiedewei 2009-02-17
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 Slash 的回复:]
其实系统IP输入组件有IPM_SETFOCUS消息,可以指定焦点在其中的某一个FIELD上,但是没有相应的方法可以得到当前处于哪个FIELD,否则用这个也能实现方向键的定位
[/Quote]
按这个思路我试了一下,基本实现了左右方向键控制:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, CommCtrl, StdCtrls, ComCtrls, ToolWin;

type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure AppMsg(var Msg: TMsg; var Handled: Boolean);
end;

var
Form1: TForm1;
IPEdit: HWND;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := AppMsg;
IPEdit := CreateWindow('SysIPAddress32', 'IPEdit', WS_CHILD or WS_VISIBLE,
100, 100, 121, 21, Handle, 0, HInstance, nil);
end;

procedure TForm1.AppMsg(var Msg: TMsg; var Handled: Boolean);
var
P1, P2, D: Integer;
R1, R2: TRect;
begin
if (GetParent(Msg.hwnd) = IPEdit) and (Msg.message = WM_KEYDOWN)
and (Msg.wParam in [VK_LEFT, VK_RIGHT]) then
begin
D := Msg.wParam - 38;
SendMessage(Msg.hwnd, EM_GETSEL, WPARAM(@P1), 0);
SendMessage(Msg.hwnd, EM_SETSEL, P1 + D, P1 + D);
SendMessage(Msg.hwnd, EM_GETSEL, WPARAM(@P2), 0);
if P1 = P2 then
begin
GetWindowRect(IPEdit, R1);
GetWindowRect(Msg.hwnd, R2);
Inc(D, (R2.Left - R1.Left) div ((R1.Right - R1.Left) shr 2));
SendMessage(IPEdit, IPM_SETFOCUS, D, 0);
end;
Handled := True;
end;
end;

end.
xiedewei 2009-02-17
  • 打赏
  • 举报
回复
经过测试,5楼是乱说,其实'SysIPAddress32'本身是具有方向键控制功能的,而且与TCP/IP属性的是一样的。
但前提是窗体上没有别的能获得焦点的控件。
似乎用类似方法创建的其他控件也有类似问题,什么原因有待大家研究一下。
Slash 2009-02-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 bdmh 的回复:]
ip地址可以用方向键,是应为该输入框做了处理个别键的方法,CREATEWINDOW不会把这些东西带过来,你只有自己处理了

参考,不知是否能给你思路
http://topic.csdn.net/t/20031220/10/2584050.html
[/Quote]

多谢这位朋友提供的思路!

不过原帖中通过子类化的方式似乎还是没有解决问题,而我现在是在TFRAME上CREATEWINDOW出系统的IP输入组件,应该是与在TFORM上类似
加载更多回复(16)

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧