Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Delphi Component

Posted on 2004-04-28
4
396 Views
Last Modified: 2013-11-23
Hi Experts!
               I am writing a components. One of the feature of compnents is to respond to Escape key even the component does not have the focus. I am wondering is there is any way i can achieve this functionality for my component. Please if any body can help me explain how i can achieve this functionality. The most important feature is if an Esc key is detected is for the component to run its new method.

Thank You

Zahid.
0
Comment
Question by:David_m43
4 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 10946483
possibilities
- you could lookup in a small intervall the keyboardstate
  - GetAsyncKeyBoardState
  - GetKeyBoardState

- you could hook the keyboard (dll needed)
  - search for "hook keyboard" here
0
 
LVL 12

Accepted Solution

by:
esoftbg earned 125 total points
ID: 10946519
0
 
LVL 11

Expert Comment

by:robert_marquardt
ID: 10946640
The real question is if your component should do that at all.
It is either a windowed control which means that it can focus and should only react to keys when focused
or it is a non-windowed control which should not react to keys at all.
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 10947514
Another way is to register a HotKey

Here's my version....

unit MyComponent;

interface
uses
 Windows, Messages, SysUtils, Classes,Controls;

type
 TMyComponent = class(TComponent)
 private
   FEnabled: Boolean;
   FRegistered: Boolean;
   prOldWndProc: TWndMethod;
   FHotkey: TSHortcut;
   FOnHotKeyPressed: TNotifyEvent;
   prWindow: TWinControl;
   prHandle: HWND;
   procedure RegisterKey;
   procedure UnRegisterKey;
   { Private declarations }
 protected
   { Protected declarations }
   procedure SetEnabled(const Value: Boolean);
   procedure SetHotKey(const Value: TShortcut);
   procedure NewWindowProc(var Message: TMessage);
   procedure Loaded; override;
 public
   { Public declarations }
   constructor Create(aOwner: TComponent); override;
   destructor Destroy; override;
   property Registered: boolean read FRegistered;
 published
   { Published declarations }
   property Enabled: Boolean read FEnabled write SetEnabled default true;
   property Key: TShortcut read FHotkey write SetHotkey;
   property OnHotKey: TNotifyEvent read FOnHotKeyPressed write FOnHotKeyPressed;
 end;

procedure Register;

implementation


{ TMyComponent }

constructor TMyComponent.Create(aOwner: TComponent);
begin
 inherited;
 FEnabled := True;
 FHotKey := 0;
 FRegistered := false;
 if not (csDesigning in ComponentState) then
 begin
   prWindow := TWinControl(Self.Owner);
   prOldWndProc := prWindow.WindowProc;
   prWindow.WindowProc := NewWindowProc;
   prHandle := prWindow.Handle;
 end;
end;

destructor TMyComponent.Destroy;
begin
 if not (csDesigning in ComponentState) then
 begin
   UnRegisterKey;
   prWindow.WindowProc := prOldWndProc;
 end;
 inherited;
end;

procedure TMyComponent.Loaded;
begin
 inherited;
 if (FEnabled) and (not (csDesigning in ComponentState)) then RegisterKey;
end;

procedure TMyComponent.NewWindowProc(var Message: TMessage);
begin
 case Message.Msg of
   WM_HOTKEY:
   begin
     if assigned(FOnHotkeyPressed) then
       FOnHotKeyPressed(self);
   end;
 end;
 prOldWndProc(Message);
end;

procedure TMyComponent.RegisterKey;
procedure ShortCutToKey(ShortCut: TShortCut; var Key: Word; var Shift: TShiftState);
begin
  Key := ShortCut and not (scShift + scCtrl + scAlt);
  Shift := [];
  if ShortCut and scShift <> 0 then Include(Shift, ssShift);
  if ShortCut and scCtrl <> 0 then Include(Shift, ssCtrl);
  if ShortCut and scAlt <> 0 then Include(Shift, ssAlt);
end;
var
 lVKey: word;
 lvShift: TShiftstate;
 lModifier: UINT;
begin
 if not FRegistered then
 begin
   lModifier := 0;
   ShortcutToKey(fHotKey, lvKey, lvShift);

   if ssShift in lvShift  then
     lModifier := lModifier or MOD_SHIFT;

   if ssAlt in lvShift then
     lModifier := lModifier or MOD_ALT;

   if ssCtrl in lvShift then
     lModifier := lModifier or MOD_CONTROL;

   FRegistered := RegisterHotKey(prWindow.Handle, 0, lModifier, LOBYTE(lVKey));
 end;
end;

procedure TMyComponent.SetEnabled(const Value: Boolean);
begin
 FEnabled := Value;
 if FEnabled then
   RegisterKey
 else
   UnregisterKey;
end;

procedure TMyComponent.UnRegisterKey;
begin
 if FRegistered then
 begin
   UnregisterHotKey(prHandle, 0);
   FRegistered := False;
 end;
end;

procedure TMyComponent.SetHotKey(const Value: TShortcut);
begin
 if Value <> FHotkey then
 begin
   FHotkey := Value;
   if not (csDesigning in ComponentState) then
   begin
       UnRegisterKey;
       if FEnabled then
         RegisterKey;
   end;
 end;
end;

procedure Register;
begin
 RegisterComponents('Samples', [TMyComponent]);
end;

end.

the Key Shortcut value must be integer (in your case for Escape Key 27) but if you want to show it in object inspector like for the MenuItem Shorcut property you need a property editor...
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Communication Between RC4 Delphi <-> PHP 3 123
Delphi XE10 Round Image 2 158
Tvertscrollbox like a whatsapp layout delete messages 1 24
DBCtrlGrid, Delphi, Scroll 7 26
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question