对了 我的这个项目中的父窗体 定义了一个shortcut的过程 procedure ShortCut(var Message: TMessage); message WM_SHORTCUT; 代码是这样的: procedure TFrmBase.ShortCut(var Message: TMessage); begin Case Message.WParam of vk_F1 : if BtnNew.Enabled then BtnNew.OnClick(BtnNew); vk_F2 : if BtnEdit.Enabled then BtnEdit.OnClick(BtnEdit); vk_F3 : if BtnSave.Enabled then BtnSave.OnClick(BtnSave); vk_F4 : if BtnUndo.Enabled then BtnUndo.OnClick(BtnUndo); vk_F5 : if BtnDelete.Enabled then BtnDelete.OnClick(BtnDelete); vk_F6 : if BtnCopy.Enabled then BtnCopy.OnClick(BtnCopy); vk_F7 : if BtnImport.Enabled then BtnImport.OnClick(BtnImport); vk_F8 : if BtnFilter.Enabled then BtnFilter.OnClick(BtnFilter); vk_F9 : if BtnReFresh.Enabled then BtnReFresh.OnClick(BtnReFresh); vk_F10 : if BtnPrint.Enabled then BtnPrint.OnClick(BtnPrint); vk_F11 : if BtnCheck.Enabled then BtnCheck.OnClick(BtnCheck); vk_F12 : if BtnExit.Enabled then BtnExit.OnClick(BtnExit); end; end; 会不会和这个有关系呢? 也不对啊 之前我实现功能的那个窗体也有这个过程的 所不同的是那个是在自己的窗体中实现的 这个是在父窗体中实现的 会产生问题么?
对了 我的这个项目中的父窗体 定义了一个shortcut的过程 procedure ShortCut(var Message: TMessage); message WM_SHORTCUT; 代码是这样的: procedure TFrmBase.ShortCut(var Message: TMessage); begin Case Message.WParam of vk_F1 : if BtnNew.Enabled then BtnNew.OnClick(BtnNew); vk_F2 : if BtnEdit.Enabled then BtnEdit.OnClick(BtnEdit); vk_F3 : if BtnSave.Enabled then BtnSave.OnClick(BtnSave); vk_F4 : if BtnUndo.Enabled then BtnUndo.OnClick(BtnUndo); vk_F5 : if BtnDelete.Enabled then BtnDelete.OnClick(BtnDelete); vk_F6 : if BtnCopy.Enabled then BtnCopy.OnClick(BtnCopy); vk_F7 : if BtnImport.Enabled then BtnImport.OnClick(BtnImport); vk_F8 : if BtnFilter.Enabled then BtnFilter.OnClick(BtnFilter); vk_F9 : if BtnReFresh.Enabled then BtnReFresh.OnClick(BtnReFresh); vk_F10 : if BtnPrint.Enabled then BtnPrint.OnClick(BtnPrint); vk_F11 : if BtnCheck.Enabled then BtnCheck.OnClick(BtnCheck); vk_F12 : if BtnExit.Enabled then BtnExit.OnClick(BtnExit); end; end; 会不会和这个有关系呢? 也不对啊 之前我实现功能的那个窗体也有这个过程的 所不同的是那个是在自己的窗体中实现的 这个是在父窗体中实现的 会产生问题么?
procedure ShortCut(var Message: TMessage); message WM_SHORTCUT;这个项目的框架因为是别人完成的 所以我只能进行猜测 会不会是这个过程对消息进行拦截 然后根据按键消息进行判断呢 Case Message.WParam of vk_F1 : if BtnNew.Enabled then BtnNew.OnClick(BtnNew); vk_F2 : if BtnEdit.Enabled then BtnEdit.OnClick(BtnEdit); vk_F3 : if BtnSave.Enabled then BtnSave.OnClick(BtnSave); vk_F4 : if BtnUndo.Enabled then BtnUndo.OnClick(BtnUndo); vk_F5 : if BtnDelete.Enabled then BtnDelete.OnClick(BtnDelete); vk_F6 : if BtnCopy.Enabled then BtnCopy.OnClick(BtnCopy); vk_F7 : if BtnImport.Enabled then BtnImport.OnClick(BtnImport); vk_F8 : if BtnFilter.Enabled then BtnFilter.OnClick(BtnFilter); vk_F9 : if BtnReFresh.Enabled then BtnReFresh.OnClick(BtnReFresh); vk_F10 : if BtnPrint.Enabled then BtnPrint.OnClick(BtnPrint); vk_F11 : if BtnCheck.Enabled then BtnCheck.OnClick(BtnCheck); vk_F12 : if BtnExit.Enabled then BtnExit.OnClick(BtnExit); end; 在这个基窗体中也没有再找到其他的相关内容了 呵呵 小弟水平不高 只能这么猜测了~!
哦 我想起来了 好像还有个自写的控件 是在这里进行消息传递的吧unit KeyJump;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TJumpOptions = set of (moEnter,moUpDn); TKeyJump = class(TComponent) private FActive : boolean; FOptions : TJumpOptions; FEditNoBeep : boolean; FOwnerKeyDown : TKeyEvent; FOwnerKeyPress : TKeyPressEvent; FLastWasEdit : boolean; protected procedure NewKeyDown(Sender : TObject;var Key : word;Shift : TShiftState); procedure NewKeyPress(Sender : Tobject;var Key : char); public constructor Create(AOwner : TComponent); override; published property Active : boolean read FActive write FActive default true; property Options : TJumpOptions read FOptions write FOptions default [moEnter,moUpDn]; property EditNoBeep : boolean read FEditNoBeep write FEditNoBeep default true; end;const WM_SHORTCUT = WM_USER + $120; WM_HLPAPPEAR= WM_USER + $140; implementation//----------------------------------------------------------------------------- constructor TKeyJump.Create(AOwner : TComponent); var Loop : integer; tmpForm: TForm; begin // 首先检查是否已经存在本类控件 for Loop:=0 to AOwner.ComponentCount-1 do if AOwner.Components[Loop] is TKeyJump then raise EInvalidOperation.Create('TKeyJump can have only one instance per form'); // 创建控件实例,并设置参数的默认值 inherited Create(AOwner); FActive:=true; FOptions:=[moEnter,moUpDn]; FEditNoBeep:=true; //截取拥有者的 OnKeyDown 和 OnKeyPress 事件. tmpForm := GetParentForm(AOwner as TForm) as TForm; tmpForm.KeyPreview:=true; FOwnerKeyDown:=tmpForm.OnKeyDown; tmpForm.OnKeyDown:=NewKeyDown; FOwnerKeyPress:=tmpForm.OnKeyPress; tmpForm.OnKeyPress:=NewKeyPress;
end; // Create//----------------------------------------------------------------------------- procedure TKeyJump.NewKeyDown(Sender : TObject;var Key : word; Shift : TShiftState); var tmpForm: TForm; begin if FActive then begin tmpForm := GetParentForm(Owner as TForm) as TForm; //判断当前获得焦点的控件是否是从 TCustomEdit类继承下来的(必须是编辑类控件) FLastWasEdit:=(Owner as TForm).ActiveControl is TCustomEdit;
if ((Key = VK_F1) and (ssCtrl in SHIFT)) THEN //if ((key= VK_F1 + VK_CONTROL)) THEN tmpForm.Perform(WM_HLPAPPEAR, 0, 0) else if key in [vk_F1..vk_F12] then tmpForm.Perform(WM_SHORTCUT,key,0); if (FOptions<>[]) then begin // 特殊键的句柄 if Key <> VK_CONTROL + VK_RETURN then if ((Key=VK_DOWN) and (moUpDn in FOptions)) or ((Key=VK_RETURN) and (moEnter in FOptions)) then tmpForm.Perform(WM_NEXTDLGCTL,0,0) else if (Key=VK_UP) and (moUpDn in FOptions) then tmpForm.Perform(WM_NEXTDLGCTL,1,0); end; // if Options<>[] ... end; // if FActive ... // 完成控件的跳转控制后,调用拥有者控件本身的 OnKeyDown 方法 if assigned(FOwnerKeyDown) then FOwnerKeyDown(Sender,Key,Shift); end; // NewKeyDown//----------------------------------------------------------------------------- procedure TKeyJump.NewKeyPress(Sender : TObject;var Key : char); begin if FActive then begin // Handle 'Enter' key that makes Edits beep if FEditNoBeep and FLastWasEdit and (Key=#13) then Key:=#0; end; // if FActive ... // Call owner OnKeyPress if it's assigned if assigned(FOwnerKeyPress) then FOwnerKeyPress(Sender,Key); end; // NewKeyPressend.
// 完成控件的跳转控制后,调用拥有者控件本身的 OnKeyDown 方法 if assigned(FOwnerKeyDown) then FOwnerKeyDown(Sender,Key,Shift); 但是这个控件在执行完Keydown后 还是会调用窗体的Onkeydown事件 没道理会没有反应的呀!
procedure TRES_SOP_F.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var Model_no,Routing_no:string; Station,Pag:Integer; begin inherited; if not(qry_main.State in [dsinsert,dsedit]) then begin if ((Key=37) or (Key=39)) then begin if (not IsLRDown) then begin sSQL:=qry_main.SQL.Text; RecorIndex:=qry_main.RecNo; end; Pag:=qry_main.fieldbyname('Page').AsInteger; Model_no:=qry_main.fieldbyname('Model_no').AsString; Routing_no:=qry_main.fieldbyname('Routing_no').AsString; Station:=qry_main.fieldbyname('Station').AsInteger; end; case Key of 68:begin if Shift=[ssCtrl] then btnSB_SearchClick(Sender); end; 37: begin if Pag>1 then begin qry_main.Close; qry_main.SQL.Text:='select * from SOP_Main where Model_no='''+Model_no+''' and Routing_no='''+Routing_no+''' and Station='''+inttostr(Station)+''' and Page='''+inttostr(pag-1)+''''; qry_main.Open; IsLRDown:=True; end; end; 39: begin qry_op.Close; qry_op.SQL.Text:='select * from SOP_Main where Model_no='''+Model_no+''' and Routing_no='''+Routing_no+''' and Station='''+inttostr(Station)+''' and Page='''+inttostr(pag+1)+''''; qry_op.Open; if qry_op.RecordCount>0 then begin qry_main.Close; qry_main.SQL.Text:=qry_op.SQL.Text; qry_main.Open; IsLRDown:=True; end; end; 38: begin if IsLRDown then begin qry_main.Close; qry_main.SQL.Text:=sSQL; qry_main.Open; qry_main.RecNo:=RecorIndex; IsLRDown:=False; end; btn4Click(Sender); end; 40: begin if IsLRDown then begin qry_main.Close; qry_main.SQL.Text:=sSQL; qry_main.Open; qry_main.RecNo:=RecorIndex; IsLRDown:=False; end; btn2Click(Sender); end; end; end; end;
應該是對DELPHI 不太熟悉ONKEYDOWN,ONKEYUP可能的過程指針已經改變了,指向了其它地方,你要下對斷點才好調試 procedure ShortCut(var Message: TMessage); message WM_SHORTCUT; 代码是这样的: procedure TFrmBase.ShortCut(var Message: TMessage); begin showMessage('OK');// 加這麼一句看下,要先判斷到這個KEY是不是在這裏有響應,但沒有處理。再找 你的代碼裏什麼時候向 WM_ShortCut 發了消息。 Case Message.WParam of vk_F1 : if BtnNew.Enabled then BtnNew.OnClick(BtnNew); vk_F2 : if BtnEdit.Enabled then BtnEdit.OnClick(BtnEdit); vk_F3 : if BtnSave.Enabled then BtnSave.OnClick(BtnSave); vk_F4 : if BtnUndo.Enabled then BtnUndo.OnClick(BtnUndo); vk_F5 : if BtnDelete.Enabled then BtnDelete.OnClick(BtnDelete); vk_F6 : if BtnCopy.Enabled then BtnCopy.OnClick(BtnCopy); vk_F7 : if BtnImport.Enabled then BtnImport.OnClick(BtnImport); vk_F8 : if BtnFilter.Enabled then BtnFilter.OnClick(BtnFilter); vk_F9 : if BtnReFresh.Enabled then BtnReFresh.OnClick(BtnReFresh); vk_F10 : if BtnPrint.Enabled then BtnPrint.OnClick(BtnPrint); vk_F11 : if BtnCheck.Enabled then BtnCheck.OnClick(BtnCheck); vk_F12 : if BtnExit.Enabled then BtnExit.OnClick(BtnExit); end; end;
procedure ShortCut(var Message: TMessage); message WM_SHORTCUT;
代码是这样的:
procedure TFrmBase.ShortCut(var Message: TMessage);
begin
Case Message.WParam of
vk_F1 : if BtnNew.Enabled then BtnNew.OnClick(BtnNew);
vk_F2 : if BtnEdit.Enabled then BtnEdit.OnClick(BtnEdit);
vk_F3 : if BtnSave.Enabled then BtnSave.OnClick(BtnSave);
vk_F4 : if BtnUndo.Enabled then BtnUndo.OnClick(BtnUndo);
vk_F5 : if BtnDelete.Enabled then BtnDelete.OnClick(BtnDelete);
vk_F6 : if BtnCopy.Enabled then BtnCopy.OnClick(BtnCopy);
vk_F7 : if BtnImport.Enabled then BtnImport.OnClick(BtnImport);
vk_F8 : if BtnFilter.Enabled then BtnFilter.OnClick(BtnFilter);
vk_F9 : if BtnReFresh.Enabled then BtnReFresh.OnClick(BtnReFresh);
vk_F10 : if BtnPrint.Enabled then BtnPrint.OnClick(BtnPrint);
vk_F11 : if BtnCheck.Enabled then BtnCheck.OnClick(BtnCheck);
vk_F12 : if BtnExit.Enabled then BtnExit.OnClick(BtnExit);
end;
end;
会不会和这个有关系呢?
也不对啊 之前我实现功能的那个窗体也有这个过程的 所不同的是那个是在自己的窗体中实现的 这个是在父窗体中实现的 会产生问题么?
procedure ShortCut(var Message: TMessage); message WM_SHORTCUT;
代码是这样的:
procedure TFrmBase.ShortCut(var Message: TMessage);
begin
Case Message.WParam of
vk_F1 : if BtnNew.Enabled then BtnNew.OnClick(BtnNew);
vk_F2 : if BtnEdit.Enabled then BtnEdit.OnClick(BtnEdit);
vk_F3 : if BtnSave.Enabled then BtnSave.OnClick(BtnSave);
vk_F4 : if BtnUndo.Enabled then BtnUndo.OnClick(BtnUndo);
vk_F5 : if BtnDelete.Enabled then BtnDelete.OnClick(BtnDelete);
vk_F6 : if BtnCopy.Enabled then BtnCopy.OnClick(BtnCopy);
vk_F7 : if BtnImport.Enabled then BtnImport.OnClick(BtnImport);
vk_F8 : if BtnFilter.Enabled then BtnFilter.OnClick(BtnFilter);
vk_F9 : if BtnReFresh.Enabled then BtnReFresh.OnClick(BtnReFresh);
vk_F10 : if BtnPrint.Enabled then BtnPrint.OnClick(BtnPrint);
vk_F11 : if BtnCheck.Enabled then BtnCheck.OnClick(BtnCheck);
vk_F12 : if BtnExit.Enabled then BtnExit.OnClick(BtnExit);
end;
end;
会不会和这个有关系呢?
也不对啊 之前我实现功能的那个窗体也有这个过程的 所不同的是那个是在自己的窗体中实现的 这个是在父窗体中实现的 会产生问题么?
然后根据按键消息进行判断呢
Case Message.WParam of
vk_F1 : if BtnNew.Enabled then BtnNew.OnClick(BtnNew);
vk_F2 : if BtnEdit.Enabled then BtnEdit.OnClick(BtnEdit);
vk_F3 : if BtnSave.Enabled then BtnSave.OnClick(BtnSave);
vk_F4 : if BtnUndo.Enabled then BtnUndo.OnClick(BtnUndo);
vk_F5 : if BtnDelete.Enabled then BtnDelete.OnClick(BtnDelete);
vk_F6 : if BtnCopy.Enabled then BtnCopy.OnClick(BtnCopy);
vk_F7 : if BtnImport.Enabled then BtnImport.OnClick(BtnImport);
vk_F8 : if BtnFilter.Enabled then BtnFilter.OnClick(BtnFilter);
vk_F9 : if BtnReFresh.Enabled then BtnReFresh.OnClick(BtnReFresh);
vk_F10 : if BtnPrint.Enabled then BtnPrint.OnClick(BtnPrint);
vk_F11 : if BtnCheck.Enabled then BtnCheck.OnClick(BtnCheck);
vk_F12 : if BtnExit.Enabled then BtnExit.OnClick(BtnExit);
end;
在这个基窗体中也没有再找到其他的相关内容了 呵呵 小弟水平不高 只能这么猜测了~!
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;type
TJumpOptions = set of (moEnter,moUpDn); TKeyJump = class(TComponent)
private
FActive : boolean;
FOptions : TJumpOptions;
FEditNoBeep : boolean;
FOwnerKeyDown : TKeyEvent;
FOwnerKeyPress : TKeyPressEvent;
FLastWasEdit : boolean;
protected
procedure NewKeyDown(Sender : TObject;var Key : word;Shift : TShiftState);
procedure NewKeyPress(Sender : Tobject;var Key : char);
public
constructor Create(AOwner : TComponent); override;
published
property Active : boolean read FActive write FActive
default true;
property Options : TJumpOptions read FOptions write FOptions
default [moEnter,moUpDn];
property EditNoBeep : boolean read FEditNoBeep write FEditNoBeep
default true;
end;const
WM_SHORTCUT = WM_USER + $120;
WM_HLPAPPEAR= WM_USER + $140;
implementation//-----------------------------------------------------------------------------
constructor TKeyJump.Create(AOwner : TComponent);
var
Loop : integer;
tmpForm: TForm;
begin
// 首先检查是否已经存在本类控件
for Loop:=0 to AOwner.ComponentCount-1 do
if AOwner.Components[Loop] is TKeyJump then raise
EInvalidOperation.Create('TKeyJump can have only one instance per form'); // 创建控件实例,并设置参数的默认值
inherited Create(AOwner);
FActive:=true;
FOptions:=[moEnter,moUpDn];
FEditNoBeep:=true; //截取拥有者的 OnKeyDown 和 OnKeyPress 事件.
tmpForm := GetParentForm(AOwner as TForm) as TForm;
tmpForm.KeyPreview:=true;
FOwnerKeyDown:=tmpForm.OnKeyDown;
tmpForm.OnKeyDown:=NewKeyDown;
FOwnerKeyPress:=tmpForm.OnKeyPress;
tmpForm.OnKeyPress:=NewKeyPress;
end; // Create//-----------------------------------------------------------------------------
procedure TKeyJump.NewKeyDown(Sender : TObject;var Key : word;
Shift : TShiftState);
var
tmpForm: TForm;
begin if FActive then begin
tmpForm := GetParentForm(Owner as TForm) as TForm; //判断当前获得焦点的控件是否是从 TCustomEdit类继承下来的(必须是编辑类控件)
FLastWasEdit:=(Owner as TForm).ActiveControl is TCustomEdit;
if ((Key = VK_F1) and (ssCtrl in SHIFT)) THEN
//if ((key= VK_F1 + VK_CONTROL)) THEN
tmpForm.Perform(WM_HLPAPPEAR, 0, 0)
else
if key in [vk_F1..vk_F12] then
tmpForm.Perform(WM_SHORTCUT,key,0); if (FOptions<>[]) then begin // 特殊键的句柄
if Key <> VK_CONTROL + VK_RETURN then
if ((Key=VK_DOWN) and (moUpDn in FOptions)) or
((Key=VK_RETURN) and (moEnter in FOptions)) then
tmpForm.Perform(WM_NEXTDLGCTL,0,0)
else if (Key=VK_UP) and (moUpDn in FOptions) then
tmpForm.Perform(WM_NEXTDLGCTL,1,0);
end; // if Options<>[] ...
end; // if FActive ... // 完成控件的跳转控制后,调用拥有者控件本身的 OnKeyDown 方法
if assigned(FOwnerKeyDown) then FOwnerKeyDown(Sender,Key,Shift);
end; // NewKeyDown//-----------------------------------------------------------------------------
procedure TKeyJump.NewKeyPress(Sender : TObject;var Key : char);
begin
if FActive then begin
// Handle 'Enter' key that makes Edits beep
if FEditNoBeep and FLastWasEdit and (Key=#13) then Key:=#0; end; // if FActive ... // Call owner OnKeyPress if it's assigned
if assigned(FOwnerKeyPress) then FOwnerKeyPress(Sender,Key);
end; // NewKeyPressend.
if assigned(FOwnerKeyDown) then FOwnerKeyDown(Sender,Key,Shift); 但是这个控件在执行完Keydown后 还是会调用窗体的Onkeydown事件 没道理会没有反应的呀!
WM_SHORTCUT = WM_USER + $120; 這個終於看到了。但發送部分呢? 知道這個地方就知道問題在什麼地方了。
在認為你以前的兄弟寫的代碼不錯的情況下,你貼出來你創建窗體的代碼create(self) or Create(nil) or Create(父。。 )
觉得还是因为他而导致窗体没有接收到KeyDown事件。。
//截取拥有者的 OnKeyDown 和 OnKeyPress 事件.
tmpForm := GetParentForm(AOwner as TForm) as TForm;
tmpForm.KeyPreview:=true;
FOwnerKeyDown:=tmpForm.OnKeyDown;
tmpForm.OnKeyDown:=NewKeyDown;
FOwnerKeyPress:=tmpForm.OnKeyPress;
tmpForm.OnKeyPress:=NewKeyPress;发送的话是这里吧 截取拥有者的 OnKeyDown 和 OnKeyPress 事件. 从而产生消息 可以这样理解么?
procedure TRES_SOP_F.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
Model_no,Routing_no:string;
Station,Pag:Integer;
begin
inherited;
if not(qry_main.State in [dsinsert,dsedit]) then
begin
if ((Key=37) or (Key=39)) then
begin
if (not IsLRDown) then
begin
sSQL:=qry_main.SQL.Text;
RecorIndex:=qry_main.RecNo;
end;
Pag:=qry_main.fieldbyname('Page').AsInteger;
Model_no:=qry_main.fieldbyname('Model_no').AsString;
Routing_no:=qry_main.fieldbyname('Routing_no').AsString;
Station:=qry_main.fieldbyname('Station').AsInteger;
end;
case Key of
68:begin if Shift=[ssCtrl] then btnSB_SearchClick(Sender); end;
37:
begin
if Pag>1
then
begin
qry_main.Close;
qry_main.SQL.Text:='select * from SOP_Main where Model_no='''+Model_no+''' and Routing_no='''+Routing_no+''' and Station='''+inttostr(Station)+''' and Page='''+inttostr(pag-1)+'''';
qry_main.Open;
IsLRDown:=True;
end;
end;
39:
begin
qry_op.Close;
qry_op.SQL.Text:='select * from SOP_Main where Model_no='''+Model_no+''' and Routing_no='''+Routing_no+''' and Station='''+inttostr(Station)+''' and Page='''+inttostr(pag+1)+'''';
qry_op.Open;
if qry_op.RecordCount>0 then
begin
qry_main.Close;
qry_main.SQL.Text:=qry_op.SQL.Text;
qry_main.Open;
IsLRDown:=True;
end;
end;
38:
begin
if IsLRDown then
begin
qry_main.Close;
qry_main.SQL.Text:=sSQL;
qry_main.Open;
qry_main.RecNo:=RecorIndex;
IsLRDown:=False;
end;
btn4Click(Sender);
end;
40:
begin
if IsLRDown then
begin
qry_main.Close;
qry_main.SQL.Text:=sSQL;
qry_main.Open;
qry_main.RecNo:=RecorIndex;
IsLRDown:=False;
end;
btn2Click(Sender);
end;
end;
end;
end;
procedure ShortCut(var Message: TMessage); message WM_SHORTCUT;
代码是这样的:
procedure TFrmBase.ShortCut(var Message: TMessage);
begin
showMessage('OK');// 加這麼一句看下,要先判斷到這個KEY是不是在這裏有響應,但沒有處理。再找 你的代碼裏什麼時候向 WM_ShortCut 發了消息。
Case Message.WParam of
vk_F1 : if BtnNew.Enabled then BtnNew.OnClick(BtnNew);
vk_F2 : if BtnEdit.Enabled then BtnEdit.OnClick(BtnEdit);
vk_F3 : if BtnSave.Enabled then BtnSave.OnClick(BtnSave);
vk_F4 : if BtnUndo.Enabled then BtnUndo.OnClick(BtnUndo);
vk_F5 : if BtnDelete.Enabled then BtnDelete.OnClick(BtnDelete);
vk_F6 : if BtnCopy.Enabled then BtnCopy.OnClick(BtnCopy);
vk_F7 : if BtnImport.Enabled then BtnImport.OnClick(BtnImport);
vk_F8 : if BtnFilter.Enabled then BtnFilter.OnClick(BtnFilter);
vk_F9 : if BtnReFresh.Enabled then BtnReFresh.OnClick(BtnReFresh);
vk_F10 : if BtnPrint.Enabled then BtnPrint.OnClick(BtnPrint);
vk_F11 : if BtnCheck.Enabled then BtnCheck.OnClick(BtnCheck);
vk_F12 : if BtnExit.Enabled then BtnExit.OnClick(BtnExit);
end;
end;
一般是 SendMessage, PostMessage 之類。