如何用回车键实现FORM中所有组件的焦点切换(15分)

Z

zyb

Unregistered / Unconfirmed
GUEST, unregistred user!
如何用回车键实现某FORM中所有组件的焦点切换?
本人曾利用FORM的ONKEYDOWN事件,判断KEY=#13
则利用PERFORM(WM_NEXTDLGCTL,0,0)实现,但
当焦点不在窗体上时,如何截获键盘消息是一个问题。
另外,是否有别的妙方呢?
 
application.OnMessage里处理
 
顺便提醒一句, 真正要做好enter替换tab并不容易.
举个简单的例子:
form上有一个edit, 一个memo, 一个stringgrid, 一个dbgrid.
memo不允许多行? stringgrid不允许编辑(默认状态时)?
呵呵, 判断什么时候应该用enter替换tab的工作量很大的.
 
呵呵,确实这是个问题.
 
我的方法:
1、先利用控件的TAG属性进行编号(TAG 是保留的一个整型量)
2、编写一个控件查询函数,来找到获得焦点的下一个控件
3、在需要响应ENTER事件的控件的KEYPASS事件中加入控件查询函数,移动焦点
 
可以利用类似的方法实现
procedure tform1.focusnext(thistag:integer);
var
I:integer;
begin
for i:=0 to ControlCount-1 do
if Controls.Tag =thistag+1 then
ActiveControl:=twincontrol(controls);
end;
 
说明:
当焦点控件为TMemo类,同时按下Shift键和Enter,既可在Memo中回车
对Richedit之类控件,同样加上去既可实现回车.
将Form窗的属性KeyPreView 设置为True;
procedure TForm1.FormKeyDown(Sender: TObject;
var Key: Word;
Shift: TShiftState);
begin
if (ActiveControl <> nil) and (Key = VK_RETURN) then
begin
if ssShift in Shift then
begin
if ActiveControl is TMemo then
begin
;
end
else
ActiveControl := FindNextControl(
ActiveControl as TWinControl, False, True,False)
End
else
ActiveControl := FindNextControl(
ActiveControl as TWinControl, True, True, False);
End
end;

procedure TForm1.FormKeyPress(Sender: TObject;
var Key: Char);
begin
if (Key = Char(VK_RETURN)) and (not (ActiveControl is TMemo)) then

Key := #0;
end;
 
用selectnext()怎么样?
 
procedure TQueryForm.FormKeyPress(Sender: TObject;
var Key: Char);
begin
if key=#13 then
begin
key:=#0;
Perform(CM_DialogKey,VK_TAB,0);
end;
end;
我的这段代码为什么没有用???????
 
form.keypreview:=true;
 
先将TForm1的KeyPreview设置为true.
然后加入:
procedure TForm1.FormKeyPress(Sender: TObject;
var Key: Char);
begin
if (Key = #13) then
begin
key := #0;
Perform(WM_NEXTDLGCTL, 0, 0);
end;
end;
 
还是建议:
TForm1的KeyPreview设置为true.
然后加入:
procedure TForm1.FormKeyPress(Sender: TObject;
var Key: Char);
begin
if (Key = #13) then
begin
key := #0;
Perform(WM_NEXTDLGCTL, 0, 0);
end;
end;
当然,你也可通过判断Sender来确定下一个得到焦点的控件.
 
可用一函数:
如:
假设Form1有:
Edit1:Tedit;
Edit2:TEdit;
要在此连控件中实现焦点切换:
procedure TForm1.Edit1KeyDown(Sender: TObject;
var Key: Word;
Shift: TShiftState);
begin
if Key=vk_Return then
PostMessage(0,VK_Tab,0,0);//like the 'tab' button pressed.
end;

 
这问题怎么还在这里?
 
可以在每个可编辑的控件的OnKeyDown事件上写一下一句
if key = VK_Return then
keybd_event( VK_TAB, MapVirtualKey( VK_TAB, 0 ), 0 , 0 );
来模拟按Tab键
 
procedure TForm2.FormKeyDown(Sender: TObject;
var Key: Word;
Shift: TShiftState);
begin
if (key=13) and (not(shift>=[ssShift])) and (not(activecontrol is TDbMemo))then
SelectNext(activecontrol,true,true);
end;
 
sorry 觉得你的代码比较好,所以想往自己的信箱里发一封
说明:
当焦点控件为TMemo类,同时按下Shift键和Enter,既可在Memo中回车
对Richedit之类控件,同样加上去既可实现回车.
将Form窗的属性KeyPreView 设置为True;
procedure TForm1.FormKeyDown(Sender: TObject;
var Key: Word;
Shift: TShiftState);
begin
if (ActiveControl <> nil) and (Key = VK_RETURN) then
begin
if ssShift in Shift then
begin
if ActiveControl is TMemo then
begin
;
end
else
ActiveControl := FindNextControl(
ActiveControl as TWinControl, False, True,False)
End
else
ActiveControl := FindNextControl(
ActiveControl as TWinControl, True, True, False);
End
end;

procedure TForm1.FormKeyPress(Sender: TObject;
var Key: Char);
begin
if (Key = Char(VK_RETURN)) and (not (ActiveControl is TMemo)) then

Key := #0;
end;
 
在一个form中实现各个控件的焦点切换可以使用如下方法:
首先设置form上的所有的控件的default属性为false.
对于每个控件的keydown事件,拦截enter键,并且设置下一个控件的setfocus.
 
我的心得:
procedure GotoNextTag(FrmName:TForm);
//在记录编辑画面里,从当前项跳到下一个可以编辑的项中
var intTag:integer;
i,j:integer;
flag:boolean;
tagArray:array[1..100] of integer;
begin
flag:=false;
with FrmNamedo
begin
for i:=1 to 100do
tagArray:=0;//初始化
// j:=ComponentCount;
for i:=0 to ComponentCount-1do
begin
j:=Components.tag;
if j>100 then
begin
MessageBeep(0);
showm('发现某控件的 Tag 值大于100,不能自动移位!');
exit;
end;
if j>0 then
tagArray[j]:=i+1;
end;
//endfor
inttag:=ActiveControl.Tag ;//当前控件
i:=intTag+1;//从下一个tag数开始
while i<=100do
begin
j:= tagArray;
if j>0 then
//找到tag比当前控件的tag 大的控件
begin
if (Components[j-1] as twincontrol).Enabled=True
and (Components[j-1] as twincontrol).Visible=True then
begin
(Components[j-1] as twincontrol).setfocus;
flag:=true;
break;
end;
//endif
end;
//endif
i:=i+1;
end;
//endwhile
if flag=false then
//找不到tag比当前控件的tag大的控件,则找tag 最小的控件
begin
for i:=1 to inttag-1do
begin
j:= tagArray;
if j>0 then
//找到tag最小的控件
begin
if (Components[j-1] as twincontrol).Enabled=True
and (Components[j-1] as twincontrol).Visible=True then
begin
(Components[j-1] as twincontrol).setfocus;
break;
end;
//endif
end;
//endif
end;
//endfor
end;
//endif
end;
//endwith
end;
 
that is not a good method to use enter changing the focus
the tab or the cursor key is the best :)
 

Similar threads

顶部