回车键代替TAB键带来的麻烦!!!(30分)

  • 主题发起人 主题发起人 HHSH
  • 开始时间 开始时间
H

HHSH

Unregistered / Unconfirmed
GUEST, unregistred user!
用下面的函数实现回车键代替TAB键后,麻烦来了。
一个窗口中有一个dbgrid、两个dbmemo,我希望在dbgrid中及在控件之间按回车键时实现
焦点转移到是很顺利的实现了,但希望在dbmemo中打回车键时实现换行而不是焦点转移,
请问如何实现?
procedure TForm_main.DoEnterAsTab(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.Message = WM_KEYDOWN then
begin
if Msg.wParam = VK_RETURN Then
Keybd_event(VK_TAB, 0, 0, 0);
end;
end;
procedure TForm_main.FormCreate(Sender: TObject);
begin
Application.OnMessage := DoEnterAsTab;
end;
 
在dbmemo中的onkeypress事件中重新定义一遍,不让他从父类中响应消息。
没试,你自己试一遍。
不行的话,你就得定义每个控件的onkeypress事件,比较麻烦。
 
试试这个:
procedure Tform1.ComboBox1KeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
begin
if Key=13 Then Perform(WM_NEXTDLGCTL,0,0);
end;
 
ase Key of
VK_Return://响应回车键。
begin
if not (ActiveControl is TDBGrid) and not (ActiveControl is TdbMemo) then
begin
PerForm(WM_NEXTDLGCTL, 0, 0);
end
else if (ActiveControl is TDBGrid) then
with TDBGrid(ActiveControl) do
if selectedIndex < (FieldCount - 1) then
selectedIndex := selectedIndex + 1
else
selectedIndex := 0;
end;
 
TO ugvanxk:
请问你这段代码是放在TForm_main.DoEnterAsTab()中,还是当前窗口的keypress()中。
 
放到KeyPress中,将窗体的KeyPreview设置为True。
 
to 飘摇客:
我按老兄说的试了下,但有两个问题:
(1)在dbmemo中打回车倒是能换行了,但留不住焦点。
(2)在dbgrid中打回车不是跳到相邻的下一列中,而是多跳了一列。
另外,应该把VK_Return改成#13吧?
请指点!
 
上面缺少一句key=#0;完整的如下,另外在DBGrid中试了没有你说的情况:
if Key = #13 then
if not ((ActiveControl is TDBGrid) or (ActiveControl is TMemo)) then
begin
Key := #0;
Perform(WM_NEXTDLGCTL, 0, 0);
end
else
if (ActiveControl is TDBGrid) then
begin
with TDBGrid(ActiveControl) do
if SelectedIndex < (FieldCount - 1) then
SelectedIndex := SelectedIndex + 1
else
SelectedIndex := 0;
end;
 
有一个DOSMOVE的控件专用于回车替代TAB的,
印象里是带源码的,挺好用,你参考一下。
 
把下面的代码放到公共窗口的OnKeyup事件中。
procedure SetFocusToNext(Form: TObject; Key: Word);
begin
with Form as TForm do
case Key of
VK_Return://响应回车键。
begin
if not (ActiveControl is TDBGrid) and not (ActiveControl is TMemo) then
begin
PerForm(WM_NEXTDLGCTL, 0, 0);
end
else if (ActiveControl is TDBGrid) then
with TDBGrid(ActiveControl) do
if selectedIndex < (FieldCount - 1) then
selectedIndex := selectedIndex + 1
else
selectedIndex := 0;
end;
VK_ESCape://响应ESC键。
begin
if application.MessageBox('是否关闭当前窗口?', 'RelTest', MB_YesNo + MB_ICONQUESTION) = id_yes then
Close;
end;
44 {VK_Print}://响应打印键。
if application.MessageBox('打印当前窗口吗?', 'RelTest', MB_YesNo + MB_ICONQUESTION) = id_yes then
begin
Print;
end;
end;
end;
 
to 飘摇客:
谢谢回答。按老兄说的,可行!但是还有疑问:
我发现,要想实现你说的功能,就不能再使用原来的那个函数了,否则就会出现我上面
说的那两个问题。但这样,就麻烦了。那个函数是个全局函数,在整个应用中都在使用,
我是想在不改变它的前提下,能使当前窗口中的dbmemo能正常换行就行了。
请老兄再指点一下,给个周全之计。
 
那就直接在Tmemo的KeyPress事件中写入
if Key=#13 then
key:=0;
应该就可以了吧。
 
to 飘摇客:
不行。这样,在dbmemo中就不能换行了,打回车后就直接跳到下一个控件上去了。
 
说错了,使用前一个给你的函数应该可以的,没有出现你说的情况,可能是我的理解有问题
能再说明白些吗?
 
笨方法,也可行:
procedure TForm_main.DoEnterAsTab(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.Message = WM_KEYDOWN then
begin
if Msg.wParam = VK_RETURN Then
if ActiveControl <> DBMemo then
Keybd_event(VK_TAB, 0, 0, 0);
end;
end;
 
To DarwinZhang:
这个方法成功了一半!打回车时,在dbgrid中能代替Tab,在dbmemo中也能实现换行。但美中
不足的是dbmemo中不能留住焦点,换行后就跑到其他控件上去了,还是不方便!
请继续指点。
 
DOSMOVE是最好用的了。。自己好好改改里面的代码就能很好的适应你的需求了。。
 
这样应该可以:
procedure TForm1.DoEnterAsTab(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.Message = WM_KEYDOWN then
begin
if Msg.wParam = VK_RETURN Then
if not(ActiveControl is TDBMemo) then
Keybd_event(VK_TAB, 0, 0, 0);
end;
end;
 
TO forss:
何处有dosmove控件?
To DarwinZhang:
我就是这么做的。因为你上次写的代码有点bug.我现在用的与你这次写的完全一样,但
结果就是我说的。
没什么好办法了吗?

 
我的机器上没有你的问题,如果你确有问题可能是:
1有其它的函数或控件在干扰.
2Delphi的具体版本问题.
你可以先试一下下面的代码,不行的话最好把你的程序贴出来,把情况讲详细一些,
procedure TForm1.DoEnterAsTab(var Msg: TMsg; var Handled: Boolean);
var
Temp:TWinControl;
begin
if Msg.Message = WM_KEYDOWN then
begin
if Msg.wParam = VK_RETURN Then
if not(ActiveControl is TDBMemo) then
begin
Temp:=ActiveControl;
Keybd_event(VK_TAB, 0, 0, 0);
Application.ProcessMessages;
Temp.SetFocus;
end;
end;
end;
 
后退
顶部