PDA

Ver la Versión Completa : TComponent y Handle


ixMike
24-04-2007, 20:24:42
Hola a todos,

¿alguien sabe cómo añadirle la propiedad Handle a un TComponent, con todo lo que ello implica?

Es que necesito crear un componente no visible que tiene que recibir un mensaje (concretamente el WM_HOTKEY), y procesarlo.

Gracias desde ya.

roman
24-04-2007, 20:34:06
La componente debe crear una ventana y dirigir a ella los mensajes. Eso puedes hacerlo con AllocateHWnd y DeallocateHWnd. En mi página (http://romansg.net/) puedes ver la componente TCDChange (http://romansg.net/index.php?pg=cdchange), en donde se ejemplifica eso.

// Saludos

ixMike
11-05-2007, 19:21:20
Muchísimas gracias, Roman.

Y perdón por la tardanza, he estado de exámenes.

ixMike
25-07-2007, 19:17:26
mmmm

No funciona. ¿En qué unidad están AllocateHWnd y DeallocateHWnd?

Utilizo Delphi 3 standar.



El código lo necesitaba para un componente, el cual analiza el cambio de estado de CapsLock, NumLock y ScrollLock. Para ello necesitaba un HotKey, y por eso necesitaba el Handle de la ventana. Este es el código (por si a alguien se le ocurre cómo solucionar el problema):



unit KeyState;

interface

uses
Windows, Messages, Classes;

type
TKeyState = class(TComponent)
private
aCaps,
aNum,
aScroll: ATOM;
Active,
FCapsLock,
FNumLock,
FScrollLock: Boolean;
FHotKeyName: String;
FOnChange: TNotifyEvent;

InternalWindow: HWnd;
Procedure WndProc(var Msg: TMessage); virtual;

// Procedure WMHotKey(var msg: TWMHotKey); message WM_HOTKEY;

public
Constructor Create(AOwner: TComponent); override;
Destructor Destroy; override;

Procedure Start;
Procedure Stop;

Property CapsLock: Boolean read FCapsLock;
Property NumLock: Boolean read FNumLock;
Property ScrollLock: Boolean read FScrollLock;
Property HotKeyName: String read FHotKeyName write FHotKeyName;

published
Property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;

procedure Register;

implementation

{procedure TKeyState.WMHotKey(var Msg: TWMHotKey);
var
K: TKeyBoardState;
begin
GetKeyBoardState(K);
If Msg.HotKey=aCaps then FCapsLock:=not FCapsLock;
If Msg.HotKey=aNum then FNumLock:=not FNumLock;
If Msg.HotKey=aScroll then FScrollLock:=not FScrollLock;
K[VK_CAPITAL]:=Integer(FCapsLock);
K[VK_NUMLOCK]:=Integer(FNumLock);
K[VK_SCROLL]:=Integer(FScrollLock);
SetKeyBoardState(K);
If Assigned(FOnChange) then FOnChange(Self);
end;}

Procedure TKeyState.WndProc(var Msg: TMessage);
var
K: TKeyBoardState;
begin
If Msg.Msg=WM_HOTKEY then
with TWMHotKey(Msg) do
begin
GetKeyBoardState(K);
If HotKey=aCaps then FCapsLock:=not FCapsLock;
If HotKey=aNum then FNumLock:=not FNumLock;
If HotKey=aScroll then FScrollLock:=not FScrollLock;
K[VK_CAPITAL]:=Integer(FCapsLock);
K[VK_NUMLOCK]:=Integer(FNumLock);
K[VK_SCROLL]:=Integer(FScrollLock);
SetKeyBoardState(K);
If Assigned(FOnChange) then FOnChange(Self);
end;
end;

Constructor TKeyState.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Active:=False;
FCapsLock:=GetKeyState(VK_CAPITAL)=1;
FNumLock:=GetKeyState(VK_NUMLOCK)=1;
FScrollLock:=GetKeyState(VK_SCROLL)=1;
end;

Destructor TKeyState.Destroy;
begin
If Active then Stop;
inherited Destroy;
end;

Procedure TKeyState.Start;
begin
If FHotKeyName='' then Exit;
InternalWindow:=AllocateHWnd(WndProc);
aCaps:=GlobalAddAtom(PChar(FHotKeyName+'C'));
aNum:=GlobalAddAtom(PChar(FHotKeyName+'N'));
aScroll:=GlobalAddAtom(PChar(FHotKeyName+'S'));
RegisterHotKey(InternalWindow, aCaps, 0, VK_CAPITAL);
RegisterHotKey(InternalWindow, aNum, 0, VK_NUMLOCK);
RegisterHotKey(InternalWindow, aScroll, 0, VK_SCROLL);
Active:=True;
end;

Procedure TKeyState.Stop;
begin
If not Active then Exit;
UnRegisterHotKey(InternalWindow, aCaps);
UnRegisterHotKey(InternalWindow, aNum);
UnRegisterHotKey(InternalWindow, aScroll);
GlobalDeleteAtom(aCaps);
GlobalDeleteAtom(aNum);
GlobalDeleteAtom(aScroll);
DeallocateHWnd(InternalWindow);
Active:=False;
end;

procedure Register;
begin
RegisterComponents('LunatikO', [TKeyState]);
end;

end.

ixMike
11-10-2007, 19:20:05
Hola.

¿Alguien tiene solución al problema? Es que Roman me dejó a medio, y como nadie lo ha vuelto a ver...


Muchas gracias (y, Roman, vuelve pronto).

aeff
12-10-2007, 13:45:52
hola, prueba con estas funciones o busca en la ayuda de Delphi al respecto, CallWindowProc, DefDlgProc, WindowProc, SetWindowLong, RegisterClass, debe haber algo por ahi,

ahora realmente estoy contra el tiempo, luego estudiare al respecto, cuando venha deñ colegio,!!

saludos
aeff!