Fixes bug #20065. Removes ssCaps, ssNum and ssScroll because they are implemented based on the key lock in win32, which is not the same as shift state, they are added only for MouseWhell events and very unreliable across platforms (cannot be correctly implemented in win32 for example). Also corrects the ShiftState for MouseWhell messages in Windows. Removes State from the mousewhell internal message, now Button is used, which is more consistent with Win32.

git-svn-id: trunk@33092 -
This commit is contained in:
sekelsenmat 2011-10-26 15:08:10 +00:00
parent 6e659b3e4a
commit 73f0887e09
21 changed files with 25 additions and 131 deletions

View File

@ -143,8 +143,8 @@ const
('ssShift', 'ssAlt', 'ssCtrl',
'ssLeft', 'ssRight', 'ssMiddle', 'ssDouble',
// Extra additions
'ssMeta', 'ssSuper', 'ssHyper', 'ssAltGr', 'ssCaps', 'ssNum',
'ssScroll', 'ssTriple', 'ssQuad', 'ssExtra1', 'ssExtra2');
'ssMeta', 'ssSuper', 'ssHyper', 'ssAltGr',
'ssTriple', 'ssQuad', 'ssExtra1', 'ssExtra2');
var
OriginalBackTraceStrFunc: TBackTraceStrFunc;

View File

@ -704,9 +704,6 @@ const
EV: array [Boolean] of TChartToolEventId = (
evidMouseWheelDown, evidMouseWheelUp);
begin
// These modifiers are added by mousewheel event, but not by mouse button
// and key events. Ignore them to avoid user confusion.
AShift -= [ssNum, ssCaps, ssScroll];
Result :=
GetToolset.Dispatch(Self, EV[AWheelDelta > 0], AShift, AMousePos) or
inherited DoMouseWheel(AShift, AWheelDelta, AMousePos);

View File

@ -6562,9 +6562,6 @@ begin
Result:='Hyper';
{$ENDIF}
ssAltGr: Result:='AltGr';
ssCaps: Result:='Caps';
ssNum: Result:='Numlock';
ssScroll: Result:='Scroll';
else Result:='Modifier'+IntToStr(ord(s));
end;
end;
@ -6577,8 +6574,7 @@ begin
inherited Create(TheOwner);
FAllowedShifts:=[ssShift, ssAlt, ssCtrl,
ssMeta, ssSuper, ssHyper, ssAltGr,
ssCaps, ssNum, ssScroll];
ssMeta, ssSuper, ssHyper, ssAltGr];
FGrabButton:=TButton.Create(Self);
with FGrabButton do begin

View File

@ -2309,7 +2309,7 @@ begin
MousePos.X := Message.X;
MousePos.Y := Message.Y;
if DoMouseWheel(Message.State, Message.WheelDelta, MousePos) then
if DoMouseWheel(KeysToShiftState(Message.Button), Message.WheelDelta, MousePos) then
Message.Result := 1 // handled, skip further handling by interface
else
inherited;

View File

@ -244,10 +244,9 @@ const
MousePoint := GetMousePoint;
Msg^.Msg := LM_MOUSEWHEEL;
Msg^.Button := GetCarbonMouseButton(AEvent);
Msg^.Button := GetCarbonMouseButton(AEvent) or ShiftStateToKeys(GetCarbonShiftState);
Msg^.X := MousePoint.X;
Msg^.Y := MousePoint.Y;
Msg^.State := GetCarbonShiftState;
Msg^.WheelDelta := GetMouseWheelDelta;
end;

View File

@ -465,7 +465,6 @@ begin
if (cmdKey and Modifiers) > 0 then Include(Result, ssMeta);
if (controlKey and Modifiers) > 0 then Include(Result, ssCtrl);
if (optionKey and Modifiers) > 0 then Include(Result, ssAlt);
if (alphaLock and Modifiers) > 0 then Include(Result, ssCaps);
//DebugLn('GetCarbonShiftState Result=',dbgs(Result),' Modifiers=',hexstr(Modifiers,8),' ButtonState=',hexstr(ButtonState,8));
end;

View File

@ -445,7 +445,6 @@ begin
if (cmdKey and Modifiers) > 0 then Include(Result, ssMeta);
if (controlKey and Modifiers) > 0 then Include(Result, ssCtrl);
if (optionKey and Modifiers) > 0 then Include(Result, ssAlt);
if (alphaLock and Modifiers) > 0 then Include(Result, ssCaps);
//DebugLn('GetCarbonShiftState Result=',dbgs(Result),' Modifiers=',hexstr(Modifiers,8),' ButtonState=',hexstr(ButtonState,8));
end;

View File

@ -2684,7 +2684,7 @@ begin
ShiftState := GTKEventStateToShiftState(Event^.State);
if (KCInfo.Flags and KCINFO_FLAG_SHIFT_XOR_NUM <> 0)
and ((ssShift in ShiftState) xor (ssNum in ShiftState))
and (ssShift in ShiftState)
then VKey := KCInfo.VKey2
else VKey := KCInfo.VKey1;

View File

@ -2354,7 +2354,7 @@ begin
KCInfo := MKeyCodeInfo[KeyCode];
if (KCInfo.Flags and KCINFO_FLAG_SHIFT_XOR_NUM <> 0)
and ((ssShift in ShiftState) xor (ssNum in ShiftState))
and (ssShift in ShiftState)
then VKey := KCInfo.VKey2
else VKey := KCInfo.VKey1;
@ -3158,8 +3158,8 @@ type
const
STATE_NAME: array[TShiftStateEnum] of String = ('ssShift', 'ssAlt', 'ssCtrl',
'ssLeft', 'ssRight', 'ssMiddle', 'ssDouble',
'ssMeta', 'ssSuper', 'ssHyper', 'ssAltGr', 'ssCaps', 'ssNum',
'ssScroll', 'ssTriple', 'ssQuad', 'ssExtra1', 'ssExtra2');
'ssMeta', 'ssSuper', 'ssHyper', 'ssAltGr',
'ssTriple', 'ssQuad', 'ssExtra1', 'ssExtra2');
{$endif}
var
ShiftState: TShiftStateEnum;
@ -3167,10 +3167,6 @@ type
if AModMap[AKeyCode] = 0 then Exit;
case AKeySym of
GDK_KEY_Caps_Lock,
GDK_KEY_Shift_Lock: ShiftState := ssCaps;
GDK_KEY_Num_Lock: ShiftState := ssNum;
GDK_KEY_Scroll_Lock: ShiftState := ssScroll;
GDK_Key_Shift_L,
GDK_Key_Shift_R: ShiftState := ssShift;
GDK_KEY_Control_L,

View File

@ -947,9 +947,6 @@ begin
// fill initial modifier list
FillByte(MModifiers, SizeOf(MModifiers), 0);
// keyboard
MModifiers[ssCaps].Mask := GDK_LOCK_MASK;
MModifiers[ssNum].Mask := GDK_MOD3_MASK; //todo: check this I've 2 here,but 3 was the original code
MModifiers[ssScroll].Mask := GDK_MOD5_MASK; //todo: check this I've ssAltGr here, but ssScroll was the original code
{$ifndef UseOwnShiftState}
MModifiers[ssShift].Mask := GDK_SHIFT_MASK;
MModifiers[ssCtrl].Mask := GDK_CONTROL_MASK;

View File

@ -1794,9 +1794,8 @@ begin
MessE.WheelDelta := WHEEL_DELTA[event^.Button = 4];
MessE.X := MappedXY.X;
MessE.Y := MappedXY.Y;
MessE.State := ShiftState;
MessE.UserData := AWinControl;
MessE.Button := 0;
MessE.Button := ShiftStateToKeys(ShiftState);
// send the message directly to the LCL
NotifyApplicationUserInput(MessE.Msg);
@ -2071,9 +2070,8 @@ begin
end;
MessE.X := MappedXY.X;
MessE.Y := MappedXY.Y;
MessE.State := ShiftState;
MessE.UserData := AWinControl;
MessE.Button := 0;
MessE.Button := ShiftStateToKeys(ShiftState);
// send the message directly to the LCL
NotifyApplicationUserInput(MessE.Msg);
@ -2900,7 +2898,7 @@ begin
ShiftState := GTKEventStateToShiftState(Event^.State);
if (KCInfo.Flags and KCINFO_FLAG_SHIFT_XOR_NUM <> 0)
and ((ssShift in ShiftState) xor (ssNum in ShiftState))
and (ssShift in ShiftState)
then VKey := KCInfo.VKey2
else VKey := KCInfo.VKey1;

View File

@ -2323,7 +2323,7 @@ begin
KCInfo := MKeyCodeInfo[KeyCode];
if (KCInfo.Flags and KCINFO_FLAG_SHIFT_XOR_NUM <> 0)
and ((ssShift in ShiftState) xor (ssNum in ShiftState))
and (ssShift in ShiftState)
then VKey := KCInfo.VKey2
else VKey := KCInfo.VKey1;
@ -3124,8 +3124,8 @@ type
const
STATE_NAME: array[TShiftStateEnum] of String = ('ssShift', 'ssAlt', 'ssCtrl',
'ssLeft', 'ssRight', 'ssMiddle', 'ssDouble',
'ssMeta', 'ssSuper', 'ssHyper', 'ssAltGr', 'ssCaps', 'ssNum',
'ssScroll', 'ssTriple', 'ssQuad', 'ssExtra1', 'ssExtra2');
'ssMeta', 'ssSuper', 'ssHyper', 'ssAltGr',
'ssTriple', 'ssQuad', 'ssExtra1', 'ssExtra2');
{$endif}
var
ShiftState: TShiftStateEnum;
@ -3133,10 +3133,6 @@ type
if AModMap[AKeyCode] = 0 then Exit;
case AKeySym of
GDK_KEY_Caps_Lock,
GDK_KEY_Shift_Lock: ShiftState := ssCaps;
GDK_KEY_Num_Lock: ShiftState := ssNum;
GDK_KEY_Scroll_Lock: ShiftState := ssScroll;
GDK_Key_Shift_L,
GDK_Key_Shift_R: ShiftState := ssShift;
GDK_KEY_Control_L,

View File

@ -940,9 +940,6 @@ begin
// fill initial modifier list
FillByte(MModifiers, SizeOf(MModifiers), 0);
// keyboard
MModifiers[ssCaps].Mask := GDK_LOCK_MASK;
MModifiers[ssNum].Mask := GDK_MOD3_MASK; //todo: check this I've 2 here,but 3 was the original code
MModifiers[ssScroll].Mask := GDK_MOD5_MASK; //todo: check this I've ssAltGr here, but ssScroll was the original code
{$ifndef UseOwnShiftState}
MModifiers[ssShift].Mask := GDK_SHIFT_MASK;
MModifiers[ssCtrl].Mask := GDK_CONTROL_MASK;

View File

@ -3079,6 +3079,7 @@ var
MousePos: TQtPoint;
Modifiers: QtKeyboardModifiers;
ModifierState: PtrInt;
ShiftState: TShiftState;
begin
Result := False;
if not CanSendLCLMessage or (LCLObject = nil) then
@ -3090,14 +3091,15 @@ begin
OffsetMousePos(@MousePos);
Modifiers := QInputEvent_modifiers(QInputEventH(Event));
Msg.State := [];
ShiftState := [];
ModifierState := QtKeyModifiersToKeyState(Modifiers);
if (ModifierState and MK_SHIFT) <> 0 then
Msg.State := [ssShift];
ShiftState := [ssShift];
if (ModifierState and MK_CONTROL) <> 0 then
Msg.State := [ssCtrl] + Msg.State;
ShiftState := [ssCtrl] + ShiftState;
if (ModifierState and $20000000) <> 0 then
Msg.State := [ssAlt] + Msg.State;
ShiftState := [ssAlt] + ShiftState;
Msg.Button := ShiftStateToKeys(ShiftState);
LastMouse.Widget := Sender;
LastMouse.MousePos := MousePos;

View File

@ -1827,7 +1827,6 @@ begin
Y := P.Y;
Button := LOWORD(Integer(WParam));
WheelDelta := SmallInt(HIWORD(Integer(WParam)));
State := GetShiftState;
Result := 0;
UserData := Pointer(GetWindowLong(Window, GWL_USERDATA));
WinProcess := false;

View File

@ -76,7 +76,6 @@ Type
function WM_To_String(WM_Message: Integer): string;
function WindowPosFlagsToString(Flags: UINT): string;
function GetShiftState: TShiftState;
function ObjectToHWND(const AObject: TObject): HWND;
function LCLControlSizeNeedsUpdate(Sender: TWinControl; SendSizeMsgOnDiff: boolean): boolean;
function GetLCLClientBoundsOffset(Sender: TObject; out ORect: TRect): boolean;
@ -521,43 +520,6 @@ begin
Result := FlagsStr;
end;
{------------------------------------------------------------------------------
function: GetShiftState
Params: None
Returns: A shift state
Creates a TShiftState set based on the status when the function was called.
------------------------------------------------------------------------------}
function GetShiftState: TShiftState;
begin
Result := [];
// NOTE: it may be better to use GetAsyncKeyState
// if GetKeyState AND $8000 <> 0 then down (e.g. shift)
// if GetKeyState AND 1 <> 0, then toggled on (e.g. num lock)
if (GetKeyState(VK_SHIFT) and $8000) <> 0 then
Result := Result + [ssShift];
if (GetKeyState(VK_CAPITAL) and 1) <> 0 then
Result := Result + [ssCaps];
if (GetKeyState(VK_CONTROL) and $8000) <> 0 then
Result := Result + [ssCtrl];
if (GetKeyState(VK_MENU) and $8000) <> 0 then
Result := Result + [ssAlt];
if (GetKeyState(VK_NUMLOCK) and 1) <> 0 then
Result := Result + [ssNum];
//TODO: ssSuper
if (GetKeyState(VK_SCROLL) and 1) <> 0 then
Result := Result + [ssScroll];
// GetKeyState takes mouse button swap into account (GetAsyncKeyState doesn't),
// so no need to test GetSystemMetrics(SM_SWAPBUTTON)
if (GetKeyState(VK_LBUTTON) and $8000) <> 0 then
Result := Result + [ssLeft];
if (GetKeyState(VK_MBUTTON) and $8000) <> 0 then
Result := Result + [ssMiddle];
if (GetKeyState(VK_RBUTTON) and $8000) <> 0 then
Result := Result + [ssRight];
//TODO: ssAltGr
end;
{------------------------------------------------------------------------------
procedure: GetWin32KeyInfo
Params: Event - Requested info

View File

@ -1699,7 +1699,6 @@ begin
Msg := LM_MOUSEWHEEL;
Button := Lo(WParam);
WheelDelta := SmallInt(Hi(WParam));
State := GetShiftState;
UserData := Pointer(GetWindowLong(Window, GWL_USERDATA));
WinProcess := false;
end;

View File

@ -57,7 +57,6 @@ procedure AssertEx(const Message: String; const PassErr: Boolean;
const Severity: Byte);
procedure AssertEx(const PassErr: Boolean; const Message: String);
procedure AssertEx(const Message: String);
function GetShiftState: TShiftState;
function ObjectToHWND(Const AObject: TObject): HWND;
function BytesPerLine(nWidth, nBitsPerPixel: Integer): PtrUInt;
@ -432,45 +431,6 @@ Begin
AssertEx(Message, False, 0);
End;
{------------------------------------------------------------------------------
Function: GetShiftState
Params: None
Returns: A shift state
Creates a TShiftState set based on the status when the function was called.
------------------------------------------------------------------------------}
function GetShiftState: TShiftState;
Begin
//roozbeh todo:remove the unecessary ones
Result := [];
If Hi(GetKeyState(VK_SHIFT)) = 1 Then
Result := Result + [ssShift];
If Hi(GetKeyState(VK_CAPITAL)) = 1 Then
Result := Result + [ssCaps];
If Hi(GetKeyState(VK_CONTROL)) = 1 Then
Result := Result + [ssCtrl];
If Hi(GetKeyState(VK_MENU)) = 1 Then
Result := Result + [ssAlt];
If Hi(GetKeyState(VK_SHIFT)) = 1 Then
Result := Result + [ssShift];
If Hi(GetKeyState(VK_CAPITAL)) = 1 Then
Result := Result + [ssCaps];
If Hi(GetKeyState(VK_CONTROL)) = 1 Then
Result := Result + [ssCtrl];
If Hi(GetKeyState(VK_NUMLOCK)) = 1 Then
Result := Result + [ssNum];
//TODO: ssSuper
If Hi(GetKeyState(VK_SCROLL)) = 1 Then
Result := Result + [ssScroll];
If ((Hi(GetKeyState(VK_LBUTTON)) = 1) And (GetSystemMetrics(SM_SWAPBUTTON) = 0)) Or ((Hi(GetKeyState(VK_RBUTTON)) = 1) And (GetSystemMetrics(SM_SWAPBUTTON) <> 0)) Then
Result := Result + [ssLeft];
If Hi(GetKeyState(VK_MBUTTON)) = 1 Then
Result := Result + [ssMiddle];
If ((Hi(GetKeyState(VK_RBUTTON)) = 1) And (GetSystemMetrics(SM_SWAPBUTTON) = 0)) Or ((Hi(GetKeyState(VK_LBUTTON)) = 1) And (GetSystemMetrics(SM_SWAPBUTTON) <> 0)) Then
Result := Result + [ssRight];
//TODO: ssAltGr
End;
{------------------------------------------------------------------------------
Procedure: GetWin32KeyInfo
Params: Event - Requested info

View File

@ -430,6 +430,7 @@ begin
Mess.X := XPos;
Mess.Y := YPos;
Mess.WheelDelta := WheelDelta;
Mess.Button := ShiftStateToKeys(ShiftState);
Result := DeliverMessage(Target, Mess);
end;

View File

@ -2108,9 +2108,6 @@ begin
if ssSuper in Shift then Add('ssSuper');
if ssHyper in Shift then Add('ssHyper');
if ssAltGr in Shift then Add('ssAltGr');
if ssCaps in Shift then Add('ssCaps');
if ssNum in Shift then Add('ssNum');
if ssScroll in Shift then Add('ssScroll');
if ssTriple in Shift then Add('ssTriple');
if ssQuad in Shift then Add('ssQuad');
Result:='['+Result+']';

View File

@ -698,6 +698,7 @@ type
Result: LRESULT;
end;
// This is the event for the mouse whell
PLMMouseEvent = ^TLMMouseEvent;
TLMMouseEvent = record
Msg: Cardinal;
@ -705,11 +706,11 @@ type
UnusedMsg: Cardinal;
{$endif}
{$IFDEF FPC_LITTLE_ENDIAN}
Button: Word; // 1=left, 2=right, 3=middle
Button: Word; // 1=left, 2=right, 3=middle, it should also contain the ShiftState via the or operator, see for example MK_CONTROL
WheelDelta: SmallInt; // -1 for up, 1 for down
{$ELSE}
WheelDelta: SmallInt; // -1 for up, 1 for down
Button: Word; // 1=left, 2=right, 3=middle
Button: Word; // 1=left, 2=right, 3=middle, it should also contain the ShiftState via the or operator, see for example MK_CONTROL
{$ENDIF}
{$ifdef cpu64}
Unused1 : Longint;
@ -721,7 +722,6 @@ type
{$endif cpu64}
Result: LRESULT; // to fit std message size
UserData: pointer; // used under gtk
State: TShiftState; // in win is the equivalent of button
end;
TLMLButtonDown = TLMMouse;