Rod*_*mez 6 delphi vcl c++builder tframe keypreview
我希望在Frames中有一个KeyPreview功能,我的意思是,当输入(例如,选择框架的一个控件,或鼠标在里面)是在一个框架(这将有几个面板和其他控件) )然后由框架首先处理用户按下的键.
有没有办法做到这一点?我没有在TFrame中找到类似于KeyPreview的属性.
我正在使用RAD Studio的XE5版本,尽管我主要使用的是C++ Builder.
感谢我最近的"ShortCut fire什么时候" -调查,我已经为你的Frame制定了一个独立的解决方案.
简而言之:所有关键消息都输入TWinControl.CNKeyDwon活动控件.该方法在确定消息是否为ShortCut时调用TWinControl.IsMenuKey遍历所有父节点的方法.是通过调用它的GetPopupMenu.IsShortCut方法来做到的.我已经覆盖了Frame的GetPopupMenu方法,如果它不存在则创建一个方法.请注意,您始终可以自己向框架添加PopupMenu.通过子类化TPopupMenu和重写IsShortCut方法,KeyDown调用Frame的方法,该方法用作您需要的KeyPreview功能.(我也可以分配OnKeyDdown事件处理程序).
unit Unit2;
interface
uses
Winapi.Messages, System.Classes, Vcl.Controls, Vcl.Forms, Vcl.Menus,
Vcl.StdCtrls;
type
TPopupMenu = class(Vcl.Menus.TPopupMenu)
public
function IsShortCut(var Message: TWMKey): Boolean; override;
end;
TFrame2 = class(TFrame)
Label1: TLabel;
Edit1: TEdit;
private
FPreviewPopup: TPopupMenu;
protected
function GetPopupMenu: Vcl.Menus.TPopupMenu; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
end;
implementation
{$R *.dfm}
{ TPopupMenu }
function TPopupMenu.IsShortCut(var Message: TWMKey): Boolean;
var
ShiftState: TShiftState;
begin
ShiftState := KeyDataToShiftState(Message.KeyData);
TFrame2(Owner).KeyDown(Message.CharCode, ShiftState);
Result := Message.CharCode = 0;
if not Result then
Result := inherited IsShortCut(Message);
end;
{ TFrame2 }
function TFrame2.GetPopupMenu: Vcl.Menus.TPopupMenu;
begin
Result := inherited GetPopUpMenu;
if Result = nil then
begin
if FPreviewPopup = nil then
FPreviewPopup := TPopupMenu.Create(Self);
Result := FPreviewPopup;
end;
end;
procedure TFrame2.KeyDown(var Key: Word; Shift: TShiftState);
begin
if (Key = Ord('X')) and (ssCtrl in Shift) then
begin
Label1.Caption := 'OH NO, DON''T DO THAT!';
Key := 0;
end;
end;
end.
Run Code Online (Sandbox Code Playgroud)