攔截方向鍵的訊息(100分)

  • 主题发起人 主题发起人 jiichen
  • 开始时间 开始时间
J

jiichen

Unregistered / Unconfirmed
GUEST, unregistred user!
現在在寫一個類似 Tmemo 的編輯控件,是從
TCustomControl 繼承而來的。
Scroll 方面是用兩個 TScrollBar 控件,而不是使用 API 的方法。
這控件是依我自己的意思來寫的,大致分成顯示與編輯兩類,
目前顯示方面已完成,可以讀檔並顯示及使用 Scroll Bar。

而編輯方面,想使用 WM_KEYDOWN、WM_KEYUP ,但是
攔截不到方向鍵,作了一個簡單的程式來測試,主視窗中除了
我的控件外,另還有幾個 Button ,當按下右鍵時,便看見
Button 焦點跑來跑去,到我的控件時,只觸發了 WM_KEYUP
事件,且焦點也跑至下一個 Button。

問題1:如何攔截方向鍵?
問題2:按方向鍵後,焦點不會跑至下一個控件?

這裡是部分程式碼:
procedure WMKEYUP(var msg:TWMKEYUP); message WM_KEYUP;
procedure WMKEYDOWN(var msg:TWMKEYDOWN); message WM_KEYDOWN;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;


// 實作 ----------------------------------------------------------
procedure TCustomJCMemo.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
//
inherited;

if FWantTab then
Message.Result := Message.Result or DLGC_WANTTAB;

if FWantAllKeys then
Message.Result := Message.Result or DLGC_WANTALLKEYS;

end;

procedure TCustomJCMemo.WMKEYUP(var msg: TWMKEYUP);
begin
inherited;
end;

procedure TCustomJCMemo.WMKEYDOWN(var msg: TWMKEYDOWN);
begin
inherited;
end;

 
procedure CMChildKey(var Message: TMessage); message CM_CHILDKEY;
 
unit ArmLabEdit;

interface

uses
Windows, Messages, stdctrls,SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TArmLabEdit = class(TWinControl)
private
FEdit:TEdit;
FLab:TLabel;
FLength:integer;
FExit:tnotifyevent;
FKey:TKeyPressEvent;
function GetCaption: string;
function GetText: string;
//设焦点
procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
//设计退出事件
procedure CMFocusChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED;
//设计击键事件
procedure CMChildKey(var Message: TMessage); message CM_CHILDKEY;

procedure SetText(const Value: string);
procedure SetCaption(const Value: string);
procedure WMSize(var message:tmessage) ;message wm_size;
procedure cmfontchanged(var message :Tmessage);message CM_fontchanged;
protected
public
constructor Create(aowner:tcomponent);override;
destructor Destory;
published
property Text:string read gettext write settext;
property Caption :string read getcaption write setcaption;
property OnExit read FExit write FExit;
property Onkeypress read Fkey write Fkey;
property TxtLength:integer read Flength write Flength;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('宫雨', [TArmLabEdit]);
end;

{ TArmLabEdit }

procedure TArmLabEdit.CMChildKey(var Message: TMessage);
begin
if Assigned(FKey) then
FEdit.OnKeyPress:=Fkey;

end;



procedure TArmLabEdit.CMFocusChanged(var Message: TCMFocusChanged);
begin
if Assigned(FExit) then
FEdit.OnExit:=FExit;
end;

procedure TArmLabEdit.cmfontchanged(var message: Tmessage);
begin
inherited;
end;


constructor TArmLabEdit.Create(aowner: tcomponent);
begin
inherited Create(aowner);
Width:=200;
Height:=25;
FLab:=tlabel.Create(self);
FLab.Font.Name:='宋体';
FLab.Font.Size:=12;
FLab.Parent:=self;
FLab.Left:=left;
FLab.Width:=75;
FLab.height:=25;
FLab.Visible:=true;
FEdit:=tedit.Create(self);
FEdit.Parent:=self;
FEdit.Left:=left+flab.Width+5;
FEdit.Width:=width-5-flab.Width;
FEdit.height:=25;
FEdit.Font.Name:='宋体';
FEdit.Font.Size:=10;
end;

destructor TArmLabEdit.Destory;
begin
FLab.free;
FEdit.Free;
inherited;
end;


function TArmLabEdit.GetCaption: string;
begin
Result:=Flab.Caption;
end;

function TArmLabEdit.gettext: string;
begin
result:=FEdit.Text;
end;

procedure TArmLabEdit.SetCaption(const Value: string);
begin
FLab.Caption:=Value;
end;

procedure TArmLabEdit.SetText(const Value: string);
begin
if length(value)<=Flength then
FEdit.Text:=value
else
FEdit.Text:=copy(value,1,flength);
end;




procedure TArmLabEdit.WMSetFocus(var Message: TWMSetFocus);
begin
inherited;
FEdit.SetFocus;
end;

procedure TArmLabEdit.wmsize(var message: tmessage);
begin
inherited;
FLab.height:=Height;
FEdit.Width:=Height;
FEdit.Width:=Width-Flab.Width-5;
end;

end.
 
unit ArmLabEdit;

interface

uses
Windows, Messages, stdctrls,SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TArmLabEdit = class(TWinControl)
private
FEdit:TEdit;
FLab:TLabel;
FLength:integer;
FExit:tnotifyevent;
FKey:TKeyPressEvent;
function GetCaption: string;
function GetText: string;
//设焦点
procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
//设计退出事件
procedure CMFocusChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED;
//设计击键事件
procedure CMChildKey(var Message: TMessage); message CM_CHILDKEY;

procedure SetText(const Value: string);
procedure SetCaption(const Value: string);
procedure WMSize(var message:tmessage) ;message wm_size;
procedure cmfontchanged(var message :Tmessage);message CM_fontchanged;
protected
public
constructor Create(aowner:tcomponent);override;
destructor Destory;
published
property Text:string read gettext write settext;
property Caption :string read getcaption write setcaption;
property OnExit read FExit write FExit;
property Onkeypress read Fkey write Fkey;
property TxtLength:integer read Flength write Flength;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('宫雨', [TArmLabEdit]);
end;

{ TArmLabEdit }

procedure TArmLabEdit.CMChildKey(var Message: TMessage);
begin
if Assigned(FKey) then
FEdit.OnKeyPress:=Fkey;

end;



procedure TArmLabEdit.CMFocusChanged(var Message: TCMFocusChanged);
begin
if Assigned(FExit) then
FEdit.OnExit:=FExit;
end;

procedure TArmLabEdit.cmfontchanged(var message: Tmessage);
begin
inherited;
end;


constructor TArmLabEdit.Create(aowner: tcomponent);
begin
inherited Create(aowner);
Width:=200;
Height:=25;
FLab:=tlabel.Create(self);
FLab.Font.Name:='宋体';
FLab.Font.Size:=12;
FLab.Parent:=self;
FLab.Left:=left;
FLab.Width:=75;
FLab.height:=25;
FLab.Visible:=true;
FEdit:=tedit.Create(self);
FEdit.Parent:=self;
FEdit.Left:=left+flab.Width+5;
FEdit.Width:=width-5-flab.Width;
FEdit.height:=25;
FEdit.Font.Name:='宋体';
FEdit.Font.Size:=10;
end;

destructor TArmLabEdit.Destory;
begin
FLab.free;
FEdit.Free;
inherited;
end;


function TArmLabEdit.GetCaption: string;
begin
Result:=Flab.Caption;
end;

function TArmLabEdit.gettext: string;
begin
result:=FEdit.Text;
end;

procedure TArmLabEdit.SetCaption(const Value: string);
begin
FLab.Caption:=Value;
end;

procedure TArmLabEdit.SetText(const Value: string);
begin
if length(value)<=Flength then
FEdit.Text:=value
else
FEdit.Text:=copy(value,1,flength);
end;




procedure TArmLabEdit.WMSetFocus(var Message: TWMSetFocus);
begin
inherited;
FEdit.SetFocus;
end;

procedure TArmLabEdit.wmsize(var message: tmessage);
begin
inherited;
FLab.height:=Height;
FEdit.Width:=Height;
FEdit.Width:=Width-Flab.Width-5;
end;

end.
 
要截获 WM_GETDLGCODE 消息,你的程序才能得到上述的系统键。
DLGC_BUTTON Button.
DLGC_DEFPUSHBUTTON Default push button.
DLGC_HASSETSEL EM_SETSEL messages.
DLGC_RADIOBUTTON Radio button.
DLGC_STATIC Static control.
DLGC_UNDEFPUSHBUTTON Nondefault push button.
<font color = #ff0000><strong>DLGC_WANTALLKEYS</font></strong> All keyboard input.
DLGC_WANTARROWS Direction keys.
DLGC_WANTCHARS WM_CHAR messages.
DLGC_WANTMESSAGE All keyboard input (the application passes this message on to a control).
DLGC_WANTTAB
 
兩位意見都成功了,奇怪!之前也攔截 WM_GETDLGCODE
,不成功,可能是寫法有誤,重寫後就好了!

請問 arm 兄,不知 CM_CHILDKEY 是代表什麼意思?
要用何種方式來查詢,使用 HELP 查不到,追了一下
Controls 才簡單的寫一個 CM_CHILDKEY = CM_BASE + 46;
那是何意思呢?
 
我也不知道,CM_CHILDKEY = CM_BASE + 46
我是在写控件时用WINSIGHT 跟踪发现的
然后看了一下TWINCONTORLS
的原码
 
多人接受答案了。
 
后退
顶部