为什么m.wParamLo呢 WM_KEYDOWN的描述不是 WM_KEYDOWN nVirtKey = (int) wParam; // virtual-key code lKeyData = lParam; 这样码 另外我跟了一下在IsKeyMsg,首先当有WM_KEYDOWN来到时,它先传CN_BASE + WM_KEYDOWN,转为 CN_KEYDOWN,先发给当前的窗口,如焦点在button上,发给它,接着button的CNKeyDown被调用 也就是它的祖先TWinControl的CNKeyDown,调用IsMenuMessage,为了处理快捷方式等等 我也跟不下去了,呵呵 其实关键的就是处理完IsKeyMsg等判断之后,调用DispatchMessage,会调用TButton继承而来的 WMKeyDown,接着调用DoKeyDown,如下: function TWinControl.DoKeyDown(var Message: TWMKey): Boolean; var ShiftState: TShiftState; Form: TCustomForm; begin Result := True; Form := GetParentForm(Self); if (Form <> nil) and (Form <> Self) and Form.KeyPreview and TWinControl(Form).DoKeyDown(Message) then Exit; with Message do begin ShiftState := KeyDataToShiftState(KeyData); if not (csNoStdEvents in ControlStyle) then begin KeyDown(CharCode, ShiftState); if CharCode = 0 then Exit; end; end; Result := False; end;其中 if (Form <> nil) and (Form <> Self) and Form.KeyPreview and TWinControl(Form).DoKeyDown(Message) then Exit; 当KeyPreview为True时才传到父窗口,接着就会调用Form的OnKeyDown事件 但这样我觉得不如OnMessage来得直接,呵呵
但是当前焦点在一Button上就不好使了
建议用Application.OnMessage来查看
怎么没有反应?
老达摩说得对,但我觉得应该是m.wParamLo = VK_F1 更准确。
至于焦点不在窗体上,但窗体的OnKeyDown是可以达到贴主的目的的,为什么呢?
应该跟Delphi对Windows消息的封装有关吧?
我从TForm.ProcessMessage开始跟踪,到了IsKeyMsg,
由于水平和时间有限,无法继续下去,希望哪位对消息丰富清楚的大侠指点迷津,
继续研究这个问题。。
WM_KEYDOWN的描述不是
WM_KEYDOWN
nVirtKey = (int) wParam; // virtual-key code
lKeyData = lParam;
这样码
另外我跟了一下在IsKeyMsg,首先当有WM_KEYDOWN来到时,它先传CN_BASE + WM_KEYDOWN,转为
CN_KEYDOWN,先发给当前的窗口,如焦点在button上,发给它,接着button的CNKeyDown被调用
也就是它的祖先TWinControl的CNKeyDown,调用IsMenuMessage,为了处理快捷方式等等
我也跟不下去了,呵呵
其实关键的就是处理完IsKeyMsg等判断之后,调用DispatchMessage,会调用TButton继承而来的
WMKeyDown,接着调用DoKeyDown,如下:
function TWinControl.DoKeyDown(var Message: TWMKey): Boolean;
var
ShiftState: TShiftState;
Form: TCustomForm;
begin
Result := True;
Form := GetParentForm(Self);
if (Form <> nil) and (Form <> Self) and Form.KeyPreview and
TWinControl(Form).DoKeyDown(Message) then Exit;
with Message do
begin
ShiftState := KeyDataToShiftState(KeyData);
if not (csNoStdEvents in ControlStyle) then
begin
KeyDown(CharCode, ShiftState);
if CharCode = 0 then Exit;
end;
end;
Result := False;
end;其中 if (Form <> nil) and (Form <> Self) and Form.KeyPreview and
TWinControl(Form).DoKeyDown(Message) then Exit;
当KeyPreview为True时才传到父窗口,接着就会调用Form的OnKeyDown事件
但这样我觉得不如OnMessage来得直接,呵呵