* Keyhandling rework. Virtual keycodes are looked up by the keycode of the key pressed.

+ Added dynamic modifier mask lookup. 

git-svn-id: trunk@10422 -
This commit is contained in:
marc 2007-01-11 01:09:11 +00:00
parent 114f79c897
commit 6c79de53ed
16 changed files with 535 additions and 407 deletions

View File

@ -1431,11 +1431,6 @@ begin
Result := false;
end;
function TWidgetSet.VkKeyScan(AChar: Char): Short;
begin
Result := -1; // $FFFF
end;
Function TWidgetSet.WindowFromPoint(Point : TPoint) : HWND;
begin
Result := 0;

View File

@ -842,11 +842,6 @@ begin
Result := WidgetSet.UpdateWindow(Handle);
end;
function VkKeyScan(AChar: Char): Short;
begin
Result := WidgetSet.VkKeyScan(AChar);
end;
function WindowFromPoint(Point : TPoint) : HWND;
begin
Result := WidgetSet.WindowFromPoint(Point);

View File

@ -237,8 +237,6 @@ function UpdateWindow(Handle: HWND): Boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$E
//function UnionRect --> independent
function VkKeyScan(AChar: Char): Short; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}
Function WindowFromPoint(Point : TPoint) : HWND; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}
//##apiwiz##eps## // Do not remove
{******************************************************************************

View File

@ -978,11 +978,6 @@ begin
Result:=inherited TextOut(DC, X, Y, Str, Count);
end;
function TCarbonWidgetSet.VkKeyScan(AChar: Char): Short;
begin
Result:=inherited VkKeyScan(AChar);
end;
function TCarbonWidgetSet.WindowFromPoint(Point: TPoint): HWND;
begin
Result:=inherited WindowFromPoint(Point);

View File

@ -202,8 +202,6 @@ function StretchMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; X
function TextOut(DC: HDC; X,Y : Integer; Str : Pchar; Count: Integer) : Boolean; override;
function VkKeyScan(AChar: Char): Short; override;
function WindowFromPoint(Point : TPoint) : HWND; override;
//##apiwiz##eps## // Do not remove, no wizard declaration after this line

View File

@ -584,16 +584,24 @@ begin
EventTrace('map', data);
end;
function GTKKeyUpDown(Widget: PGtkWidget; Event: PGdkEventKey;
Data: gPointer) : GBoolean; cdecl;
function GTKKeyPress(Widget: PGtkWidget; Event: PGdkEventKey; Data: gPointer) : GBoolean; cdecl;
begin
Result:=HandleGtkKeyUpDown(Widget,Event,Data,true);
Result := HandleGtkKeyUpDown(Widget,Event,Data,true, True);
end;
function GTKKeyUpDownAfter(Widget: PGtkWidget; Event: pgdkeventkey;
Data: gPointer): GBoolean; cdecl;
function GTKKeyPressAfter(Widget: PGtkWidget; Event: pgdkeventkey; Data: gPointer): GBoolean; cdecl;
begin
Result:=HandleGtkKeyUpDown(Widget,Event,Data,false);
Result := HandleGtkKeyUpDown(Widget,Event,Data,false, True);
end;
function GTKKeyRelease(Widget: PGtkWidget; Event: PGdkEventKey; Data: gPointer) : GBoolean; cdecl;
begin
Result := HandleGtkKeyUpDown(Widget,Event,Data,true, False);
end;
function GTKKeyReleaseAfter(Widget: PGtkWidget; Event: pgdkeventkey; Data: gPointer): GBoolean; cdecl;
begin
Result := HandleGtkKeyUpDown(Widget,Event,Data,false, False);
end;
function GTKFocusCB( widget: PGtkWidget; event:PGdkEventFocus;
@ -914,7 +922,7 @@ begin
Point(TruncToInt(Event^.X),TruncToInt(Event^.Y)),
PGtkWidget(AWinControl.Handle));
ShiftState := GTKEventState2ShiftState(Event^.State);
ShiftState := GTKEventStateToShiftState(Event^.State);
with Msg do
begin
Msg := LM_MouseMove;
@ -1252,7 +1260,7 @@ begin
MousePositionValid:=false;
EventXY:=Point(TruncToInt(Event^.X),TruncToInt(Event^.Y));
ShiftState := GTKEventState2ShiftState(Event^.State);
ShiftState := GTKEventStateToShiftState(Event^.State);
MappedXY:=TranslateGdkPointToClientArea(Event^.Window,EventXY,
PGtkWidget(AWinControl.Handle));
//DebugLn('DeliverMouseDownMessage ',DbgSName(AWinControl),' Mapped=',dbgs(MappedXY.X),',',dbgs(MappedXY.Y),' Event=',dbgs(EventXY.X),',',dbgs(EventXY.Y));
@ -1526,7 +1534,7 @@ begin
MessI.XPos := MappedXY.X;
MessI.YPos := MappedXY.Y;
ShiftState := gtkeventstate2shiftstate(Event^.State);
ShiftState := gtkeventstateToshiftstate(Event^.State);
MessI.Keys := 0;
if ssShift in ShiftState then MessI.Keys := MessI.Keys or MK_SHIFT;
if ssCtrl in ShiftState then MessI.Keys := MessI.Keys or MK_CONTROL;
@ -1679,7 +1687,7 @@ begin
and (ofAllowMultiSelect in TOpenDialog(theDialog).Options)
and (FileSelWidget^.file_list=widget) then begin
// multi selection
ShiftState := GTKEventState2ShiftState(BEvent^.State);
ShiftState := GTKEventStateToShiftState(BEvent^.State);
if ssShift in ShiftState then begin
if LastFileSelectRow <> -1 then begin
startRow := LastFileSelectRow;
@ -2876,11 +2884,11 @@ var
end;
const
STATE_MAP: array[0..3] of Byte = (
GDK_SHIFT_MASK, // shift
GDK_CONTROL_MASK, // control
GDK_MOD1_MASK, // alt
GDK_MOD4_MASK // win
STATE_MAP: array[0..3] of TShiftStateEnum = (
ssShift,
ssCtrl,
ssAlt,
ssSuper
);
VK_MAP: array[0..3] of array[0..2] of Byte = (
// (Main key, alt key 1, alt key 2) to check
@ -2890,9 +2898,13 @@ const
(VK_LWIN, VK_RWIN, 0)
);
var
VKey: PVKeyRecord;
Pressed: Boolean;
KeyCode: Word;
KCInfo: TKeyCodeInfo;
VKey: Byte;
Pressed, InState: Boolean;
n: Integer;
ShiftState: TShiftState;
begin
Result := 0;
@ -2905,54 +2917,80 @@ begin
// not interested
Exit;
end;
VKey := MKeySymToVKMap.GetDataPtr(Event^.keyval);
if VKey = nil
{$ifdef gtk1}
KeyCode := XKeysymToKeycode(gdk_display, Event^.keyval);
{$else}
KeyCode := Event^.hardware_keycode;
{$endif}
//DebugLn('GTKKeySnooper: KeyCode=%u -> %s', [KeyCode, {$IFDEF GTK2} Event^._String {$ELSE} Event^.theString {$ENDIF}]);
if KeyCode > High(MKeyCodeInfo)
then begin
if Pressed
then DebugLn(Format('[WARNING] Key pressed without VKey: K=0x%x S="%s"', [
then DebugLn('[WARNING] Key pressed with keycode (%u) larger than expected: K=0x%x S="%s"', [
KeyCode,
Event^.KeyVal,
{$IFDEF GTK2} Event^._String {$ELSE} Event^.theString {$ENDIF}
]));
]);
Exit;
end;
KCInfo := MKeyCodeInfo[KeyCode];
if KCInfo.VKey1 = 0
then begin
if Pressed
then DebugLn('[WARNING] Key pressed without VKey: K=0x%x S="%s"', [
Event^.KeyVal,
{$IFDEF GTK2} Event^._String {$ELSE} Event^.theString {$ENDIF}
]);
Exit;
end;
if FuncData=nil then exit;
if FuncData = nil then exit;
KeyStateList := TObject(FuncData) as TFPList;
ShiftState := GTKEventStateToShiftState(Event^.State);
if (KCInfo.Flags and KCINFO_FLAG_SHIFT_XOR_NUM <> 0)
and ((ssShift in ShiftState) xor (ssNum in ShiftState))
then VKey := KCInfo.VKey2
else VKey := KCInfo.VKey1;
UpdateList(Vkey^.VKey, Pressed);
if IsToggleKey(Vkey^.VKey)
then UpdateToggleList(Vkey^.VKey);
UpdateList(VKey, Pressed);
if (KCInfo.Flags and KCINFO_FLAG_TOGGLE <> 0)
then UpdateToggleList(VKey);
// Add special left and right codes
case Event^.KeyVal of
GDK_Key_Shift_L: UpdateList(VK_LSHIFT, Pressed);
GDK_Key_Shift_R: UpdateList(VK_RSHIFT, Pressed);
GDK_Key_Control_L: UpdateList(VK_LCONTROL, Pressed);
GDK_Key_Control_R: UpdateList(VK_RCONTROL, Pressed);
GDK_Key_Alt_L: UpdateList(VK_LMENU, Pressed);
GDK_Key_Alt_R: UpdateList(VK_RMENU, Pressed);
GDK_Key_Shift_L: UpdateList(VK_LSHIFT, Pressed);
GDK_Key_Shift_R: UpdateList(VK_RSHIFT, Pressed);
GDK_Key_Control_L: UpdateList(VK_LCONTROL, Pressed);
GDK_Key_Control_R: UpdateList(VK_RCONTROL, Pressed);
GDK_Key_Alt_L: UpdateList(VK_LMENU, Pressed);
GDK_Key_Alt_R: UpdateList(VK_RMENU, Pressed);
end;
// Recheck the list against the modifiers
for n := 0 to High(STATE_MAP) do
begin
// Skip our current key, since the state is updated after the event
if VKey^.Vkey = VK_MAP[n][0] then Continue;
if VKey^.Vkey = VK_MAP[n][1] then Continue;
if VKey^.Vkey = VK_MAP[n][2] then Continue;
if VKey = VK_MAP[n][0] then Continue;
if VKey = VK_MAP[n][1] then Continue;
if VKey = VK_MAP[n][2] then Continue;
UpdateList(VK_MAP[n][0], (STATE_MAP[n] and Event^.State) <> 0);
UpdateList(VK_MAP[n][1], (STATE_MAP[n] and Event^.State) <> 0);
UpdateList(VK_MAP[n][2], (STATE_MAP[n] and Event^.State) <> 0);
InState := STATE_MAP[n] in ShiftState;
UpdateList(VK_MAP[n][0], InState);
UpdateList(VK_MAP[n][1], InState);
UpdateList(VK_MAP[n][2], InState);
end;
// if the VKey has multiple VK_codes then SHIFT distinguishes between them
// In that case SHIFT is not pressed
// On the next event the shift flag will be restored based on modifiers
if Pressed and ((VKey^.Flags and VKEY_FLAG_MULTI_VK) <> 0)
if Pressed and ((KCInfo.Flags and KCINFO_FLAG_SHIFT_XOR_NUM) <> 0)
then begin
UpdateList(VK_SHIFT, False);
UpdateList(VK_SHIFT, False);
UpdateList(VK_LSHIFT, False);
UpdateList(VK_RSHIFT, False);
end;

View File

@ -3614,13 +3614,13 @@ procedure TGtkWidgetSet.SetCallback(const AMsg: LongInt;
begin
//debugln('ConnectKeyPressReleaseEvents A ALCLObject=',DbgSName(ALCLObject));
ConnectSenderSignal(AnObject,
'key-press-event', @GTKKeyUpDown, GDK_KEY_PRESS_MASK);
'key-press-event', @GTKKeyPress, GDK_KEY_PRESS_MASK);
ConnectSenderSignalAfter(AnObject,
'key-press-event', @GTKKeyUpDownAfter, GDK_KEY_PRESS_MASK);
'key-press-event', @GTKKeyPressAfter, GDK_KEY_PRESS_MASK);
ConnectSenderSignal(AnObject,
'key-release-event', @GTKKeyUpDown, GDK_KEY_RELEASE_MASK);
'key-release-event', @GTKKeyRelease, GDK_KEY_RELEASE_MASK);
ConnectSenderSignalAfter(AnObject,
'key-release-event', @GTKKeyUpDownAfter, GDK_KEY_RELEASE_MASK);
'key-release-event', @GTKKeyReleaseAfter, GDK_KEY_RELEASE_MASK);
end;
function GetAdjustment(const gObject: PGTKObject; vertical: boolean):PGtkObject;

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,9 @@ interface
{off $DEFINE VerboseAccelerator}
{off $define VerboseModifiermap}
{$IFDEF Unix}
{$DEFINE HasX}
{$IFDEF Gtk1}
@ -178,10 +181,16 @@ function gtkfrmactivateAfter( widget: PGtkWidget; Event: PgdkEventFocus;
function gtkfrmdeactivateAfter( widget: PGtkWidget; Event: PgdkEventFocus;
data: gPointer): GBoolean; cdecl;
function GTKMap(Widget: PGTKWidget; Data: gPointer): GBoolean; cdecl;
function GTKKeyUpDown(Widget: PGtkWidget; Event: pgdkeventkey;
function GTKKeyPress(Widget: PGtkWidget; Event: pgdkeventkey;
Data: gPointer): GBoolean; cdecl;
function GTKKeyUpDownAfter(Widget: PGtkWidget; Event: pgdkeventkey;
function GTKKeyPressAfter(Widget: PGtkWidget; Event: pgdkeventkey;
Data: gPointer): GBoolean; cdecl;
function GTKKeyRelease(Widget: PGtkWidget; Event: pgdkeventkey;
Data: gPointer): GBoolean; cdecl;
function GTKKeyReleaseAfter(Widget: PGtkWidget; Event: pgdkeventkey;
Data: gPointer): GBoolean; cdecl;
function GTKFocusCB(widget: PGtkWidget; event:PGdkEventFocus;
data: gPointer): GBoolean; cdecl;
function GTKFocusCBAfter(widget: PGtkWidget; event:PGdkEventFocus;
@ -502,18 +511,15 @@ function GetRGBAsKey(p: pointer): pointer;
type
TVKeyUTF8Char = array[0..7] of Char;
TVKeyInfo = record
KeyCode: Byte;
KeyCode: array[Boolean] of Byte; // false is primary keycode, true the keycode of the other key when 2 keys exist (like CTRL or extended key)
KeySym: array[0..7] of Integer;
KeyChar: array[0..3] of TVKeyUTF8Char;
end;
procedure InitKeyboardTables;
procedure DoneKeyboardTables;
function CharToVKandFlags(const AUTF8Char: TVKeyUTF8Char): Word;
function GetVKeyInfo(const AVKey: Byte): TVKeyInfo;
function IsToggleKey(const AVKey: Byte): Boolean;
function GTKEventState2ShiftState(KeyState: Word): TShiftState;
//function KeyToListCode_(KeyCode, VirtKeyCode: Word; Extended: boolean): integer;
function GTKEventStateToShiftState(KeyState: Word): TShiftState;
procedure gdk_event_key_get_string(Event: PGDKEventKey; var theString: Pointer);
procedure gdk_event_key_set_string(Event: PGDKEventKey; const NewString: PChar);
function gdk_event_get_type(Event: Pointer): TGdkEventType;
@ -521,8 +527,8 @@ procedure RememberKeyEventWasHandledByLCL(Event: PGdkEventKey;
BeforeEvent: boolean);
function KeyEventWasHandledByLCL(Event: PGdkEventKey;
BeforeEvent: boolean): boolean;
function HandleGTKKeyUpDown(Widget: PGtkWidget; Event: PGdkEventKey;
Data: gPointer; BeforeEvent: boolean) : GBoolean;
function HandleGTKKeyUpDown(AWidget: PGtkWidget; AEvent: PGdkEventKey;
AData: gPointer; ABeforeEvent, AHandleDown: Boolean) : GBoolean;
// ----
@ -941,28 +947,43 @@ uses
dynlibs;
const
VKEY_FLAG_SHIFT = $01;
VKEY_FLAG_CTRL = $02;
VKEY_FLAG_ALT = $04;
VKEY_FLAG_KEY_MASK = $07;
VKEY_FLAG_EXT = $10; // extended key
VKEY_FLAG_MULTI_VK = $20; // key has more than one VK
KCINFO_FLAG_SHIFT = $01;
KCINFO_FLAG_CTRL = $02;
KCINFO_FLAG_ALTGR = $04;
KCINFO_FLAG_KEY_MASK = $07;
KCINFO_FLAG_EXT = $10; // extended key
KCINFO_FLAG_TOGGLE = $20; // toggle key
KCINFO_FLAG_SHIFT_XOR_NUM = $40; // second vkey should be used when numlock <>shift
KCINFO_FLAG_MULTI_MASK = $C0; // key has more than one VK
type
PVKeyRecord = ^TVKeyRecord;
TVKeyRecord = record
VKey: Byte;
PKeyCodeInfo = ^TKeyCodeInfo;
TKeyCodeInfo = record
VKey1: Byte;
VKey2: Byte; // second code to be used depending on the type of MULTI_VK flag
Flags: Byte; // indicates if Alt | Ctrl | Shift is needed
// extended state
end;
var
MKeyCodeToVK: array[Byte] of Byte;
MKeyCodeInfo: array[Byte] of TKeyCodeInfo;
MVKeyInfo: array[Byte] of TVKeyInfo;
MKeySymToVKMap: TMap; // keysym ->TVKeyRecord
MSymCharToVKMap: TMap; //char->TVKeyRecord
// Modifier keys can be set by a modmap and don't have to be the same on all systems
// Some defaults are set here incase we didn't find them
type
TModifier = record
Mask: Cardinal; // if UseValue is set, the modifier is set when the masked state matches the value
Value: Cardinal; // otherwise any nonzero value will match
UseValue: Boolean;
end;
var
MModifiers: array[TShiftStateEnum] of TModifier;
type
// TLCLHandledKeyEvent is used to remember, if an gdk key event was already
// handled.
@ -1041,12 +1062,27 @@ procedure InitGTKProc;
var
lgs: TLazGtkStyle;
begin
MKeySymToVKMap := TMap.Create(itu4, SizeOf(TVKeyRecord));
//MKeySymToVKMap := TMap.Create(itu4, SizeOf(TVKeyRecord));
// UTF8 is max 4 bytes, acombined makes it 8
MSymCharToVKMap := TMap.Create(itu8, SizeOf(TVKeyRecord));
//MSymCharToVKMap := TMap.Create(itu8, SizeOf(TVKeyRecord));
// fill initial modifier list
FillByte(MModifiers, SizeOf(MModifiers), 0);
// keyboard
MModifiers[ssShift].Mask := GDK_SHIFT_MASK;
MModifiers[ssCaps].Mask := GDK_LOCK_MASK;
MModifiers[ssCtrl].Mask := GDK_CONTROL_MASK;
MModifiers[ssAlt].Mask := GDK_MOD1_MASK;
MModifiers[ssNum].Mask := GDK_MOD3_MASK; //todo: check this I've 2 here,but 3 was the original code
MModifiers[ssSuper].Mask := GDK_MOD4_MASK;
MModifiers[ssScroll].Mask := GDK_MOD5_MASK; //todo: check this I've ssAltGr here, but ssScroll was the original code
MModifiers[ssAltGr].Mask := GDK_RELEASE_MASK;
// mouse
MModifiers[ssLeft].Mask := GDK_BUTTON1_MASK;
MModifiers[ssMiddle].Mask := GDK_BUTTON2_MASK;
MModifiers[ssRight].Mask := GDK_BUTTON3_MASK;
FillChar(MKeyCodeToVK, SizeOf(MKeyCodeToVK), $FF);
FillChar(MKeyCodeInfo, SizeOf(MKeyCodeInfo), $FF);
FillChar(MVKeyInfo, SizeOf(MVKeyInfo), 0);
@ -1062,8 +1098,8 @@ end;
procedure DoneGTKProc;
begin
DoneKeyboardTables;
FreeAndNil(MKeySymToVKMap);
FreeAndNil(MSymCharToVKMap);
// FreeAndNil(MKeySymToVKMap);
// FreeAndNil(MSymCharToVKMap);
end;
{$IFDEF GTK1}

View File

@ -9665,21 +9665,6 @@ begin
end;
end;
{$EndIf}
{------------------------------------------------------------------------------
Function: VkKeyScan
Params: AChar: Character to translate
Returns: LoByte: VK-code
HiByte: ALT | CTRL | SHIFT pressed -> bit2 | bit1 | bit0
------------------------------------------------------------------------------}
function TGtkWidgetSet.VkKeyScan(AChar: Char): Short;
var
UTF8Char: TVKeyUTF8Char;
begin
FillByte(UTF8Char, SizeOf(UTF8Char), 0);
UTF8Char[0] := AChar;
Result := CharToVkAndFlags(UTF8Char);
end;
{------------------------------------------------------------------------------
Function: WindowFromPoint

View File

@ -207,8 +207,6 @@ function StretchMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; X
Function TextOut(DC: HDC; X,Y : Integer; Str : Pchar; Count: Integer) : Boolean; override;
function VkKeyScan(AChar: Char): Short; override;
Function WindowFromPoint(Point : TPoint) : HWND; override;
//##apiwiz##eps## // Do not remove, no wizard declaration after this line

View File

@ -740,7 +740,7 @@ begin
Msg.msg := LM_HSCROLL;
// get scrollcode
if ssLeft in GTKEventState2ShiftState(Word(Mask))
if ssLeft in GTKEventStateToShiftState(Word(Mask))
then Msg.ScrollCode := SB_THUMBTRACK
else if V <= L
then Msg.ScrollCode := SB_TOP
@ -802,7 +802,7 @@ begin
Msg.msg := LM_VSCROLL;
// Get scrollcode
if ssLeft in GTKEventState2ShiftState(Word(Mask))
if ssLeft in GTKEventStateToShiftState(Word(Mask))
then Msg.ScrollCode := SB_THUMBTRACK
else if V <= L
then Msg.ScrollCode := SB_TOP

View File

@ -65,28 +65,28 @@ function GTK2KeyDown(Widget: PGtkWidget; Event : pgdkeventkey;
Data: gPointer) : GBoolean; cdecl;
begin
//debugln('GTK2KeyDown ',DbgSName(TObject(Data)));
Result := HandleGtkKeyUpDown(Widget, Event, Data, True);
Result := HandleGtkKeyUpDown(Widget, Event, Data, True, True);
end;
function GTK2KeyDownAfter(Widget: PGtkWidget; Event : pgdkeventkey;
Data: gPointer) : GBoolean; cdecl;
begin
//debugln('GTK2KeyDownAfter ',DbgSName(TObject(Data)));
Result := HandleGtkKeyUpDown(Widget, Event, Data, False);
Result := HandleGtkKeyUpDown(Widget, Event, Data, False, True);
end;
function GTK2KeyUp(Widget: PGtkWidget; Event : pgdkeventkey;
Data: gPointer) : GBoolean; cdecl;
begin
//debugln('GTK2KeyUp ',DbgSName(TObject(Data)));
Result := HandleGtkKeyUpDown(Widget, Event, Data, True);
Result := HandleGtkKeyUpDown(Widget, Event, Data, True, False);
end;
function GTK2KeyUpAfter(Widget: PGtkWidget; Event : pgdkeventkey;
Data: gPointer) : GBoolean; cdecl;
begin
//debugln('GTK2KeyUpAfter ',DbgSName(TObject(Data)));
Result := HandleGtkKeyUpDown(Widget, Event, Data, False);
Result := HandleGtkKeyUpDown(Widget, Event, Data, False, False);
end;
function GTK2KillFocusCB(widget: PGtkWidget; event:PGdkEventFocus;

View File

@ -27,7 +27,7 @@ unit Gtk2WSComCtrls;
interface
uses
// libs
// libs
GLib2, Gtk2, Gdk2, Gdk2pixbuf,
// LCL
ComCtrls, Classes, FPCAdds, LCLType, LMessages, Controls, Graphics, CommCtrl,

View File

@ -2483,12 +2483,6 @@ Begin
// Result := 0;
End;
{function TWinCEWidgetSet.VkKeyScan(AChar: Char): Short;
begin
Result:=inherited VkKeyScan(AChar);
end;
}
{------------------------------------------------------------------------------
Method: CallDefaultWndHandler

View File

@ -228,7 +228,6 @@ function StretchMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; X
Function TextOut(DC: HDC; X,Y : Integer; Str : Pchar; Count: Integer) : Boolean; override;
function UpdateWindow(Handle: HWND): Boolean;override;
{function VkKeyScan(AChar: Char): Short; override;}
Function WindowFromPoint(Point : TPoint) : HWND; override;