View Issue Details

IDProjectCategoryView StatusLast Update
0020065LazarusLCLpublic2011-10-28 19:25
ReporterFlávio Etrusco (notifications not working)Assigned ToFelipe Monteiro de Carvalho 
PrioritynormalSeverityminorReproducibilityN/A
Status resolvedResolutionfixed 
Product Version0.9.31 (SVN)Product Build 
Target VersionFixed in Version0.9.31 (SVN) 
Summary0020065: [patch] WMMouseWheel handling in Win32 has special implementation of GetKeyShiftState.
DescriptionWMMouseWheel handling in Win32 has special implementation of GetKeyShiftState.
If the additional key states are necessary somewhere they could be handled by the other widgetset-agnostic functions (in Forms and Controls units, I'll post to the ML about some issues regarding them).
I checked that the field isn't used in any other WS.
TagsNo tags attached.
Fixed in Revision33092, 33096, 33111, 33112, 33114
LazTarget0.99.0
WidgetsetWin32/Win64
Attached Files
  • win-shiftstate-cleanup.patch (3,681 bytes)
    diff --git lcl/include/control.inc lcl/include/control.inc
    index 29f099f..cc8d359 100644
    --- lcl/include/control.inc
    +++ lcl/include/control.inc
    @@ -2265,7 +2265,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;
    diff --git lcl/interfaces/win32/win32callback.inc lcl/interfaces/win32/win32callback.inc
    index 637c070..088c094 100644
    --- lcl/interfaces/win32/win32callback.inc
    +++ lcl/interfaces/win32/win32callback.inc
    @@ -1829,7 +1829,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;
    diff --git lcl/interfaces/win32/win32proc.pp lcl/interfaces/win32/win32proc.pp
    index e33249c..555cf4d 100644
    --- lcl/interfaces/win32/win32proc.pp
    +++ lcl/interfaces/win32/win32proc.pp
    @@ -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;
    @@ -522,43 +521,6 @@ begin
     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
                KeyCode    - the ASCII key code of the eventkey
    diff --git lcl/lmessages.pp lcl/lmessages.pp
    index f977748..3790090 100644
    --- lcl/lmessages.pp
    +++ lcl/lmessages.pp
    @@ -721,7 +721,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;
    
  • wmmousewheel-remove-special-case.patch (5,078 bytes)
    diff --git lcl/forms.pp lcl/forms.pp
    index a68e9d8..325c21e 100644
    --- lcl/forms.pp
    +++ lcl/forms.pp
    @@ -1616,7 +1616,7 @@ type
     
     function KeysToShiftState(Keys: PtrUInt): TShiftState;
     function KeyDataToShiftState(KeyData: PtrInt): TShiftState;
    -function ShiftStateToKeys(ShiftState: TShiftState): PtrUInt;
    +function ShiftStateToKeys(ShiftState: TShiftState): PtrInt;
     
     function WindowStateToStr(const State: TWindowState): string;
     function StrToWindowState(const Name: string): TWindowState;
    @@ -1771,7 +1771,7 @@ begin
       Result := MsgKeyDataToShiftState(KeyData);
     end;
     
    -function ShiftStateToKeys(ShiftState: TShiftState): PtrUInt;
    +function ShiftStateToKeys(ShiftState: TShiftState): PtrInt;
     begin
       Result := 0;
       if ssShift  in ShiftState then Result := Result or MK_SHIFT;
    diff --git lcl/include/control.inc lcl/include/control.inc
    index 32fa34e..8357e41 100644
    --- lcl/include/control.inc
    +++ lcl/include/control.inc
    @@ -2265,7 +2265,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;
    diff --git lcl/interfaces/gtk2/gtk2callback.inc lcl/interfaces/gtk2/gtk2callback.inc
    index 520471b..999afbc 100644
    --- lcl/interfaces/gtk2/gtk2callback.inc
    +++ lcl/interfaces/gtk2/gtk2callback.inc
    @@ -1777,7 +1777,6 @@ 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;
     
    @@ -2054,7 +2053,6 @@ begin
       end;
       MessE.X := MappedXY.X;
       MessE.Y := MappedXY.Y;
    -  MessE.State := ShiftState;
       MessE.UserData := AWinControl;
       MessE.Button := 0;
     
    diff --git lcl/interfaces/win32/win32callback.inc lcl/interfaces/win32/win32callback.inc
    index b2bbb60..80c79d9 100644
    --- lcl/interfaces/win32/win32callback.inc
    +++ lcl/interfaces/win32/win32callback.inc
    @@ -1816,7 +1816,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;
    diff --git lcl/interfaces/win32/win32proc.pp lcl/interfaces/win32/win32proc.pp
    index e33249c..555cf4d 100644
    --- lcl/interfaces/win32/win32proc.pp
    +++ lcl/interfaces/win32/win32proc.pp
    @@ -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;
    @@ -522,43 +521,6 @@ begin
     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
                KeyCode    - the ASCII key code of the eventkey
    diff --git lcl/lmessages.pp lcl/lmessages.pp
    index f977748..3790090 100644
    --- lcl/lmessages.pp
    +++ lcl/lmessages.pp
    @@ -721,7 +721,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;
    

Activities

2011-08-27 00:46

 

win-shiftstate-cleanup.patch (3,681 bytes)
diff --git lcl/include/control.inc lcl/include/control.inc
index 29f099f..cc8d359 100644
--- lcl/include/control.inc
+++ lcl/include/control.inc
@@ -2265,7 +2265,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;
diff --git lcl/interfaces/win32/win32callback.inc lcl/interfaces/win32/win32callback.inc
index 637c070..088c094 100644
--- lcl/interfaces/win32/win32callback.inc
+++ lcl/interfaces/win32/win32callback.inc
@@ -1829,7 +1829,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;
diff --git lcl/interfaces/win32/win32proc.pp lcl/interfaces/win32/win32proc.pp
index e33249c..555cf4d 100644
--- lcl/interfaces/win32/win32proc.pp
+++ lcl/interfaces/win32/win32proc.pp
@@ -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;
@@ -522,43 +521,6 @@ begin
 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
            KeyCode    - the ASCII key code of the eventkey
diff --git lcl/lmessages.pp lcl/lmessages.pp
index f977748..3790090 100644
--- lcl/lmessages.pp
+++ lcl/lmessages.pp
@@ -721,7 +721,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;
Oops. Somehow I missed it in gtk2 :-$
In lcl/interfaces/gtk2/gtk2callback.inc, mousedown and mousewheel fill 'State' too.

2011-09-13 19:19

 

wmmousewheel-remove-special-case.patch (5,078 bytes)
diff --git lcl/forms.pp lcl/forms.pp
index a68e9d8..325c21e 100644
--- lcl/forms.pp
+++ lcl/forms.pp
@@ -1616,7 +1616,7 @@ type
 
 function KeysToShiftState(Keys: PtrUInt): TShiftState;
 function KeyDataToShiftState(KeyData: PtrInt): TShiftState;
-function ShiftStateToKeys(ShiftState: TShiftState): PtrUInt;
+function ShiftStateToKeys(ShiftState: TShiftState): PtrInt;
 
 function WindowStateToStr(const State: TWindowState): string;
 function StrToWindowState(const Name: string): TWindowState;
@@ -1771,7 +1771,7 @@ begin
   Result := MsgKeyDataToShiftState(KeyData);
 end;
 
-function ShiftStateToKeys(ShiftState: TShiftState): PtrUInt;
+function ShiftStateToKeys(ShiftState: TShiftState): PtrInt;
 begin
   Result := 0;
   if ssShift  in ShiftState then Result := Result or MK_SHIFT;
diff --git lcl/include/control.inc lcl/include/control.inc
index 32fa34e..8357e41 100644
--- lcl/include/control.inc
+++ lcl/include/control.inc
@@ -2265,7 +2265,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;
diff --git lcl/interfaces/gtk2/gtk2callback.inc lcl/interfaces/gtk2/gtk2callback.inc
index 520471b..999afbc 100644
--- lcl/interfaces/gtk2/gtk2callback.inc
+++ lcl/interfaces/gtk2/gtk2callback.inc
@@ -1777,7 +1777,6 @@ 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;
 
@@ -2054,7 +2053,6 @@ begin
   end;
   MessE.X := MappedXY.X;
   MessE.Y := MappedXY.Y;
-  MessE.State := ShiftState;
   MessE.UserData := AWinControl;
   MessE.Button := 0;
 
diff --git lcl/interfaces/win32/win32callback.inc lcl/interfaces/win32/win32callback.inc
index b2bbb60..80c79d9 100644
--- lcl/interfaces/win32/win32callback.inc
+++ lcl/interfaces/win32/win32callback.inc
@@ -1816,7 +1816,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;
diff --git lcl/interfaces/win32/win32proc.pp lcl/interfaces/win32/win32proc.pp
index e33249c..555cf4d 100644
--- lcl/interfaces/win32/win32proc.pp
+++ lcl/interfaces/win32/win32proc.pp
@@ -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;
@@ -522,43 +521,6 @@ begin
 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
            KeyCode    - the ASCII key code of the eventkey
diff --git lcl/lmessages.pp lcl/lmessages.pp
index f977748..3790090 100644
--- lcl/lmessages.pp
+++ lcl/lmessages.pp
@@ -721,7 +721,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;
Updated patch. Tested compilation for gtk2 on Windows. I tried compiling carbon, cocoa, qt and wince, all succeeded but didn't created a folder in the output dir, so I guess something went wrong but I have no idea what.

Felipe Monteiro de Carvalho

2011-10-21 21:23

developer   ~0053259

SVN shows that GetShiftState is there from the start.
Please elaborate.
Turns out I'm the one who confused the functions' names, so I'm the one to elaborate :-$
Yes, GetShiftState (not GetKeyShiftState as I stated in the report) exists since r5549, 2004-06-10, but it is also unused or buggy since the beginning.

Felipe Monteiro de Carvalho

2011-10-24 14:36

developer   ~0053361

> Please elaborate.

I just marked this information in case someone else also wanted to search the svn history to check why it was added. Since it is from the beginning, we can't know why it was added.
Correction: the commit I cited previously is actually a code move. The original revision is r579 - MG: win32 interface update from Keith Bowes. Committed by Mattias.

Felipe Monteiro de Carvalho

2011-10-25 13:46

developer   ~0053409

This part of the patch is wrong:

-function ShiftStateToKeys(ShiftState: TShiftState): PtrUInt;
+function ShiftStateToKeys(ShiftState: TShiftState): PtrInt;

And unrelated to the rest.

Another problem is that TortoiseSVN does not recognize the patch format.

Felipe Monteiro de Carvalho

2011-10-25 13:49

developer   ~0053410

Oh, crap, GIT has a different patch format then SVN ...

Felipe Monteiro de Carvalho

2011-10-25 14:08

developer   ~0053414

Can you send a svn unified diff without this part:

-function ShiftStateToKeys(ShiftState: TShiftState): PtrUInt;
+function ShiftStateToKeys(ShiftState: TShiftState): PtrInt;

?

Felipe Monteiro de Carvalho

2011-10-25 14:18

developer   ~0053417

This patch has deeper implications also. Basically if we apply it then ssCaps will stop working in Windows, maybe Gtk too. One could argue that ssCaps should not really exist at all, it does not exist in Delphi. It seams to have been wrongly added. Maybe we should have a separate routine to obtain the state of such keys like CAPS LOCK.

On the other hand it looks possible to make a general routine for obtaining CAPS LOCK, NUM LOCK, etc, and then sum that information with the standard shift state to keep backwards compatibility supporting ssCaps in the mouse whell event.

Felipe Monteiro de Carvalho

2011-10-25 14:21

developer   ~0053420

Ah, there is already ... LCLIntf.GetKeyState

What about sending a patch which uses LCLIntf.GetKeyState in the LCL to avoid breaking ssCaps ?

Felipe Monteiro de Carvalho

2011-10-25 14:23

developer   ~0053421

Last edited: 2011-10-25 14:24

Not just ssCaps, but also Num, Scroll and Alt

That check could be added into KeysToShiftState

Felipe Monteiro de Carvalho

2011-10-25 14:36

developer   ~0053424

Last edited: 2011-10-25 14:41

Ok, actually it really looks like ssCaps and friends work in no other events ... so the idea of removing them gets stronger.

Edit: Not even for the mouse whell event they worked in my Windows XP

Flávio Etrusco (notifications not working)

2011-10-25 16:55

developer   ~0053430

Last edited: 2011-10-26 07:59

If you search ShiftStateToKeys, you'll see that all callers assign the result to TLMMouse.Keys, which is declared as PtrInt.
How are you trying to apply the patch? I don't have any problem applying git patches with 'svn patch' or TortoiseSVN.
Yes, no other message handler (or any other code) besides WMMouseWheel uses it. As I told you in private, somebody already reported that this was messing with his code because MouseWheel notification included ssCaps in ShiftState according to toggled state, not keydown state.
Also as I told you in pvt, besides LCLIntf.GetKeyState there are other similar functions in Controls and Forms.

Felipe Monteiro de Carvalho

2011-10-25 20:21

developer   ~0053433

> How are you trying to apply the patch?

With TortoiseSVN. In failed in 2 computers.

Felipe Monteiro de Carvalho

2011-10-26 16:20

developer   ~0053467

Another error that I spoted in your patch: It would desimplement ShiftState for Gtk2 ... I am fixing in my commit:

- MessE.State := ShiftState;
     MessE.UserData := AWinControl;
     MessE.Button := 0;

Correct solution:

    MessE.Button := ShiftStateToKeys(ShiftState);

Felipe Monteiro de Carvalho

2011-10-26 16:51

developer   ~0053469

Your patch also forgot other places in Gtk/Gtk2 which use that, also forgot Carbon, WinCE

Felipe Monteiro de Carvalho

2011-10-26 17:12

developer   ~0053473

Ok, this was a very massive change =D I hope I didn't break anything (it always breaks when I say that =D ) I tested wince, win32, qt, gtk2 and commited a bit blindly Carbon (will test when I am home)

I killed ssCaps, ssNum and ssScroll, they are unreliable and the existing implementation sucks. It uses the key lock in Win32 for example and it is impossible to implement them correct in Windows. Most other platforms offer some kind of partial implementation. I hate unreliable stuff =D

Jesus Reyes

2011-10-26 19:13

developer   ~0053483

I have installed some components I don't use to check for general compile status, this time it seems virtualtreeview from ccr was affected, I don't know if current development happens in ccr for it anyway.

one less in my component palette.

Felipe Monteiro de Carvalho

2011-10-26 20:16

developer   ~0053485

I fixed the virtualtreeview
Thanks, Felipe.

Issue History

Date Modified Username Field Change
2011-08-27 00:46 Flávio Etrusco (notifications not working) New Issue
2011-08-27 00:46 Flávio Etrusco (notifications not working) File Added: win-shiftstate-cleanup.patch
2011-08-27 00:46 Flávio Etrusco (notifications not working) LazTarget => -
2011-08-27 00:46 Flávio Etrusco (notifications not working) Widgetset => Win32/Win64
2011-08-30 04:39 Flávio Etrusco (notifications not working) Note Added: 0051265
2011-09-13 17:11 Flávio Etrusco (notifications not working) Summary WMMouseWheel handling in Win32 has special implementation of GetKeyShiftState. => [patch] WMMouseWheel handling in Win32 has special implementation of GetKeyShiftState.
2011-09-13 19:19 Flávio Etrusco (notifications not working) File Added: wmmousewheel-remove-special-case.patch
2011-09-13 19:45 Flávio Etrusco (notifications not working) Note Added: 0051795
2011-10-07 14:56 Vincent Snijders LazTarget - => 0.99.0
2011-10-07 14:56 Vincent Snijders Status new => acknowledged
2011-10-07 14:56 Vincent Snijders Target Version => 0.99.0
2011-10-21 21:22 Felipe Monteiro de Carvalho Status acknowledged => assigned
2011-10-21 21:22 Felipe Monteiro de Carvalho Assigned To => Felipe Monteiro de Carvalho
2011-10-21 21:23 Felipe Monteiro de Carvalho Note Added: 0053259
2011-10-21 21:27 Flávio Etrusco (notifications not working) Note Added: 0053260
2011-10-22 19:01 Flávio Etrusco (notifications not working) Note Added: 0053287
2011-10-24 14:36 Felipe Monteiro de Carvalho Note Added: 0053361
2011-10-24 18:24 Flávio Etrusco (notifications not working) Note Added: 0053371
2011-10-25 13:46 Felipe Monteiro de Carvalho Note Added: 0053409
2011-10-25 13:49 Felipe Monteiro de Carvalho Note Added: 0053410
2011-10-25 14:08 Felipe Monteiro de Carvalho Note Added: 0053414
2011-10-25 14:18 Felipe Monteiro de Carvalho Note Added: 0053417
2011-10-25 14:21 Felipe Monteiro de Carvalho Note Added: 0053420
2011-10-25 14:23 Felipe Monteiro de Carvalho Note Added: 0053421
2011-10-25 14:24 Felipe Monteiro de Carvalho Note Edited: 0053421
2011-10-25 14:36 Felipe Monteiro de Carvalho Note Added: 0053424
2011-10-25 14:41 Felipe Monteiro de Carvalho Note Edited: 0053424
2011-10-25 16:55 Flávio Etrusco (notifications not working) Note Added: 0053430
2011-10-25 20:21 Felipe Monteiro de Carvalho Note Added: 0053433
2011-10-26 07:59 Flávio Etrusco (notifications not working) Note Edited: 0053430
2011-10-26 16:20 Felipe Monteiro de Carvalho Note Added: 0053467
2011-10-26 16:51 Felipe Monteiro de Carvalho Note Added: 0053469
2011-10-26 17:12 Felipe Monteiro de Carvalho Fixed in Revision => 33092
2011-10-26 17:12 Felipe Monteiro de Carvalho Status assigned => resolved
2011-10-26 17:12 Felipe Monteiro de Carvalho Fixed in Version => 0.9.31 (SVN)
2011-10-26 17:12 Felipe Monteiro de Carvalho Resolution open => fixed
2011-10-26 17:12 Felipe Monteiro de Carvalho Note Added: 0053473
2011-10-26 19:13 Jesus Reyes Note Added: 0053483
2011-10-26 20:16 Felipe Monteiro de Carvalho Note Added: 0053485
2011-10-27 19:53 Felipe Monteiro de Carvalho Fixed in Revision 33092 => 33092, 33096, 33111, 33112
2011-10-27 20:09 Felipe Monteiro de Carvalho Fixed in Revision 33092, 33096, 33111, 33112 => 33092, 33096, 33111, 33112, 33114
2011-10-28 19:25 Flávio Etrusco (notifications not working) Note Added: 0053558