Paste from Pascal Newsletter #27:unit Unit1;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls;type TForm1 = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Label1: TLabel; Button1: TButton; Button2: TButton; ComboBox1: TComboBox; CheckBox1: TCheckBox; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } procedure ApplicationMessage(var Msg: TMsg; var Handled: Boolean); public { Public declarations } end;var Form1: TForm1;implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject); begin Application.OnMessage := ApplicationMessage; Visible := True; end;procedure TForm1.ApplicationMessage(var Msg: TMsg; var Handled: Boolean); var ActiveControl : TWinControl; Form : TCustomForm; ShiftState : TShiftState; KeyState : TKeyboardState; begin case Msg.Message of WM_KEYDOWN, WM_KEYUP: case Msg.wParam of VK_RETURN: // Replaces ENTER with TAB, and CTRL+ENTER with ENTER... begin GetKeyboardState(KeyState); ShiftState := KeyboardStateToShiftState(KeyState); if (ShiftState = []) or (ShiftState = [ssCtrl]) then begin ActiveControl := Screen.ActiveControl; if (ActiveControl is TCustomComboBox) and (TCustomComboBox(ActiveControl).DroppedDown) then begin if ShiftState = [ssCtrl] then begin KeyState[VK_LCONTROL] := KeyState[VK_LCONTROL] and $7F; KeyState[VK_RCONTROL] := KeyState[VK_RCONTROL] and $7F; KeyState[VK_CONTROL] := KeyState[VK_CONTROL] and $7F; SetKeyboardState(KeyState); end; end else if (ActiveControl is TCustomEdit) and not (ActiveControl is TCustomMemo) or (ActiveControl is TCustomCheckbox) or (ActiveControl is TRadioButton) or (ActiveControl is TCustomListBox) or (ActiveControl is TCustomComboBox) // You can add more controls to the list with "or" then if ShiftState = [] then begin Msg.wParam := VK_TAB end else begin // ShiftState = [ssCtrl] Msg.wParam := 0; if Msg.Message = WM_KEYDOWN then begin Form := GetParentForm(ActiveControl); if (Form <> nil) and (ActiveControl.Perform(CM_WANTSPECIALKEY, VK_RETURN, 0) = 0) and (ActiveControl.Perform(WM_GETDLGCODE, 0, 0) and DLGC_WANTALLKEYS = 0) then begin KeyState[VK_LCONTROL] := KeyState[VK_LCONTROL] and $7F; KeyState[VK_RCONTROL] := KeyState[VK_RCONTROL] and $7F; KeyState[VK_CONTROL] := KeyState[VK_CONTROL] and $7F; SetKeyboardState(KeyState); Form.Perform(CM_DIALOGKEY, VK_RETURN, Msg.lParam); end; end; end; end; end; VK_DOWN: begin GetKeyboardState(KeyState); if KeyboardStateToShiftState(KeyState) = [] then begin ActiveControl := Screen.ActiveControl; if (ActiveControl is TCustomEdit) and not (ActiveControl is TCustomMemo) // You can add more controls to the list with "or" then Msg.wParam := VK_TAB; end; end; VK_UP: begin GetKeyboardState(KeyState); if KeyboardStateToShiftState(KeyState) = [] then begin ActiveControl := Screen.ActiveControl; if (ActiveControl is TCustomEdit) and not (ActiveControl is TCustomMemo) // You can add more controls to the list with "or" then begin Msg.wParam := 0; if Msg.Message = WM_KEYDOWN then begin Form := GetParentForm(ActiveControl); if Form <> nil then // Move to previous control Form.Perform(WM_NEXTDLGCTL, 1, 0); end; end; end; end; // Replace the decimal point of the numeric key pad (VK_DECIMAL) // with a comma (key code = 188). For Spanish applications. VK_DECIMAL: begin GetKeyboardState(KeyState); if KeyboardStateToShiftState(KeyState) = [] then begin Msg.wParam := 188; end; end; end; end; end;procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage('Button1Click'); end;procedure TForm1.Button2Click(Sender: TObject); begin ShowMessage('Button2Click'); end;end.
if Key = 13 then begin findnextcontrol(Sender as TWinControl, true, true, false).SetFocus; end; 前提是每一个可转移焦点的控件的TabOrder 的顺序 和 TabStop = true;
在回车及光标键时根据taborder查找下一个control,然后setfocus
Form的KeyPress事件 if Key = #13 then SelectNext(ActiveControl,true,true);
非常感谢各位。问题已经解决!不过好像用 selectnext(sender as TwinControl,true,true),就不管用。不知这是为什么?
Form的KeyPress事件,设置Form的KeyPreview属性为True; if Key = #13 then SelectNext(ActiveControl,true,true);
就像按Tab键一样。
Paste from Pascal Newsletter #27:unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Label1: TLabel;
Button1: TButton;
Button2: TButton;
ComboBox1: TComboBox;
CheckBox1: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
procedure ApplicationMessage(var Msg: TMsg; var Handled: Boolean);
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := ApplicationMessage;
Visible := True;
end;procedure TForm1.ApplicationMessage(var Msg: TMsg;
var Handled: Boolean);
var
ActiveControl : TWinControl;
Form : TCustomForm;
ShiftState : TShiftState;
KeyState : TKeyboardState;
begin
case Msg.Message of
WM_KEYDOWN, WM_KEYUP:
case Msg.wParam of
VK_RETURN:
// Replaces ENTER with TAB, and CTRL+ENTER with ENTER...
begin
GetKeyboardState(KeyState);
ShiftState := KeyboardStateToShiftState(KeyState);
if (ShiftState = []) or (ShiftState = [ssCtrl]) then begin
ActiveControl := Screen.ActiveControl;
if (ActiveControl is TCustomComboBox) and
(TCustomComboBox(ActiveControl).DroppedDown) then begin
if ShiftState = [ssCtrl] then begin
KeyState[VK_LCONTROL] := KeyState[VK_LCONTROL] and $7F;
KeyState[VK_RCONTROL] := KeyState[VK_RCONTROL] and $7F;
KeyState[VK_CONTROL] := KeyState[VK_CONTROL] and $7F;
SetKeyboardState(KeyState);
end;
end else if (ActiveControl is TCustomEdit)
and not (ActiveControl is TCustomMemo)
or (ActiveControl is TCustomCheckbox)
or (ActiveControl is TRadioButton)
or (ActiveControl is TCustomListBox)
or (ActiveControl is TCustomComboBox)
// You can add more controls to the list with "or"
then
if ShiftState = [] then begin
Msg.wParam := VK_TAB
end else begin // ShiftState = [ssCtrl]
Msg.wParam := 0;
if Msg.Message = WM_KEYDOWN then begin
Form := GetParentForm(ActiveControl);
if (Form <> nil) and
(ActiveControl.Perform(CM_WANTSPECIALKEY,
VK_RETURN, 0) = 0) and
(ActiveControl.Perform(WM_GETDLGCODE, 0, 0)
and DLGC_WANTALLKEYS = 0) then
begin
KeyState[VK_LCONTROL] := KeyState[VK_LCONTROL] and $7F;
KeyState[VK_RCONTROL] := KeyState[VK_RCONTROL] and $7F;
KeyState[VK_CONTROL] := KeyState[VK_CONTROL] and $7F;
SetKeyboardState(KeyState);
Form.Perform(CM_DIALOGKEY, VK_RETURN, Msg.lParam);
end;
end;
end;
end;
end;
VK_DOWN:
begin
GetKeyboardState(KeyState);
if KeyboardStateToShiftState(KeyState) = [] then begin
ActiveControl := Screen.ActiveControl;
if (ActiveControl is TCustomEdit)
and not (ActiveControl is TCustomMemo)
// You can add more controls to the list with "or"
then
Msg.wParam := VK_TAB;
end;
end;
VK_UP:
begin
GetKeyboardState(KeyState);
if KeyboardStateToShiftState(KeyState) = [] then begin
ActiveControl := Screen.ActiveControl;
if (ActiveControl is TCustomEdit)
and not (ActiveControl is TCustomMemo)
// You can add more controls to the list with "or"
then
begin
Msg.wParam := 0;
if Msg.Message = WM_KEYDOWN then begin
Form := GetParentForm(ActiveControl);
if Form <> nil then // Move to previous control
Form.Perform(WM_NEXTDLGCTL, 1, 0);
end;
end;
end;
end;
// Replace the decimal point of the numeric key pad (VK_DECIMAL)
// with a comma (key code = 188). For Spanish applications.
VK_DECIMAL:
begin
GetKeyboardState(KeyState);
if KeyboardStateToShiftState(KeyState) = [] then begin
Msg.wParam := 188;
end;
end;
end;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Button1Click');
end;procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage('Button2Click');
end;end.
begin
findnextcontrol(Sender as TWinControl, true, true, false).SetFocus;
end;
前提是每一个可转移焦点的控件的TabOrder 的顺序 和 TabStop = true;
if Key = #13 then
SelectNext(ActiveControl,true,true);
selectnext(sender as TwinControl,true,true),就不管用。不知这是为什么?
if Key = #13 then
SelectNext(ActiveControl,true,true);