怎样使按下“ESC”键后关闭当前窗口?而菜单的快捷键又有效?(现在二者有冲突!)

时间:2022-08-20 23:52:30
我在form1上设了一个“全屏”按钮,来调用一个全屏窗口,当全屏窗口出来后,我想通过按“ESC”键来关闭全屏窗口却不行,有一位朋友说是什么东西(忘了)拦截了此消息,所以收不到,所以按下“ESC”键后无效。
然后他给我了一段代码来解决此问题,代码如下:

procedure MyOnMessage(var MSG: TMSG; var Handle: Boolean);

procedure TFullScreenForm.MyOnMessage(var MSG: TMSG; var Handle: Boolean);
begin
  if ((msg.message=WM_KEYUP) or (msg.message=WM_KEYDOWN))
     and (msg.wParam=VK_Escape) then
  begin
    Handle:=true;
    Close;
  end;
end;

procedure TFullScreenForm.FormCreate(Sender: TObject);
begin
  Height:=Screen.Height;
  Width:=Screen.Width;
  Application.OnMessage:=MyOnMessage;
end;

用这段代码后,确实可以按“ESC”键来关闭全屏窗口了,但我发现form1上所有菜单项的快捷键都无效了,好像跟这段代码有冲突!

请问到底怎样才能使“ESC”键既可以关闭全屏窗口,但又不使快捷键失效。
这问题好久了,请各位帮忙啊!谢谢!!!

17 个解决方案

#1


没太看懂你的意思,我试着这么搞了一下,不知道对不对
我的理解是form1和全屏那个窗口是两个窗口是吧,我new了一个form2,将其windowstate设置为wsMaximized,然后在form1里扔了个按钮,点击打开form2,将form2的keypreview设置为true,在form2的onkeydown中处理esc键。主要代码如下,有什么问题吗?
var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2 := TForm2.Create(self);
  Form2.ShowModal;
end;

end.

。。。。。。。。。。。。。。。。。。。。。。

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_ESCAPE then Form2.Close;
end;

end.

#2


今天论坛人气真差啊,朋友有空帮我看个问题好不好?
http://expert.csdn.net/Expert/topic/1250/1250891.xml?temp=.8562586

#3


加上
else inherited;

其实没必要拦截整个程序消息,完全没必要!

在OnKeyDown事件中写:
if Key=27 then Close;
即可

#4


to killlaoli(菜鸟):先谢谢。
我试了你的方法,还是不行。

to ehom(?!):别人也要我加那句代码试了的,也不能解决问题。
另外key=27是什么意思,代表哪个键?我试了,是ESC吗?无效啊?

#5


VK_ESCAPE = 27

不行是因为你的所有消息都被拦截了,用后一种方法就要先去掉消息的拦截
去掉Application.OnMessage:=MyOnMessage;

实际上还有个小问题
TMessageEvent = procedure (var Msg: TMsg; var Handled: Boolean) of object;

看见没有?
所以应该是
procedure MyOnMessage(var MSG: TMSG; var Handled: Boolean);

你那个Handle会让别人误解为Form1.Handle(虽然类型不同,但要注意)!

用你的方法要去掉
Handle:=true;
就好了!

#6


在你的程序中有用的键只有esc了,因为其他的被你拦截了,当然没有用了
,其他键调用原过程即可

#7


//你那个Handle会让别人误解为Form1.Handle(虽然类型不同,但要注意)!

我不明白你的意思啊?
我改了,还是不行,要么就是form1的快捷键有效,ESC无效;要么就是form2的ESC有效,form1的快捷键无效。
能不能给出完整代码啊?
谢谢了!

#8


方法一:
去掉你以上全部代码,在Form2的OnKeyDown中写入:
 if Key = VK_ESCAPE then Close;

方法二:
procedure MyOnMessage(var MSG: TMSG; var Handled: Boolean);

procedure TFullScreenForm.MyOnMessage(var MSG: TMSG; var Handled: Boolean);
begin
  if ((msg.message=WM_KEYUP) or (msg.message=WM_KEYDOWN))
     and (msg.wParam=VK_ESCAPE) then
  begin
    Close;
  end
  else
    inherited;
end;

#9


to ehom(?!) ,先谢谢了。

方法二:确实不行。

方法一:刚才我自己也那样试过了,当Key = VK_ESCAPE 时,按ESC键无效;
当Key = 13 时,按回车键却可以关闭窗口。(没有在别处定义ESC键,只在此处定义了)

为什么会这样呢?请再告诉我几个别的键的这个码,比如空格、TAB、A、B、C等等,我想试试它们行不行。

#10


to xli(菜鸟) 呵呵,咱的名字一样嘛
没道理的啊,你重新new一个application,然后按偶说的,搞两个form,在form2上放个菜单,设置个快界见,绝对可以的啊,看一下你程序里的其他地方都有些什么东东。

找虚拟键值,可以在delphi help里搜索virtual Key

#11


to killlaoli(菜鸟),我是真菜鸟,可你不是啊:)

我试过新建一个应用程序的,那个方法是好的。
但我实在不知我程序在其他地方有什么问题,并且现在是可以按回车键,但不能按ESC键。

我搜了,没有virtual Key的内容啊?

#12


(1) 设置属性 Form1.keyPreview := true;
(2) 
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_ESCAPE then Close;
end;

(3) 我没测试

#13


LuckyJan(小虾无招),这些基本方法我都已试过了,

我现在只想知道别的键的虚拟码,来试试,谁再告诉我几个,谢谢!

#14


Tab--9
Shift--16
Ctrl--17
Alt--18
CapsLock--20
Esc--27
Win--91,92
NumLock--144
ScrollLock--145

#15


呵呵,不会吧

vk_LButton   = $01;
vk_RButton   = $02;
vk_Cancel    = $03;
vk_MButton   = $04;   { NOT contiguous with L & RBUTTON }
vk_Back      = $08;
vk_Tab       = $09;
vk_Clear     = $0C;
vk_Return    = $0D;
vk_Shift     = $10;
vk_Control   = $11;
vk_Menu      = $12;
vk_Pause     = $13;
vk_Capital   = $14;
vk_Escape    = $1B;
vk_Space     = $20;
vk_Prior     = $21;
vk_Next      = $22;
vk_End       = $23;
vk_Home      = $24;
vk_Left      = $25;
vk_Up        = $26;
vk_Right     = $27;
vk_Down      = $28;
vk_Select    = $29;
vk_Print     = $2A;
vk_Execute   = $2B;
vk_SnapShot  = $2C;
vk_Copy      = $2C not used by keyboards }
vk_Insert    = $2D;
vk_Delete    = $2E;
vk_Help      = $2F;
vk_A thru vk_Z are the same as their ASCII equivalents: 'A' thru 'Z' }
vk_0 thru vk_9 are the same as their ASCII equivalents: '0' thru '9' }
vk_NumPad0   = $60;
vk_NumPad1   = $61;
vk_NumPad2   = $62;
vk_NumPad3   = $63;
vk_NumPad4   = $64;
vk_NumPad5   = $65;
vk_NumPad6   = $66;
vk_NumPad7   = $67;
vk_NumPad8   = $68;
vk_NumPad9   = $69;
vk_Multiply  = $6A;
vk_Add       = $6B;
vk_Separator = $6C;
vk_Subtract  = $6D;
vk_Decimal   = $6E;
vk_Divide    = $6F;
vk_F1        = $70;
vk_F2        = $71;
vk_F3        = $72;
vk_F4        = $73;
vk_F5        = $74;
vk_F6        = $75;
vk_F7        = $76;
vk_F8        = $77;
vk_F9        = $78;
vk_F10       = $79;
vk_F11       = $7A;
vk_F12       = $7B;
vk_F13       = $7C;
vk_F14       = $7D;
vk_F15       = $7E;
vk_F16       = $7F;
vk_F17       = $80;
vk_F18       = $81;
vk_F19       = $82;
vk_F20       = $83;
vk_F21       = $84;
vk_F22       = $85;
vk_F23       = $86;
vk_F24       = $87;
vk_NumLock   = $90;
vk_Scroll    = $91;

#16


试了,奇怪,
Tab不行,ESC不行,
其他都可以。

请问空格是多少?完了就结贴。

#17


Study

#1


没太看懂你的意思,我试着这么搞了一下,不知道对不对
我的理解是form1和全屏那个窗口是两个窗口是吧,我new了一个form2,将其windowstate设置为wsMaximized,然后在form1里扔了个按钮,点击打开form2,将form2的keypreview设置为true,在form2的onkeydown中处理esc键。主要代码如下,有什么问题吗?
var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2 := TForm2.Create(self);
  Form2.ShowModal;
end;

end.

。。。。。。。。。。。。。。。。。。。。。。

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_ESCAPE then Form2.Close;
end;

end.

#2


今天论坛人气真差啊,朋友有空帮我看个问题好不好?
http://expert.csdn.net/Expert/topic/1250/1250891.xml?temp=.8562586

#3


加上
else inherited;

其实没必要拦截整个程序消息,完全没必要!

在OnKeyDown事件中写:
if Key=27 then Close;
即可

#4


to killlaoli(菜鸟):先谢谢。
我试了你的方法,还是不行。

to ehom(?!):别人也要我加那句代码试了的,也不能解决问题。
另外key=27是什么意思,代表哪个键?我试了,是ESC吗?无效啊?

#5


VK_ESCAPE = 27

不行是因为你的所有消息都被拦截了,用后一种方法就要先去掉消息的拦截
去掉Application.OnMessage:=MyOnMessage;

实际上还有个小问题
TMessageEvent = procedure (var Msg: TMsg; var Handled: Boolean) of object;

看见没有?
所以应该是
procedure MyOnMessage(var MSG: TMSG; var Handled: Boolean);

你那个Handle会让别人误解为Form1.Handle(虽然类型不同,但要注意)!

用你的方法要去掉
Handle:=true;
就好了!

#6


在你的程序中有用的键只有esc了,因为其他的被你拦截了,当然没有用了
,其他键调用原过程即可

#7


//你那个Handle会让别人误解为Form1.Handle(虽然类型不同,但要注意)!

我不明白你的意思啊?
我改了,还是不行,要么就是form1的快捷键有效,ESC无效;要么就是form2的ESC有效,form1的快捷键无效。
能不能给出完整代码啊?
谢谢了!

#8


方法一:
去掉你以上全部代码,在Form2的OnKeyDown中写入:
 if Key = VK_ESCAPE then Close;

方法二:
procedure MyOnMessage(var MSG: TMSG; var Handled: Boolean);

procedure TFullScreenForm.MyOnMessage(var MSG: TMSG; var Handled: Boolean);
begin
  if ((msg.message=WM_KEYUP) or (msg.message=WM_KEYDOWN))
     and (msg.wParam=VK_ESCAPE) then
  begin
    Close;
  end
  else
    inherited;
end;

#9


to ehom(?!) ,先谢谢了。

方法二:确实不行。

方法一:刚才我自己也那样试过了,当Key = VK_ESCAPE 时,按ESC键无效;
当Key = 13 时,按回车键却可以关闭窗口。(没有在别处定义ESC键,只在此处定义了)

为什么会这样呢?请再告诉我几个别的键的这个码,比如空格、TAB、A、B、C等等,我想试试它们行不行。

#10


to xli(菜鸟) 呵呵,咱的名字一样嘛
没道理的啊,你重新new一个application,然后按偶说的,搞两个form,在form2上放个菜单,设置个快界见,绝对可以的啊,看一下你程序里的其他地方都有些什么东东。

找虚拟键值,可以在delphi help里搜索virtual Key

#11


to killlaoli(菜鸟),我是真菜鸟,可你不是啊:)

我试过新建一个应用程序的,那个方法是好的。
但我实在不知我程序在其他地方有什么问题,并且现在是可以按回车键,但不能按ESC键。

我搜了,没有virtual Key的内容啊?

#12


(1) 设置属性 Form1.keyPreview := true;
(2) 
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_ESCAPE then Close;
end;

(3) 我没测试

#13


LuckyJan(小虾无招),这些基本方法我都已试过了,

我现在只想知道别的键的虚拟码,来试试,谁再告诉我几个,谢谢!

#14


Tab--9
Shift--16
Ctrl--17
Alt--18
CapsLock--20
Esc--27
Win--91,92
NumLock--144
ScrollLock--145

#15


呵呵,不会吧

vk_LButton   = $01;
vk_RButton   = $02;
vk_Cancel    = $03;
vk_MButton   = $04;   { NOT contiguous with L & RBUTTON }
vk_Back      = $08;
vk_Tab       = $09;
vk_Clear     = $0C;
vk_Return    = $0D;
vk_Shift     = $10;
vk_Control   = $11;
vk_Menu      = $12;
vk_Pause     = $13;
vk_Capital   = $14;
vk_Escape    = $1B;
vk_Space     = $20;
vk_Prior     = $21;
vk_Next      = $22;
vk_End       = $23;
vk_Home      = $24;
vk_Left      = $25;
vk_Up        = $26;
vk_Right     = $27;
vk_Down      = $28;
vk_Select    = $29;
vk_Print     = $2A;
vk_Execute   = $2B;
vk_SnapShot  = $2C;
vk_Copy      = $2C not used by keyboards }
vk_Insert    = $2D;
vk_Delete    = $2E;
vk_Help      = $2F;
vk_A thru vk_Z are the same as their ASCII equivalents: 'A' thru 'Z' }
vk_0 thru vk_9 are the same as their ASCII equivalents: '0' thru '9' }
vk_NumPad0   = $60;
vk_NumPad1   = $61;
vk_NumPad2   = $62;
vk_NumPad3   = $63;
vk_NumPad4   = $64;
vk_NumPad5   = $65;
vk_NumPad6   = $66;
vk_NumPad7   = $67;
vk_NumPad8   = $68;
vk_NumPad9   = $69;
vk_Multiply  = $6A;
vk_Add       = $6B;
vk_Separator = $6C;
vk_Subtract  = $6D;
vk_Decimal   = $6E;
vk_Divide    = $6F;
vk_F1        = $70;
vk_F2        = $71;
vk_F3        = $72;
vk_F4        = $73;
vk_F5        = $74;
vk_F6        = $75;
vk_F7        = $76;
vk_F8        = $77;
vk_F9        = $78;
vk_F10       = $79;
vk_F11       = $7A;
vk_F12       = $7B;
vk_F13       = $7C;
vk_F14       = $7D;
vk_F15       = $7E;
vk_F16       = $7F;
vk_F17       = $80;
vk_F18       = $81;
vk_F19       = $82;
vk_F20       = $83;
vk_F21       = $84;
vk_F22       = $85;
vk_F23       = $86;
vk_F24       = $87;
vk_NumLock   = $90;
vk_Scroll    = $91;

#16


试了,奇怪,
Tab不行,ESC不行,
其他都可以。

请问空格是多少?完了就结贴。

#17


Study