|
|
|
@@ -9,170 +9,162 @@ unit uutlEventManager; |
|
|
|
interface |
|
|
|
|
|
|
|
uses |
|
|
|
Classes, SysUtils, syncobjs, Controls, |
|
|
|
uutlGenerics; |
|
|
|
Classes, SysUtils, Controls, |
|
|
|
uutlEvent; |
|
|
|
|
|
|
|
type |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
TutlEventManager = class(TObject) |
|
|
|
public type |
|
|
|
TEventType = 0..63; |
|
|
|
TEventTypeMask = UInt64; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////// |
|
|
|
TEvent = class |
|
|
|
public |
|
|
|
EventType: TEventType; |
|
|
|
Timestamp: QWord; |
|
|
|
|
|
|
|
function Clone: TEvent; |
|
|
|
procedure Assign(const aEvent: TEvent); virtual; |
|
|
|
constructor Create; virtual; |
|
|
|
end; |
|
|
|
TEventClass = class of TEvent; |
|
|
|
TEventList = specialize TutlList<TEvent>; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////// |
|
|
|
TEventListener = class(TObject) |
|
|
|
public |
|
|
|
function DispatchEvent(const aEvent: TEvent): Boolean; virtual; |
|
|
|
end; |
|
|
|
TEventListenerSet = specialize TutlHashSet<TEventListener>; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////// |
|
|
|
TEventHandlerCallback = procedure(aSender: TObject; aEvent: TEvent) of object; |
|
|
|
TCallbackEventListener = class(TEventListener) |
|
|
|
public |
|
|
|
Callback: TEventHandlerCallback; |
|
|
|
Filter: TEventTypeMask; |
|
|
|
function DispatchEvent(const aEvent: TEvent): Boolean; override; |
|
|
|
end; |
|
|
|
|
|
|
|
TutlMouseButtons = set of TMouseButton; |
|
|
|
TutlWinControlEvent = class(TutlEvent) |
|
|
|
private |
|
|
|
fEventQueue: TEventList; |
|
|
|
fEventQueueLock: TCriticalSection; |
|
|
|
fEventListener: TEventListenerSet; |
|
|
|
|
|
|
|
procedure DispatchEvent(const aEvent: TEvent); |
|
|
|
protected |
|
|
|
procedure PushEvent(const aEvent: TEvent); virtual; |
|
|
|
procedure RecordEvent(const aEvent: TEvent); virtual; |
|
|
|
fSender: TControl; |
|
|
|
public |
|
|
|
procedure RegisterListener(const aEventMask: TEventTypeMask; const aCallback: TEventHandlerCallback); |
|
|
|
procedure RegisterListener(const aListener: TEventListener); |
|
|
|
property Sender: TControl read fSender; |
|
|
|
constructor Create( |
|
|
|
const aEventType: TutlEventType; |
|
|
|
const aSender: TControl); |
|
|
|
end; |
|
|
|
|
|
|
|
procedure UnregisterListener(const aHandler: TEventHandlerCallback); |
|
|
|
procedure UnregisterListener(const aListener: TEventListener); |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
TutlMouseEvent = class(TutlWinControlEvent) |
|
|
|
private |
|
|
|
fButtons: TutlMouseButtons; |
|
|
|
fClientPos: TPoint; |
|
|
|
fScreenPos: TPoint; |
|
|
|
|
|
|
|
procedure DispatchEvents; |
|
|
|
public |
|
|
|
property Buttons: TutlMouseButtons read fButtons; |
|
|
|
property ClientPos: TPoint read fClientPos; |
|
|
|
property ScreenPos: TPoint read fScreenPos; |
|
|
|
|
|
|
|
constructor Create( |
|
|
|
const aEventType: TutlEventType; |
|
|
|
const aSender: TControl; |
|
|
|
const aButtons: TutlMouseButtons; |
|
|
|
const aClientPos: TPoint); |
|
|
|
end; |
|
|
|
|
|
|
|
constructor Create; |
|
|
|
destructor Destroy; override; |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
TutlMouseWheelEvent = class(TutlWinControlEvent) |
|
|
|
private |
|
|
|
fWheelDelta: Integer; |
|
|
|
fClientPos: TPoint; |
|
|
|
fScreenPos: TPoint; |
|
|
|
|
|
|
|
public |
|
|
|
class function MakeMask (const aTypes: array of TEventType): TEventTypeMask; |
|
|
|
class function CombineMasks(const aMasks: array of TEventTypeMask): TEventTypeMask; |
|
|
|
class function MaskHasType (const aMask: TEventTypeMask; const aType: TEventType): Boolean; inline; |
|
|
|
property WheelDelta: Integer read fWheelDelta; |
|
|
|
property ClientPos: TPoint read fClientPos; |
|
|
|
property ScreenPos: TPoint read fScreenPos; |
|
|
|
|
|
|
|
constructor Create( |
|
|
|
const aSender: TControl; |
|
|
|
const aWheelDelta: Integer; |
|
|
|
const aClientPos: TPoint); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
TutlWinControlEventManager = class(TutlEventManager) |
|
|
|
public type |
|
|
|
//////////////////////////////////////////////////////////////////////////// |
|
|
|
TMouseEvent = class(TEvent) |
|
|
|
public |
|
|
|
Button: TMouseButton; |
|
|
|
ClientPos: TPoint; |
|
|
|
ScreenPos: TPoint; |
|
|
|
procedure Assign(const aEvent: TEvent); override; |
|
|
|
end; |
|
|
|
TutlKeyEvent = class(TutlWinControlEvent) |
|
|
|
private |
|
|
|
fCharCode: WideChar; |
|
|
|
fKeyCode: Word; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////// |
|
|
|
TMouseWheelEvent = class(TEvent) |
|
|
|
public |
|
|
|
WheelDelta: Integer; |
|
|
|
ClientPos: TPoint; |
|
|
|
ScreenPos: TPoint; |
|
|
|
procedure Assign(const aEvent: TEvent); override; |
|
|
|
end; |
|
|
|
public |
|
|
|
property CharCode: WideChar read fCharCode; |
|
|
|
property KeyCode: Word read fKeyCode; |
|
|
|
|
|
|
|
constructor Create( |
|
|
|
const aEventType: TutlEventType; |
|
|
|
const aSender: TControl; |
|
|
|
const aCharCode: WideChar; |
|
|
|
const aKeyCode: Word); |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////// |
|
|
|
TKeyEvent = class(TEvent) |
|
|
|
public |
|
|
|
CharCode: WideChar; |
|
|
|
KeyCode: Word; |
|
|
|
procedure Assign(const aEvent: TEvent); override; |
|
|
|
end; |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
TutlWindowEvent = class(TutlWinControlEvent) |
|
|
|
private |
|
|
|
fScreenRect: TRect; |
|
|
|
fClientWidth: Cardinal; |
|
|
|
fClientHeight: Cardinal; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////// |
|
|
|
TWindowEvent = class(TEvent) |
|
|
|
public |
|
|
|
ScreenRect: TRect; |
|
|
|
ClientWidth: Cardinal; |
|
|
|
ClientHeight: Cardinal; |
|
|
|
procedure Assign(const aEvent: TEvent); override; |
|
|
|
end; |
|
|
|
public |
|
|
|
property ScreenRect: TRect read fScreenRect; |
|
|
|
property ClientWidth: Cardinal read fClientWidth; |
|
|
|
property ClientHeight: Cardinal read fClientHeight; |
|
|
|
|
|
|
|
constructor Create( |
|
|
|
const aEventType: TutlEventType; |
|
|
|
const aSender: TControl; |
|
|
|
const aScreenRect: TRect; |
|
|
|
const aClientWidth: Cardinal; |
|
|
|
const aClientHeight: Cardinal); |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////// |
|
|
|
TMouseButtons = set of TMouseButton; |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
TutlWinControlEventManager = class(TutlEventListenerSet) |
|
|
|
public const |
|
|
|
EVENT_MOUSE_DOWN = 0; |
|
|
|
EVENT_MOUSE_UP = 1; |
|
|
|
EVENT_MOUSE_WHEEL_UP = 2; |
|
|
|
EVENT_MOUSE_WHEEL_DOWN = 3; |
|
|
|
EVENT_MOUSE_MOVE = 4; |
|
|
|
EVENT_MOUSE_ENTER = 5; |
|
|
|
EVENT_MOUSE_LEAVE = 6; |
|
|
|
EVENT_MOUSE_CLICK = 7; |
|
|
|
EVENT_MOUSE_DBL_CLICK = 8; |
|
|
|
|
|
|
|
EVENT_KEY_DOWN = 10; |
|
|
|
EVENT_KEY_REPEAT = 11; |
|
|
|
EVENT_KEY_UP = 12; |
|
|
|
|
|
|
|
EVENT_WINDOW_RESIZE = 15; |
|
|
|
EVENT_WINDOW_ACTIVATE = 16; |
|
|
|
EVENT_WINDOW_DEACTIVATE = 17; |
|
|
|
|
|
|
|
EVENTS_MOUSE: TutlEventTypes = [ |
|
|
|
EVENT_MOUSE_DOWN, |
|
|
|
EVENT_MOUSE_UP, |
|
|
|
EVENT_MOUSE_WHEEL_UP, |
|
|
|
EVENT_MOUSE_WHEEL_DOWN, |
|
|
|
EVENT_MOUSE_MOVE, |
|
|
|
EVENT_MOUSE_ENTER, |
|
|
|
EVENT_MOUSE_LEAVE, |
|
|
|
EVENT_MOUSE_CLICK, |
|
|
|
EVENT_MOUSE_DBL_CLICK |
|
|
|
]; |
|
|
|
EVENTS_KEYBOARD: TutlEventTypes = [ |
|
|
|
EVENT_KEY_DOWN, |
|
|
|
EVENT_KEY_REPEAT, |
|
|
|
EVENT_KEY_UP |
|
|
|
]; |
|
|
|
EVENTS_WINDOW: TutlEventTypes = [ |
|
|
|
EVENT_WINDOW_RESIZE, |
|
|
|
EVENT_WINDOW_ACTIVATE, |
|
|
|
EVENT_WINDOW_DEACTIVATE |
|
|
|
]; |
|
|
|
|
|
|
|
private type |
|
|
|
TKeyboardState = record |
|
|
|
Modifiers: TShiftState; |
|
|
|
KeyState: array[Byte] of Boolean; |
|
|
|
end; |
|
|
|
|
|
|
|
TMouseState = record |
|
|
|
ScreenPos, ClientPos: TPoint; |
|
|
|
Buttons: TMouseButtons; |
|
|
|
ScreenPos: TPoint; |
|
|
|
ClientPos: TPoint; |
|
|
|
Buttons: TutlMouseButtons; |
|
|
|
end; |
|
|
|
|
|
|
|
TWindowState = record |
|
|
|
Active: boolean; |
|
|
|
Active: Boolean; |
|
|
|
ScreenRect: TRect; |
|
|
|
ClientWidth: Integer; |
|
|
|
ClientHeight: Integer; |
|
|
|
end; |
|
|
|
|
|
|
|
public const |
|
|
|
MOUSE_DOWN = 0; |
|
|
|
MOUSE_UP = 1; |
|
|
|
MOUSE_WHEEL_UP = 2; |
|
|
|
MOUSE_WHEEL_DOWN = 3; |
|
|
|
MOUSE_MOVE = 4; |
|
|
|
MOUSE_ENTER = 5; |
|
|
|
MOUSE_LEAVE = 6; |
|
|
|
MOUSE_CLICK = 7; |
|
|
|
MOUSE_DBL_CLICK = 8; |
|
|
|
|
|
|
|
KEY_DOWN = 10; |
|
|
|
KEY_REPEAT = 11; |
|
|
|
KEY_UP = 12; |
|
|
|
|
|
|
|
WINDOW_RESIZE = 15; |
|
|
|
WINDOW_ACTIVATE = 16; |
|
|
|
WINDOW_DEACTIVATE = 17; |
|
|
|
|
|
|
|
EVENTS_MOUSE: TEventTypeMask = |
|
|
|
(1 shl MOUSE_DOWN) or |
|
|
|
(1 shl MOUSE_UP) or |
|
|
|
(1 shl MOUSE_WHEEL_UP) or |
|
|
|
(1 shl MOUSE_WHEEL_DOWN) or |
|
|
|
(1 shl MOUSE_MOVE) or |
|
|
|
(1 shl MOUSE_ENTER) or |
|
|
|
(1 shl MOUSE_LEAVE) or |
|
|
|
(1 shl MOUSE_CLICK) or |
|
|
|
(1 shl MOUSE_DBL_CLICK); |
|
|
|
EVENTS_KEYBOARD: TEventTypeMask = |
|
|
|
(1 shl KEY_DOWN) or |
|
|
|
(1 shl KEY_REPEAT) or |
|
|
|
(1 shl KEY_UP); |
|
|
|
EVENTS_WINDOW: TEventTypeMask = |
|
|
|
(1 shl WINDOW_RESIZE) or |
|
|
|
(1 shl WINDOW_ACTIVATE) or |
|
|
|
(1 shl WINDOW_DEACTIVATE); |
|
|
|
private |
|
|
|
fKeyboard: TKeyboardState; |
|
|
|
fMouse: TMouseState; |
|
|
|
fWindow: TWindowState; |
|
|
|
|
|
|
|
private |
|
|
|
procedure HandlerMouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); |
|
|
|
procedure HandlerMouseUp (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); |
|
|
|
procedure HandlerMouseMove (Sender: TObject; Shift: TShiftState; X, Y: Integer); |
|
|
|
@@ -190,27 +182,41 @@ type |
|
|
|
procedure HandlerDeactivate (Sender: TObject); |
|
|
|
|
|
|
|
protected |
|
|
|
procedure RecordEvent(const aEvent: TEvent); override; |
|
|
|
procedure RecordEvent(const aEvent: IutlEvent); virtual; |
|
|
|
|
|
|
|
protected |
|
|
|
function CreateMouseEvent (aEvent: TMouseEvent; aType: TEventType; aButton: TMouseButton; aClientPos, aScreenPos: TPoint): TMouseEvent; virtual; |
|
|
|
function CreateMouseWheelEvent(aEvent: TMouseWheelEvent; aSender: TWinControl; aDelta: Integer; aClientPos: TPoint): TMouseWheelEvent; virtual; |
|
|
|
function CreateKeyEvent (aEvent: TKeyEvent; aType: TEventType; aKey: Word): TKeyEvent; virtual; |
|
|
|
function CreateWindowEvent (aEvent: TWindowEvent; aType: TEventType; aSender: TControl): TWindowEvent; virtual; |
|
|
|
function CreateMouseEvent( |
|
|
|
aSender: TObject; |
|
|
|
aType: TutlEventType; |
|
|
|
aButtons: TutlMouseButtons; |
|
|
|
aClientPos: TPoint): TutlMouseEvent; virtual; |
|
|
|
|
|
|
|
function CreateMouseWheelEvent( |
|
|
|
aSender: TObject; |
|
|
|
aDelta: Integer; |
|
|
|
aClientPos: TPoint): TutlMouseWheelEvent; virtual; |
|
|
|
|
|
|
|
function CreateKeyEvent( |
|
|
|
aSender: TObject; aType: TutlEventType; |
|
|
|
aKey: Word): TutlKeyEvent; virtual; |
|
|
|
|
|
|
|
function CreateWindowEvent( |
|
|
|
aSender: TObject; |
|
|
|
aType: TutlEventType): TutlWindowEvent; virtual; |
|
|
|
|
|
|
|
public |
|
|
|
property Keyboard: TKeyboardState read fKeyboard; |
|
|
|
property Mouse: TMouseState read fMouse; |
|
|
|
property Window: TWindowState read fWindow; |
|
|
|
|
|
|
|
procedure AttachEvents(const aControl: TWinControl; const aMask: TEventTypeMask); |
|
|
|
procedure DispatchEvent(const aEvent: IutlEvent); override; |
|
|
|
procedure AttachEvents(const aControl: TWinControl; const aTypes: TutlEventTypes); |
|
|
|
end; |
|
|
|
|
|
|
|
implementation |
|
|
|
|
|
|
|
uses |
|
|
|
LCLIntf, Forms, |
|
|
|
uutlTiming, uutlConversion, uutlKeyCodes; |
|
|
|
uutlKeyCodes; |
|
|
|
|
|
|
|
type |
|
|
|
TWinControlVisibilityClass = class(TWinControl) |
|
|
|
@@ -232,339 +238,167 @@ type |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlEventManager.TEvent//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function TutlEventManager.TEvent.Clone: TEvent; |
|
|
|
begin |
|
|
|
result := TEventClass(ClassType).Create; |
|
|
|
result.Assign(self); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlEventManager.TEvent.Assign(const aEvent: TEvent); |
|
|
|
begin |
|
|
|
Timestamp := aEvent.Timestamp; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
constructor TutlEventManager.TEvent.Create; |
|
|
|
begin |
|
|
|
inherited Create; |
|
|
|
Timestamp := GetMicroTime; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlEventManager.TEventListener//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function TutlEventManager.TEventListener.DispatchEvent(const aEvent: TEvent): Boolean; |
|
|
|
begin |
|
|
|
result := false; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlEventManager.TCallbackEventListener//////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function TutlEventManager.TCallbackEventListener.DispatchEvent(const aEvent: TEvent): Boolean; |
|
|
|
begin |
|
|
|
result := inherited DispatchEvent(aEvent); |
|
|
|
if TutlEventManager.MaskHasType(Filter, aEvent.EventType) then |
|
|
|
Callback(self, aEvent); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlEventManager/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlEventManager.DispatchEvent(const aEvent: TEvent); |
|
|
|
var |
|
|
|
l: TEventListener; |
|
|
|
begin |
|
|
|
for l in fEventListener do begin |
|
|
|
if l.DispatchEvent(aEvent) then |
|
|
|
break; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlEventManager.PushEvent(const aEvent: TEvent); |
|
|
|
begin |
|
|
|
fEventQueueLock.Enter; |
|
|
|
try |
|
|
|
if Assigned(fEventQueue) then |
|
|
|
fEventQueue.Add(aEvent) |
|
|
|
else if Assigned(aEvent) then |
|
|
|
aEvent.Free; |
|
|
|
finally |
|
|
|
fEventQueueLock.Leave; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlEventManager.RecordEvent(const aEvent: TEvent); |
|
|
|
begin |
|
|
|
// DUMMY |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlEventManager.RegisterListener(const aEventMask: TEventTypeMask; const aCallback: TEventHandlerCallback); |
|
|
|
var |
|
|
|
l: TCallbackEventListener; |
|
|
|
begin |
|
|
|
UnregisterListener(aCallback); |
|
|
|
l := TCallbackEventListener.Create; |
|
|
|
try |
|
|
|
l.Filter := aEventMask; |
|
|
|
l.Callback := aCallback; |
|
|
|
RegisterListener(l); |
|
|
|
except |
|
|
|
FreeAndNil(l); |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlEventManager.RegisterListener(const aListener: TEventListener); |
|
|
|
begin |
|
|
|
fEventListener.Add(aListener); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlEventManager.UnregisterListener(const aHandler: TEventHandlerCallback); |
|
|
|
var |
|
|
|
i: Integer; |
|
|
|
m1, m2: TMethod; |
|
|
|
cel: TCallbackEventListener; |
|
|
|
begin |
|
|
|
m1 := TMethod(aHandler); |
|
|
|
for i := fEventListener.Count-1 downto 0 do |
|
|
|
if Supports(fEventListener[i], TCallbackEventListener, cel) then begin |
|
|
|
m2 := TMethod(cel.Callback); |
|
|
|
if (m1.Data = m2.Data) and |
|
|
|
(m1.Code = m2.Code) then |
|
|
|
fEventListener.Delete(i); |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlEventManager.UnregisterListener(const aListener: TEventListener); |
|
|
|
begin |
|
|
|
fEventListener.Remove(aListener); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlEventManager.DispatchEvents; |
|
|
|
var |
|
|
|
e: TEvent; |
|
|
|
begin |
|
|
|
fEventQueueLock.Acquire; |
|
|
|
try |
|
|
|
if Assigned(fEventQueue) then begin |
|
|
|
for e in fEventQueue do begin |
|
|
|
DispatchEvent(e); |
|
|
|
RecordEvent(e); |
|
|
|
end; |
|
|
|
fEventQueue.Clear; |
|
|
|
end; |
|
|
|
finally |
|
|
|
fEventQueueLock.Release; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
constructor TutlEventManager.Create; |
|
|
|
begin |
|
|
|
inherited Create; |
|
|
|
fEventListener := TEventListenerSet.Create(true); |
|
|
|
fEventQueue := TEventList.Create(true); |
|
|
|
fEventQueueLock := TCriticalSection.Create; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
destructor TutlEventManager.Destroy; |
|
|
|
begin |
|
|
|
fEventQueueLock.Enter; |
|
|
|
try |
|
|
|
FreeAndNil(fEventQueue); |
|
|
|
finally |
|
|
|
fEventQueueLock.Leave; |
|
|
|
end; |
|
|
|
FreeAndNil(fEventQueueLock); |
|
|
|
FreeAndNil(fEventListener); |
|
|
|
inherited Destroy; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
class function TutlEventManager.MakeMask(const aTypes: array of TEventType): TEventTypeMask; |
|
|
|
var |
|
|
|
e: TEventType; |
|
|
|
begin |
|
|
|
result := 0; |
|
|
|
for e in aTypes do |
|
|
|
result := result or (1 shl e); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
class function TutlEventManager.CombineMasks(const aMasks: array of TEventTypeMask): TEventTypeMask; |
|
|
|
var |
|
|
|
m: TEventTypeMask; |
|
|
|
begin |
|
|
|
result := 0; |
|
|
|
for m in aMasks do |
|
|
|
result := result or m; |
|
|
|
end; |
|
|
|
|
|
|
|
//TutlWinControlEvent//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
class function TutlEventManager.MaskHasType(const aMask: TEventTypeMask; const aType: TEventType): Boolean; |
|
|
|
constructor TutlWinControlEvent.Create(const aEventType: TutlEventType; const aSender: TControl); |
|
|
|
begin |
|
|
|
result := ((aMask and (1 shl aType)) <> 0); |
|
|
|
inherited Create(aEventType); |
|
|
|
fSender := aSender; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlWinControlEventManager.TMouseEvent///////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlMouseEvent///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.TMouseEvent.Assign(const aEvent: TEvent); |
|
|
|
var |
|
|
|
me: TMouseEvent; |
|
|
|
constructor TutlMouseEvent.Create( |
|
|
|
const aEventType: TutlEventType; |
|
|
|
const aSender: TControl; |
|
|
|
const aButtons: TutlMouseButtons; |
|
|
|
const aClientPos: TPoint); |
|
|
|
begin |
|
|
|
inherited Assign(aEvent); |
|
|
|
if Supports(aEvent, TMouseEvent, me) then begin |
|
|
|
Button := me.Button; |
|
|
|
ClientPos := me.ClientPos; |
|
|
|
ScreenPos := me.ScreenPos; |
|
|
|
end; |
|
|
|
inherited Create(aEventType, aSender); |
|
|
|
fButtons := aButtons; |
|
|
|
fClientPos := aClientPos; |
|
|
|
fScreenPos := fSender.ClientToScreen(fClientPos); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlWinControlEventManager.TMouseWheelEvent//////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlMouseWheelEvent//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.TMouseWheelEvent.Assign(const aEvent: TEvent); |
|
|
|
var |
|
|
|
mwe: TMouseWheelEvent; |
|
|
|
constructor TutlMouseWheelEvent.Create( |
|
|
|
const aSender: TControl; |
|
|
|
const aWheelDelta: Integer; |
|
|
|
const aClientPos: TPoint); |
|
|
|
begin |
|
|
|
inherited Assign(aEvent); |
|
|
|
if Supports(aEvent, TMouseWheelEvent, mwe) then begin |
|
|
|
WheelDelta := mwe.WheelDelta; |
|
|
|
ClientPos := mwe.ClientPos; |
|
|
|
ScreenPos := mwe.ScreenPos; |
|
|
|
end; |
|
|
|
if (aWheelDelta < 0) |
|
|
|
then inherited Create(TutlWinControlEventManager.EVENT_MOUSE_WHEEL_DOWN, aSender) |
|
|
|
else inherited Create(TutlWinControlEventManager.EVENT_MOUSE_WHEEL_UP, aSender); |
|
|
|
fWheelDelta := aWheelDelta; |
|
|
|
fClientPos := aClientPos; |
|
|
|
fScreenPos := fSender.ClientToScreen(fClientPos); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlWinControlEventManager.TKeyEvent/////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlKeyEvent/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.TKeyEvent.Assign(const aEvent: TEvent); |
|
|
|
var |
|
|
|
ke: TKeyEvent; |
|
|
|
constructor TutlKeyEvent.Create( |
|
|
|
const aEventType: TutlEventType; |
|
|
|
const aSender: TControl; |
|
|
|
const aCharCode: WideChar; |
|
|
|
const aKeyCode: Word); |
|
|
|
begin |
|
|
|
inherited Assign(aEvent); |
|
|
|
if Supports(aEvent, TKeyEvent, ke) then begin |
|
|
|
CharCode := ke.CharCode; |
|
|
|
KeyCode := ke.KeyCode; |
|
|
|
end; |
|
|
|
inherited Create(aEventType, aSender); |
|
|
|
fCharCode := aCharCode; |
|
|
|
fKeyCode := aKeyCode; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlWinControlEventManager.TWindowEvent//////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlWindowEvent//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.TWindowEvent.Assign(const aEvent: TEvent); |
|
|
|
var |
|
|
|
we: TWindowEvent; |
|
|
|
constructor TutlWindowEvent.Create( |
|
|
|
const aEventType: TutlEventType; |
|
|
|
const aSender: TControl; |
|
|
|
const aScreenRect: TRect; |
|
|
|
const aClientWidth: Cardinal; |
|
|
|
const aClientHeight: Cardinal); |
|
|
|
begin |
|
|
|
inherited Assign(aEvent); |
|
|
|
if Supports(aEvent, TWindowEvent, we) then begin |
|
|
|
ScreenRect := we.ScreenRect; |
|
|
|
ClientWidth := we.ClientWidth; |
|
|
|
ClientHeight := we.ClientHeight; |
|
|
|
end; |
|
|
|
inherited Create(aEventType, aSender); |
|
|
|
fScreenRect := aScreenRect; |
|
|
|
fClientWidth := aClientWidth; |
|
|
|
fClientHeight := aClientHeight; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TutlWinControlEventManager///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); |
|
|
|
procedure TutlWinControlEventManager.HandlerMouseDown(Sender: TObject; Button: TMouseButton; |
|
|
|
Shift: TShiftState; X, Y: Integer); |
|
|
|
begin |
|
|
|
PushEvent(CreateMouseEvent(nil, MOUSE_DOWN, Button, Point(X, Y), TWinControl(Sender).ClientToScreen(Point(X, Y)))); |
|
|
|
DispatchEvent(CreateMouseEvent(Sender, EVENT_MOUSE_DOWN, [ Button ], Point(X, Y))); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); |
|
|
|
procedure TutlWinControlEventManager.HandlerMouseUp(Sender: TObject; Button: TMouseButton; |
|
|
|
Shift: TShiftState; X, Y: Integer); |
|
|
|
begin |
|
|
|
PushEvent(CreateMouseEvent(nil, MOUSE_UP, Button, Point(X, Y), TWinControl(Sender).ClientToScreen(Point(X, Y)))); |
|
|
|
DispatchEvent(CreateMouseEvent(Sender, EVENT_MOUSE_UP, [Button], Point(X, Y))); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); |
|
|
|
begin |
|
|
|
PushEvent(CreateMouseEvent(nil, MOUSE_MOVE, mbLeft, Point(X, Y), TWinControl(Sender).ClientToScreen(Point(X, Y)))); |
|
|
|
DispatchEvent(CreateMouseEvent(Sender, EVENT_MOUSE_MOVE, [], Point(X, Y))); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerMouseEnter(Sender: TObject); |
|
|
|
begin |
|
|
|
PushEvent(CreateMouseEvent(nil, MOUSE_ENTER, mbLeft, TWinControl(Sender).ScreenToClient(Controls.Mouse.CursorPos), Controls.Mouse.CursorPos)); |
|
|
|
DispatchEvent(CreateMouseEvent(Sender, EVENT_MOUSE_ENTER, [], TControl(Sender).ScreenToClient(Controls.Mouse.CursorPos))); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerMouseLeave(Sender: TObject); |
|
|
|
begin |
|
|
|
PushEvent(CreateMouseEvent(nil, MOUSE_LEAVE, mbLeft, TWinControl(Sender).ScreenToClient(Controls.Mouse.CursorPos), Controls.Mouse.CursorPos)); |
|
|
|
DispatchEvent(CreateMouseEvent(Sender, EVENT_MOUSE_LEAVE, [], TControl(Sender).ScreenToClient(Controls.Mouse.CursorPos))); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerClick(Sender: TObject); |
|
|
|
begin |
|
|
|
PushEvent(CreateMouseEvent(nil, MOUSE_CLICK, mbLeft, TWinControl(Sender).ScreenToClient(Controls.Mouse.CursorPos), Controls.Mouse.CursorPos)); |
|
|
|
DispatchEvent(CreateMouseEvent(Sender, EVENT_MOUSE_CLICK, [], TControl(Sender).ScreenToClient(Controls.Mouse.CursorPos))); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerDblClick(Sender: TObject); |
|
|
|
begin |
|
|
|
PushEvent(CreateMouseEvent(nil, MOUSE_DBL_CLICK, mbLeft, TWinControl(Sender).ScreenToClient(Controls.Mouse.CursorPos), Controls.Mouse.CursorPos)); |
|
|
|
DispatchEvent(CreateMouseEvent(Sender, EVENT_MOUSE_DBL_CLICK, [], TControl(Sender).ScreenToClient(Controls.Mouse.CursorPos))); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); |
|
|
|
procedure TutlWinControlEventManager.HandlerMouseWheel(Sender: TObject; Shift: TShiftState; |
|
|
|
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); |
|
|
|
begin |
|
|
|
PushEvent(CreateMouseWheelEvent(nil, TWinControl(Sender), WheelDelta, MousePos)); |
|
|
|
DispatchEvent(CreateMouseWheelEvent(Sender, WheelDelta, MousePos)); |
|
|
|
Handled := false; |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); |
|
|
|
begin |
|
|
|
PushEvent(CreateKeyEvent(nil, KEY_DOWN, Key)); |
|
|
|
DispatchEvent(CreateKeyEvent(Sender, EVENT_KEY_DOWN, Key)); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); |
|
|
|
begin |
|
|
|
PushEvent(CreateKeyEvent(nil, KEY_UP, Key)); |
|
|
|
DispatchEvent(CreateKeyEvent(Sender, EVENT_KEY_UP, Key)); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerResize(Sender: TObject); |
|
|
|
begin |
|
|
|
PushEvent(CreateWindowEvent(nil, WINDOW_RESIZE, TControl(Sender))); |
|
|
|
DispatchEvent(CreateWindowEvent(Sender, EVENT_WINDOW_RESIZE)); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerActivate(Sender: TObject); |
|
|
|
begin |
|
|
|
PushEvent(CreateWindowEvent(nil, WINDOW_ACTIVATE, TControl(Sender))); |
|
|
|
DispatchEvent(CreateWindowEvent(Sender, EVENT_WINDOW_ACTIVATE)); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.HandlerDeactivate(Sender: TObject); |
|
|
|
begin |
|
|
|
PushEvent(CreateWindowEvent(nil, WINDOW_DEACTIVATE, TControl(Sender))); |
|
|
|
DispatchEvent(CreateWindowEvent(Sender, EVENT_WINDOW_DEACTIVATE)); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.RecordEvent(const aEvent: TEvent); |
|
|
|
procedure TutlWinControlEventManager.RecordEvent(const aEvent: IutlEvent); |
|
|
|
var |
|
|
|
me: TMouseEvent; |
|
|
|
ke: TKeyEvent; |
|
|
|
we: TWindowEvent; |
|
|
|
me: TutlMouseEvent; |
|
|
|
ke: TutlKeyEvent; |
|
|
|
we: TutlWindowEvent; |
|
|
|
|
|
|
|
function GetPressedButtons: TMouseButtons; |
|
|
|
function GetPressedButtons: TutlMouseButtons; |
|
|
|
begin |
|
|
|
result := []; |
|
|
|
if (GetKeyState(VK_LBUTTON) < 0) then |
|
|
|
@@ -580,26 +414,24 @@ var |
|
|
|
end; |
|
|
|
|
|
|
|
begin |
|
|
|
inherited RecordEvent(aEvent); |
|
|
|
|
|
|
|
if Supports(aEvent, TMouseEvent, me) then begin |
|
|
|
if Supports(aEvent, TutlMouseEvent, me) then begin |
|
|
|
fMouse.ClientPos := me.ClientPos; |
|
|
|
fMouse.ScreenPos := me.ScreenPos; |
|
|
|
case me.EventType of |
|
|
|
MOUSE_DOWN: |
|
|
|
Include(fMouse.Buttons, me.Button); |
|
|
|
MOUSE_UP: |
|
|
|
Exclude(fMouse.Buttons, me.Button); |
|
|
|
MOUSE_LEAVE: |
|
|
|
EVENT_MOUSE_DOWN: |
|
|
|
fMouse.Buttons := fMouse.Buttons + me.Buttons; |
|
|
|
EVENT_MOUSE_UP: |
|
|
|
fMouse.Buttons := fMouse.Buttons - me.Buttons; |
|
|
|
EVENT_MOUSE_LEAVE: |
|
|
|
fMouse.Buttons := []; |
|
|
|
MOUSE_ENTER: |
|
|
|
EVENT_MOUSE_ENTER: |
|
|
|
fMouse.Buttons := GetPressedButtons; |
|
|
|
end; |
|
|
|
|
|
|
|
end else if Supports(aEvent, TKeyEvent, ke) then begin |
|
|
|
end else if Supports(aEvent, TutlKeyEvent, ke) then begin |
|
|
|
case ke.EventType of |
|
|
|
KEY_DOWN, |
|
|
|
KEY_REPEAT: begin |
|
|
|
EVENT_KEY_DOWN, |
|
|
|
EVENT_KEY_REPEAT: begin |
|
|
|
fKeyboard.KeyState[ke.KeyCode and $FF] := true; |
|
|
|
case ke.KeyCode of |
|
|
|
VK_SHIFT: Include(fKeyboard.Modifiers, ssShift); |
|
|
|
@@ -607,7 +439,7 @@ begin |
|
|
|
VK_CONTROL: Include(fKeyboard.Modifiers, ssCtrl); |
|
|
|
end; |
|
|
|
end; |
|
|
|
KEY_UP: begin |
|
|
|
EVENT_KEY_UP: begin |
|
|
|
fKeyboard.KeyState[ke.KeyCode and $FF] := false; |
|
|
|
case ke.KeyCode of |
|
|
|
VK_SHIFT: Exclude(fKeyboard.Modifiers, ssShift); |
|
|
|
@@ -620,13 +452,13 @@ begin |
|
|
|
then include(fKeyboard.Modifiers, ssAltGr) |
|
|
|
else exclude(fKeyboard.Modifiers, ssAltGr); |
|
|
|
|
|
|
|
end else if Supports(aEvent, TWindowEvent, we) then begin |
|
|
|
end else if Supports(aEvent, TutlWindowEvent, we) then begin |
|
|
|
case we.EventType of |
|
|
|
WINDOW_ACTIVATE: |
|
|
|
EVENT_WINDOW_ACTIVATE: |
|
|
|
fWindow.Active := true; |
|
|
|
WINDOW_DEACTIVATE: |
|
|
|
EVENT_WINDOW_DEACTIVATE: |
|
|
|
fWindow.Active := false; |
|
|
|
WINDOW_RESIZE: begin |
|
|
|
EVENT_WINDOW_RESIZE: begin |
|
|
|
fWindow.ScreenRect := we.ScreenRect; |
|
|
|
fWindow.ClientWidth := we.ClientWidth; |
|
|
|
fWindow.ClientHeight := we.ClientHeight; |
|
|
|
@@ -636,61 +468,64 @@ begin |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function TutlWinControlEventManager.CreateMouseEvent(aEvent: TMouseEvent; aType: TEventType; aButton: TMouseButton; aClientPos, aScreenPos: TPoint): TMouseEvent; |
|
|
|
function TutlWinControlEventManager.CreateMouseEvent(aSender: TObject; aType: TutlEventType; |
|
|
|
aButtons: TutlMouseButtons; aClientPos: TPoint): TutlMouseEvent; |
|
|
|
begin |
|
|
|
result := aEvent; |
|
|
|
if not Assigned(result) then |
|
|
|
result := TMouseEvent.Create; |
|
|
|
result.EventType := aType; |
|
|
|
result.Button := aButton; |
|
|
|
result.ClientPos := aClientPos; |
|
|
|
result.ScreenPos := aScreenPos; |
|
|
|
result := TutlMouseEvent.Create( |
|
|
|
aType, |
|
|
|
(aSender as TControl), |
|
|
|
aButtons, |
|
|
|
aClientPos); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function TutlWinControlEventManager.CreateMouseWheelEvent(aEvent: TMouseWheelEvent; aSender: TWinControl; aDelta: Integer; aClientPos: TPoint): TMouseWheelEvent; |
|
|
|
function TutlWinControlEventManager.CreateMouseWheelEvent(aSender: TObject; aDelta: Integer; |
|
|
|
aClientPos: TPoint): TutlMouseWheelEvent; |
|
|
|
begin |
|
|
|
result := aEvent; |
|
|
|
if not Assigned(result) then |
|
|
|
result := TMouseWheelEvent.Create; |
|
|
|
result.ClientPos := aClientPos; |
|
|
|
result.ScreenPos := aSender.ClientToScreen(aClientPos); |
|
|
|
result.WheelDelta := aDelta; |
|
|
|
if (aDelta < 0) |
|
|
|
then result.EventType := MOUSE_WHEEL_DOWN |
|
|
|
else result.EventType := MOUSE_WHEEL_UP; |
|
|
|
result := TutlMouseWheelEvent.Create( |
|
|
|
(aSender as TControl), |
|
|
|
aDelta, |
|
|
|
aClientPos); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function TutlWinControlEventManager.CreateKeyEvent(aEvent: TKeyEvent; aType: TEventType; aKey: Word): TKeyEvent; |
|
|
|
function TutlWinControlEventManager.CreateKeyEvent(aSender: TObject; aType: TutlEventType; aKey: Word): TutlKeyEvent; |
|
|
|
begin |
|
|
|
result := aEvent; |
|
|
|
if not Assigned(result) then |
|
|
|
result := TKeyEvent.Create; |
|
|
|
result.EventType := aType; |
|
|
|
if (aType = KEY_DOWN) and fKeyboard.KeyState[aKey and $FF] then |
|
|
|
result.EventType := KEY_REPEAT; |
|
|
|
result.KeyCode := aKey; |
|
|
|
result.CharCode := VKCodeToCharCode(aKey, fKeyboard.Modifiers); |
|
|
|
if (aType = EVENT_KEY_DOWN) and fKeyboard.KeyState[aKey and $FF] then |
|
|
|
aType := EVENT_KEY_REPEAT; |
|
|
|
result := TutlKeyEvent.Create( |
|
|
|
aType, |
|
|
|
(aSender as TControl), |
|
|
|
VKCodeToCharCode(aKey, fKeyboard.Modifiers), |
|
|
|
aKey); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function TutlWinControlEventManager.CreateWindowEvent(aEvent: TWindowEvent; aType: TEventType; aSender: TControl): TWindowEvent; |
|
|
|
function TutlWinControlEventManager.CreateWindowEvent(aSender: TObject; aType: TutlEventType): TutlWindowEvent; |
|
|
|
var |
|
|
|
p: TPoint; |
|
|
|
p0, p1: TPoint; |
|
|
|
begin |
|
|
|
with TControl(aSender) do begin |
|
|
|
p0 := ClientToScreen(Point(0, 0)); |
|
|
|
p1 := ClientToScreen(Point(Width, Height)); |
|
|
|
end; |
|
|
|
result := TutlWindowEvent.Create( |
|
|
|
aType, |
|
|
|
(aSender as TControl), |
|
|
|
Rect(p0.x, p0.y, p1.x, p1.y), |
|
|
|
(aSender as TWinControl).ClientWidth, |
|
|
|
(aSender as TWinControl).ClientHeight); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.DispatchEvent(const aEvent: IutlEvent); |
|
|
|
begin |
|
|
|
p := aSender.ScreenToClient(Point(0, 0)); |
|
|
|
result := aEvent; |
|
|
|
if not Assigned(result) then |
|
|
|
result := TWindowEvent.Create; |
|
|
|
result.EventType := aType; |
|
|
|
result.ClientWidth := aSender.ClientWidth; |
|
|
|
result.ClientHeight := aSender.ClientHeight; |
|
|
|
result.ScreenRect := Rect(p.x, p.y, p.x + result.ClientWidth, p.y + result.ClientHeight); |
|
|
|
RecordEvent(aEvent); |
|
|
|
inherited DispatchEvent(aEvent); |
|
|
|
end; |
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure TutlWinControlEventManager.AttachEvents(const aControl: TWinControl; const aMask: TEventTypeMask); |
|
|
|
procedure TutlWinControlEventManager.AttachEvents(const aControl: TWinControl; const aTypes: TutlEventTypes); |
|
|
|
var |
|
|
|
ctl: TWinControlVisibilityClass; |
|
|
|
frm: TCustomFormVisibilityClass; |
|
|
|
@@ -698,22 +533,22 @@ begin |
|
|
|
ctl := TWinControlVisibilityClass(aControl); |
|
|
|
|
|
|
|
// mouse events |
|
|
|
if MaskHasType(aMask, MOUSE_DOWN) then ctl.OnMouseDown := @HandlerMouseDown; |
|
|
|
if MaskHasType(aMask, MOUSE_UP) then ctl.OnMouseUp := @HandlerMouseUp; |
|
|
|
if MaskHasType(aMask, MOUSE_MOVE) then ctl.OnMouseMove := @HandlerMouseMove; |
|
|
|
if MaskHasType(aMask, MOUSE_ENTER) then ctl.OnMouseEnter := @HandlerMouseEnter; |
|
|
|
if MaskHasType(aMask, MOUSE_LEAVE) then ctl.OnMouseLeave := @HandlerMouseLeave; |
|
|
|
if MaskHasType(aMask, MOUSE_CLICK) then ctl.OnClick := @HandlerClick; |
|
|
|
if MaskHasType(aMask, MOUSE_DBL_CLICK) then ctl.OnDblClick := @HandlerDblClick; |
|
|
|
if MaskHasType(aMask, MOUSE_WHEEL_DOWN) or |
|
|
|
MaskHasType(aMask, MOUSE_WHEEL_UP) then ctl.OnMouseWheel := @HandlerMouseWheel; |
|
|
|
if (EVENT_MOUSE_DOWN in aTypes) then ctl.OnMouseDown := @HandlerMouseDown; |
|
|
|
if (EVENT_MOUSE_UP in aTypes) then ctl.OnMouseUp := @HandlerMouseUp; |
|
|
|
if (EVENT_MOUSE_MOVE in aTypes) then ctl.OnMouseMove := @HandlerMouseMove; |
|
|
|
if (EVENT_MOUSE_ENTER in aTypes) then ctl.OnMouseEnter := @HandlerMouseEnter; |
|
|
|
if (EVENT_MOUSE_LEAVE in aTypes) then ctl.OnMouseLeave := @HandlerMouseLeave; |
|
|
|
if (EVENT_MOUSE_CLICK in aTypes) then ctl.OnClick := @HandlerClick; |
|
|
|
if (EVENT_MOUSE_DBL_CLICK in aTypes) then ctl.OnDblClick := @HandlerDblClick; |
|
|
|
if (EVENT_MOUSE_WHEEL_DOWN in aTypes) or |
|
|
|
(EVENT_MOUSE_WHEEL_UP in aTypes) then ctl.OnMouseWheel := @HandlerMouseWheel; |
|
|
|
|
|
|
|
// key events |
|
|
|
if MaskHasType(aMask, KEY_DOWN) then ctl.OnKeyDown := @HandlerKeyDown; |
|
|
|
if MaskHasType(aMask, KEY_UP) then ctl.OnKeyUp := @HandlerKeyUp; |
|
|
|
if (EVENT_KEY_DOWN in aTypes) then ctl.OnKeyDown := @HandlerKeyDown; |
|
|
|
if (EVENT_KEY_UP in aTypes) then ctl.OnKeyUp := @HandlerKeyUp; |
|
|
|
|
|
|
|
// window events |
|
|
|
if MaskHasType(aMask, WINDOW_RESIZE) then begin |
|
|
|
if (EVENT_WINDOW_RESIZE in aTypes) then begin |
|
|
|
ctl.OnResize := @HandlerResize; |
|
|
|
fWindow.ClientWidth := ctl.ClientWidth; |
|
|
|
fWindow.ClientHeight := ctl.ClientHeight; |
|
|
|
@@ -721,8 +556,8 @@ begin |
|
|
|
if (aControl is TCustomForm) then begin |
|
|
|
frm := TCustomFormVisibilityClass(aControl); |
|
|
|
frm.KeyPreview := true; |
|
|
|
if MaskHasType(aMask, WINDOW_ACTIVATE) then frm.OnActivate := @HandlerActivate; |
|
|
|
if MaskHasType(aMask, WINDOW_DEACTIVATE) then frm.OnDeactivate := @HandlerDeactivate; |
|
|
|
if (EVENT_WINDOW_ACTIVATE in aTypes) then frm.OnActivate := @HandlerActivate; |
|
|
|
if (EVENT_WINDOW_DEACTIVATE in aTypes) then frm.OnDeactivate := @HandlerDeactivate; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
|