这是以前一个大富翁上的朋友写的构件,你看看是否可以用:<br>unit quickkey;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br> StdCtrls, Grids, ExtCtrls, typinfo, math;<br><br>type<br> TMoveOptions = set of (moEditDeliver, moListDeliver,<br> moComboDeliver,moGridDeliver, moButtonDeliver,moRadioDeliver);<br><br> TQuickKey = class(TComponent)<br> private<br>// FComponents: TList;<br> FActive: boolean;<br> FOwnerKeyEvents : TMessageEvent;<br> FOptions : TMoveOptions;<br><br> FEdit : Boolean;<br> FList : Boolean;<br> FGrid : boolean;<br> FCombo : boolean;<br> FButton : boolean;<br> FRadio: boolean;<br> function MoveUpSide(Sender: TWinControl;Key: word):boolean;<br> function MoveDownSide(Sender: TWinControl;Key: word):boolean;<br> function MoveLeftSide(Sender: TWinControl;Key: word):boolean;<br> function MoveRightSide(Sender: TWinControl;Key: word):boolean;<br> function MoveNextSide(Sender: TWinControl;Key: word):boolean;<br> procedure GetControl(Sender: TWinControl;Direct: integer);<br> function CanEnterKey(Sender: TWincontrol): boolean;<br> function HasProperty(Sender: TObject; AProperty: string):boolean;<br> function TestProperty(Sender: TObject; AProperty: string;<br> Value: integer): boolean;<br> function GetPropertyValue(Sender: TObject; AProperty: string): integer;<br> protected<br> { Protected declarations }<br> public<br> procedure NewKeyDown(var Msg: TMsg; var Handled: boolean);<br> { Public declarations }<br> constructor Create(AOwner : TComponent); override;<br> destructor Destroy; override;<br> published<br> { Published declarations }<br> property Active: boolean read FActive write FActive;<br> property Options : TMoveOptions read FOptions write FOptions<br> default [moEditDeliver, moListDeliver,<br> moGridDeliver, moButtonDeliver];<br> end;<br><br>procedure Register;<br><br>implementation<br><br>procedure Register;<br>begin<br> RegisterComponents('freeware', [TQuickKey]);<br>end;<br><br>constructor TQuickKey.Create(AOwner: TComponent);<br>var<br> Loop: integer;<br>begin<br> for Loop:=0 to AOwner.ComponentCount-1 do<br> if AOwner.Components[Loop] is TQuickKey then raise<br> EInvalidOperation.Create(<br> 'TQuickKey can have only one instance per form');<br><br> // Create component and set default properties<br> inherited Create(AOwner);<br> FActive:=false;<br><br> FOptions:=[moEditDeliver, moListDeliver,<br> moComboDeliver,moGridDeliver, moButtonDeliver, moRadioDeliver];<br><br> FOwnerKeyEvents:=Application.OnMessage;<br> Application.OnMessage:=NewKeyDown;<br>end;<br><br>destructor TQuickKey.Destroy;<br>begin<br> Application.OnMessage:=FOwnerKeyEvents;<br> inherited;<br>end;<br><br>procedure TQuickKey.NewKeyDown(var Msg: TMsg; var handled: boolean);<br>var<br> v: TWinControl;<br> f: TForm;<br>begin<br> if FActive then<br> begin<br> f:=self.owner as TForm;<br> if f.Active and (Msg.message=WM_KEYDOWN) then<br> if<br> (Msg.wParam = VK_RETURN) or<br> (Msg.wParam = VK_LEFT) or<br> (Msg.wParam = VK_RIGHT) or<br> (Msg.wParam = VK_UP) or<br> (Msg.wParam = VK_DOWN) then begin<br> v:=f.ActiveControl;<br> FEdit := v is TCustomEdit;<br> FList := v is TCustomListBox;<br> FGrid := v is TDrawGrid;<br> FCombo := v is TCustomComboBox;<br> FButton := v is TButtonControl;<br> FRadio := v is TRadioGroup;<br><br>{ FEdit:=HasProperty(v,'Text');<br> FList:=HasProperty(v,'Items');<br> FGrid:=HasProperty(v,'ColCount') or HasProperty(v,'RowCount');<br> FButton:=v is TButtonControl;<br>}<br> case Msg.wParam of<br> VK_UP: Handled:=MoveUpSide(v, Msg.wParam);<br> VK_DOWN: Handled:=MoveDownSide(v, Msg.wParam);<br> VK_LEFT: Handled:=MoveLeftSide(v, Msg.wParam);<br> VK_RIGHT: Handled:=MoveRightSide(v, Msg.wParam);<br> VK_RETURN: Handled:=MoveNextSide(v, Msg.wParam);<br> end;<br> end;<br> end;<br> if assigned(FOwnerKeyEvents) then FOwnerKeyEvents(Msg,handled);<br><br>end;<br><br>function TQuickKey.MoveUpSide(Sender: TWinControl; Key: word):boolean;<br>var<br> v: boolean;<br>begin<br> v:=false;<br> if FList then<br> if moListDeliver in FOptions then<br> if (Sender as TCustomListBox).ItemIndex=0 then<br> v:=true<br> else<br> else<br> else if FCombo then<br> if moComboDeliver in FOptions then<br> if (Sender as TCustomComboBox).ItemIndex=0 then<br> v:=true<br> else<br> else<br> else if FButton then<br> if moButtonDeliver in FOptions then<br> v:=true<br> else<br> else if FRadio then<br> if moRadioDeliver in FOptions then<br> if (Sender as TRadioGroup).ItemIndex = 0 then<br> v:=true<br> else<br> else<br> else if FEdit then<br> if moEditDeliver in FOptions then<br> if CanEnterKey(Sender) then<br> if HasProperty(Sender, 'Lines') then<br> if (Sender as TCustomEdit).SelStart<br> +(Sender as TCustomEdit).SelLength=0 then<br> v:=true<br> else<br> else<br> v:=true<br> else<br> v:=true<br> else<br> else if FGrid then<br> if moGridDeliver in FOptions then<br> if (not CanEnterKey(Sender))<br> and ((Sender as TDrawGrid).row<=<br> GetPropertyValue(Sender,'FixedRows')<br> )<br> then<br> v:=true;<br> if v then<br> begin<br> GetControl(Sender,1);<br> end;<br> result:=v;<br>end;<br><br>function TQuickKey.MoveDownSide(Sender: TWinControl;<br> Key: word):boolean;<br>var<br> v: Boolean;<br>begin<br> v:=false;<br> if FList then<br> if moListDeliver in FOptions then<br> if (Sender as TCustomListBox).ItemIndex=<br> (Sender as TCustomListBox).Items.Count-1<br> then<br> v:=true<br> else<br> else<br> else if FCombo then<br> if moComboDeliver in FOptions then<br> if (Sender as TCustomComboBox).ItemIndex=<br> (Sender as TCustomComboBox).Items.Count-1<br> then<br> v:=true<br> else<br> else<br> else if FButton then<br> if moButtonDeliver in FOptions then<br> v:=true<br> else<br> else if FRadio then<br> if moRadioDeliver in FOptions then<br> if (Sender as TRadioGroup).ItemIndex =<br> (Sender as TRadioGroup).Items.Count-1<br> then<br> v:=true<br> else<br> else<br> else if FEdit then<br> if moEditDeliver in FOptions then<br> if CanEnterKey(Sender) then<br> if HasProperty(Sender, 'Lines') then<br> if (Sender as TCustomEdit).SelStart<br> +(Sender as TCustomEdit).SelLength>=<br> length((Sender as TCustomEdit).text)-1<br> then<br> v:=true<br> else<br> else<br> v:=true<br> else<br> v:=true<br> else<br> else if FGrid then<br> if moGridDeliver in FOptions then<br> if (not CanEnterKey(Sender))<br> and ((Sender as TDrawGrid).Row>=<br> GetPropertyValue(Sender, 'RowCount')-1)<br> then<br> v:=true;<br><br> if v then<br> begin<br> GetControl(Sender,3);<br> end;<br> result:=v;<br>end;<br><br>function TQuickKey.MoveLeftSide(Sender: TWinControl;<br> key: word):boolean;<br>var<br> v: boolean;<br>begin<br> v:=false;<br> if FList then<br> if moListDeliver in FOptions then<br> if (Sender as TCustomListBox).ItemIndex= 0<br>// (Sender as TCustomListBox).Items.Count-1<br> then<br> v:=true<br> else<br> else<br> else if FCombo then<br> if moComboDeliver in FOptions then<br> if CanEnterKey(Sender) then<br> if (Sender as TCustomCombobox).selstart<br> +(Sender as TCustomComboBox).SelLength = 0 then<br> v:=true<br> else<br> else<br> v:=true<br> else<br> else if FButton then<br> if moButtonDeliver in FOptions then<br> v:=true<br> else<br> else if FRadio then<br> if moRadioDeliver in FOptions then<br> if (Sender as TRadioGroup).ItemIndex = 0<br>// (Sender as TRadioGroup).Items.Count-1<br> then<br> v:=true<br> else<br> else<br> else if FEdit then<br> if moEditDeliver in FOptions then<br> if CanEnterKey(Sender) then<br> if (Sender as TCustomEdit).SelStart<br> +(Sender as TCustomEdit).SelLength=0<br>// length((Sender as TCustomEdit).text)-1<br> then<br> v:=true<br> else<br> else<br> v:=true<br> else<br> else if FGrid then<br> if moGridDeliver in FOptions then<br> if (not CanEnterKey(Sender))<br> and ((Sender as TDrawGrid).Col<=<br> GetPropertyValue(Sender,'FixedCols'))<br> then<br> v:=true;<br> if v then<br> begin<br> GetControl(Sender,0);<br> end;<br> result:=v;<br>end;<br><br>function TQuickKey.MoveRightSide(Sender: TWinControl;<br> Key: word):boolean;<br>var<br> v: boolean;<br>begin<br> v:=false;<br> if FList then<br> if moListDeliver in FOptions then<br> if (Sender as TCustomListBox).ItemIndex=<br> (Sender as TCustomListBox).Items.Count-1<br> then<br> v:=true<br> else<br> else<br> else if FCombo then<br> if moComboDeliver in FOptions then<br> if CanEnterKey(Sender) then<br> if (Sender as TCustomComboBox).SelStart<br> +(Sender as TCustomComboBox).SelLength>=<br> length((Sender as TComboBox).text)<br> then<br> v:=true<br> else<br> else<br> v:=true<br> else<br> else if FButton then<br> if moButtonDeliver in FOptions then<br> v:=true<br> else<br> else if FRadio then<br> if moRadioDeliver in FOptions then<br> if (Sender as TRadioGroup).ItemIndex =<br> (Sender as TRadioGroup).Items.Count-1<br> then<br> v:=true<br> else<br> else<br> else if FEdit then<br> if moEditDeliver in FOptions then<br> if CanEnterKey(Sender) then<br> if (Sender as TCustomEdit).SelStart<br> +(Sender as TCustomEdit).SelLength>=<br> length((Sender as TCustomEdit).text)<br> then<br> v:=true<br> else<br> else<br> v:=true<br> else<br> else if FGrid then<br> if moGridDeliver in FOptions then<br> if (not CanEnterKey(Sender))<br> and ((Sender as TDrawGrid).col>=<br> GetPropertyValue(Sender,'ColCount')-1)<br> then<br> v:=true;<br> if v then<br> begin<br> GetControl(Sender,2);<br> end;<br> result:=v;<br>end;<br><br>function TQuickKey.MoveNextSide(Sender: TwinControl;<br> Key: word):boolean;<br>var<br> v: boolean;<br>begin<br> v:=false;<br> if FList then<br> if moListDeliver in FOptions then<br> if (Sender as TCustomListBox).ItemIndex=<br> (Sender as TCustomListBox).Items.Count-1<br> then<br> v:=true<br> else<br> else<br> else if FCombo then<br> if moComboDeliver in FOptions then<br> if CanEnterKey(Sender) then<br> if (Sender as TCustomComboBox).SelStart<br> +(Sender as TCustomComboBox).SelLength>=<br> length((Sender as TComboBox).text)<br> then<br> v:=true<br> else<br> else<br> v:=true<br> else<br> else if FRadio then<br> if moRadioDeliver in FOptions then<br> if (Sender as TRadioGroup).ItemIndex =<br> (Sender as TRadioGroup).Items.Count-1<br> then<br> v:=true<br> else<br> else<br> else if FEdit then<br> if CanEnterKey(Sender) then<br> if HasProperty(Sender, 'Lines') then<br> if (Sender as TCustomEdit).SelStart<br> +(Sender as TCustomEdit).SelLength>=<br> length((Sender as TCustomEdit).text)<br> then<br> v:=true<br> else<br> else<br> v:=true<br> else<br> v:=true;<br> if v then<br> begin<br>// GetControl(Sender,4);<br> (Sender.Owner as TForm).Perform(WM_NEXTDLGCTL,0,0);<br> end;<br> result:=v;<br>end;<br><br>function TQuickKey.CanEnterKey(Sender: TWinControl): boolean;<br>begin<br> if hidecaret(0) then<br> begin<br> showcaret(0);<br> result:=true;<br> if HasProperty(Sender,'ReadOnly')<br> and (not TestProperty(Sender,'ReadOnly',0))<br> then<br> result:=false;<br> end<br> else<br> result:=false;<br>end;<br><br>function TQuickKey.HasProperty(Sender:TObject; AProperty: string):boolean;<br>begin<br> result:=(GetPropInfo(Sender.ClassInfo, AProperty)<>nil);<br>end;<br><br>function TQuickKey.TestProperty(Sender:TObject; AProperty: string;<br> Value: integer): boolean;<br>var<br> T
PropInfo;<br>begin<br> T:=GetPropInfo(Sender.ClassInfo, AProperty);<br> result:=(GetOrdProp(Sender,T) = Value);<br>end;<br><br>procedure TQuickKey.GetControl(Sender:TWinControl;Direct:integer);<br>var<br> i: integer;<br> scs: TRect;<br> sc1,sc2: TRect;<br> wc: TWinControl ;<br> f:TForm;<br>begin<br> wc:=nil;<br> f:= Sender.Owner as TForm;<br>{ scs := Sender.BoundsRect;<br> scs.TopLeft :=<br> (Sender.Parent as TWinControl).ClientToScreen(sc1.TopLeft);<br> scs.BottomRight :=<br> (Sender.Parent as TWinControl).ClientToScreen(sc1.BottomRight);<br> }<br><br> scs := Sender.ClientRect;<br> scs.TopLeft :=<br> (Sender as TWinControl).ClientToScreen(scs.TopLeft);<br> scs.BottomRight :=<br> (Sender as TWinControl).ClientToScreen(scs.BottomRight);<br> { }<br> case Direct of<br> 0:<br> begin<br> scs.Right:=scs.Left-1;<br> scs.Left:=-3000;<br> end;<br> 1:<br> begin<br> scs.Bottom:=scs.Top-1;<br> scs.Top:=-3000;<br> end;<br> 2:<br> begin<br> scs.Left:=scs.Right+1;<br> scs.Right:=3000;<br> end;<br> 3:<br> begin<br> scs.Top:=scs.bottom+1;<br> scs.Bottom:=3000;<br> end;<br> end;<br> for i:= 0 to f.ComponentCount-1 do<br> begin<br> if (f.Components
<> Sender)<br>{ and (<br> (f.Components is TWinControl) and<br> (HasProperty(f.Components,'Text') or<br> HasProperty(f.Components,'Items') or<br> HasProperty(f.Components,'ColCount')<br> ) )}<br> and (f.Components is TWinControl)<br> and (<br> (not HasProperty(f.Components,'ControlCount'))<br> or (<br> HasProperty(f.components,'ControlCount')<br> and TestProperty(f.Components,'ControlCount',0)<br>  <br> )<br> and (f.Components as TWinControl).CanFocus<br> then<br> begin<br> {<br> sc1:=(f.components as TWinControl).BoundsRect;<br> sc1.TopLeft:=<br> ((f.Components as TWinControl).Parent as TWinControl).ClientToScreen(sc1.TopLeft);<br> sc1.BottomRight:=<br> ((f.Components as TWinControl).Parent as TWinControl).ClientToScreen(sc1.BottomRight);<br> }<br> sc1:=(f.components as TWinControl).ClientRect;<br> sc1.TopLeft:=<br> (f.Components as TWinControl).ClientToScreen(sc1.TopLeft);<br> sc1.BottomRight:=<br> (f.Components as TWinControl).ClientToScreen(sc1.BottomRight);<br> {}<br> if IntersectRect(sc2,scs,sc1) then<br> begin<br> wc:=f.Components as TWinControl;<br> case Direct of<br> 0: scs.Left:=sc2.Right+1;<br> 1: scs.Top:=sc2.Bottom+1;<br> 2: scs.Right:=sc2.Left-1;<br> 3: scs.Bottom:=sc2.Top-1;<br> end;<br> if (scs.Top>scs.Bottom) or (scs.Left>scs.Right) then<br> break;<br> end;<br> end;<br> end;<br> if wc<>nil then<br> postmessage(f.Handle,WM_NEXTDLGCTL,wc.Handle,1)<br> else if Direct<=1 then<br> postmessage(f.handle,WM_NEXTDLGCTL,1,0)<br> else<br> postmessage(f.handle,WM_NEXTDLGCTL,0,0);<br><br>end;<br><br>function TQuickKey.GetPropertyValue(Sender:TObject; AProperty:string):integer;<br>var<br> TPropInfo;<br>begin<br> T:=GetPropInfo(Sender.ClassInfo,AProperty);<br> if T<>nil then<br> result:=GetOrdProp(Sender,T)<br> else<br> result:=-1;<br>end;<br><br>end.