View Issue Details

IDProjectCategoryView StatusLast Update
0022666LazarusIDEpublic2012-08-30 00:19
ReporterWilliam de Oliveira FerreiraAssigned ToMattias Gaertner 
PrioritynormalSeverityblockReproducibilityalways
Status closedResolutionfixed 
Product Version1.0.0RC1Product Build 
Target Version1.0.0Fixed in Version1.0.1 (SVN) 
Summary0022666: ENTER Key behavior on String Editor
DescriptionHi,

I don´t remeber to read something about on Mailing list. The String Editor Dialog (e.g. TMemo.Lines OI's editor) now closes itself when the user hit <ENTER> and adds a new line when user hit <SHIFT> + <ENTER> but there isn´t any hint about that.

Should add some text explaining it or make it works as in old behavior (<ENTER> adds a new line)
Additional InformationDidn´t tested on other os/widgets...
TagsNo tags attached.
Fixed in Revision38427
LazTarget1.0.2
WidgetsetWin32/Win64
Attached Files
  • wantspecialkey.diff (12,685 bytes)
    Index: components/synedit/synedit.pp
    ===================================================================
    --- components/synedit/synedit.pp	(revision 38269)
    +++ components/synedit/synedit.pp	(working copy)
    @@ -4575,7 +4575,7 @@
           Message.Result := 0;
       end
       else
    -    inherited CMWantSpecialKey(Message);
    +    inherited;
     end;
     
     procedure TCustomSynEdit.ScanRanges(ATextChanged: Boolean = True);
    Index: lcl/forms.pp
    ===================================================================
    --- lcl/forms.pp	(revision 38269)
    +++ lcl/forms.pp	(working copy)
    @@ -1460,10 +1460,12 @@
         function IsRTLLang(ALang: String): Boolean;
         function Direction(ALang: String): TBiDiMode;
       public
    +    // on key down
         procedure DoArrowKey(AControl: TWinControl; var Key: Word; Shift: TShiftState);
    +    procedure DoTabKey(AControl: TWinControl; var Key: Word; Shift: TShiftState);
    +    // on key up
         procedure DoEscapeKey(AControl: TWinControl; var Key: Word; Shift: TShiftState);
         procedure DoReturnKey(AControl: TWinControl; var Key: Word; Shift: TShiftState);
    -    procedure DoTabKey(AControl: TWinControl; var Key: Word; Shift: TShiftState);
     
         property Active: boolean read GetActive;
         property ApplicationType : TApplicationType read FApplicationType write FApplicationType;
    Index: lcl/controls.pp
    ===================================================================
    --- lcl/controls.pp	(revision 38269)
    +++ lcl/controls.pp	(working copy)
    @@ -1278,7 +1278,6 @@
         procedure CMParentShowHintChanged(var Message: TLMessage); message CM_PARENTSHOWHINTCHANGED;
         procedure CMVisibleChanged(var Message: TLMessage); message CM_VISIBLECHANGED;
         procedure CMTextChanged(var Message: TLMessage); message CM_TEXTCHANGED;
    -    procedure CMWantSpecialKey(var Message: TLMessage); message CM_WANTSPECIALKEY;
         procedure CMCursorChanged(var Message: TLMessage); message CM_CURSORCHANGED;
       protected
         // drag and drop
    @@ -1889,7 +1888,6 @@
         procedure SetTabStop(NewTabStop: Boolean);
         procedure SetUseDockManager(const AValue: Boolean);
         procedure UpdateTabOrder(NewTabOrder: TTabOrder);
    -    function  WantsKeyBeforeInterface(Key: word; Shift: TShiftState): boolean;
         procedure Insert(AControl: TControl);
         procedure Insert(AControl: TControl; Index: integer);
         procedure Remove(AControl: TControl);
    Index: lcl/include/wincontrol.inc
    ===================================================================
    --- lcl/include/wincontrol.inc	(revision 38269)
    +++ lcl/include/wincontrol.inc	(working copy)
    @@ -5610,46 +5610,6 @@
     end;
     
     {------------------------------------------------------------------------------
    -  Method: TWinControl.WantsKey
    -  Params: CharCode - the key to inspect whether it is wanted
    -  Returns: true if key is wanted before the interface handles it.
    -
    -  Checks if control wants the passed key to handle before the interface.
    - ------------------------------------------------------------------------------}
    -function TWinControl.WantsKeyBeforeInterface(Key: word; Shift: TShiftState
    -  ): boolean;
    -var
    -  lWantKeys: dword;
    -{ values for lWantKeys
    -           0 - if not wanted
    -           1 - if wanted, but is special (arrow)
    -           2 - if wanted, but is special (tab)
    -           4 - if wanted, but is special (all)
    -           8 - if wanted, is normal key
    -}
    -begin
    -  // For Delphi compatibility we send a LM_GETDLGCODE message to the control
    -  // asking if it wants to handle the key.
    -  // We don't define a default handler for LM_GETDLGCODE,
    -  // so the default return is 0.
    -  // Note: Contrary to Delphi/win32api, we don't know what keys are special,
    -  // different widgetsets may have different sets of special keys;
    -  lWantKeys := Perform(LM_GETDLGCODE, 0, 0);
    -  if (lWantKeys and DLGC_WANTALLKEYS) <> 0 then
    -  begin
    -    lWantKeys := DLGC_WANTALLKEYS;
    -  end else begin
    -    case Key of
    -    VK_TAB: 
    -      lWantKeys := lWantKeys and DLGC_WANTTAB;
    -    VK_UP, VK_LEFT, VK_DOWN, VK_RIGHT:
    -      lWantKeys := lWantKeys and DLGC_WANTARROWS;
    -    end;
    -  end;  
    -  Result := (lWantKeys<>0);
    -end;
    -
    -{------------------------------------------------------------------------------
       TWinControl DoKeyDownBeforeInterface
       
       returns true if handled
    Index: lcl/include/control.inc
    ===================================================================
    --- lcl/include/control.inc	(revision 38269)
    +++ lcl/include/control.inc	(working copy)
    @@ -275,7 +275,8 @@
       begin
         FLastSearchIndex := 1;
         FLastSearchInSubcontrols := True;
    -    Result := TWinControl(OwnerControl).Controls[0].GetAccessibleObject();
    +    if (TWinControl(OwnerControl).ControlCount > 0) then
    +      Result := TWinControl(OwnerControl).Controls[0].GetAccessibleObject();
       end;
     end;
     
    @@ -295,7 +296,7 @@
       end
       else
       begin
    -    if TWinControl(OwnerControl).ControlCount < FLastSearchIndex then
    +    if TWinControl(OwnerControl).ControlCount > FLastSearchIndex then
         begin
           Result := TWinControl(OwnerControl).Controls[FLastSearchIndex].GetAccessibleObject();
           Inc(FLastSearchIndex);
    @@ -1116,15 +1117,6 @@
       TextChanged;
     end;
     
    -procedure TControl.CMWantSpecialKey(var Message: TLMessage);
    -begin
    -  // by default control does not want to handle VK_TAB itself
    -  if Message.wParam = VK_TAB then
    -    Message.Result := 0
    -  else
    -    Message.Result := 1;
    -end;
    -
     procedure TControl.CMCursorChanged(var Message: TLMessage);
     begin
       if not (csDesigning in ComponentState) then
    Index: lcl/include/application.inc
    ===================================================================
    --- lcl/include/application.inc	(revision 38269)
    +++ lcl/include/application.inc	(working copy)
    @@ -1671,7 +1671,8 @@
         // handle navigation key
         DoTabKey(AControl, Key, Shift);
         DoArrowKey(AControl, Key, Shift);
    -  end else
    +  end
    +  else
         FLastKeyDownSender := nil;
       //DebugLn(['TApplication.ControlKeyDown Sender=',DbgSName(Sender),' Key=',Key,' Shift=',dbgs(Shift)]);
       FLastKeyDownKey := Key;
    @@ -1683,21 +1684,23 @@
     var
       AControl: TWinControl;
     begin
    -  if Key=VK_UNKNOWN then exit;
    +  if Key = VK_UNKNOWN then exit;
     
    -  if Sender is TWinControl then begin
    -    AControl:=TWinControl(Sender);
    +  if Sender is TWinControl then
    +  begin
    +    AControl := TWinControl(Sender);
         //debugln('TApplication.ControlKeyUp A ',DbgSName(AControl),' Key=',dbgs(Key),' Shift=',dbgs(Shift));
    -    if FLastKeyDownKey=VK_UNKNOWN then begin
    +    if FLastKeyDownKey = VK_UNKNOWN then
    +    begin
           // key was already handled in key down
           //debugln('TApplication.ControlKeyUp key was handled in key down');
    -      exit;
    +      Exit;
         end;
    -    if (Key<>FLastKeyDownKey) or (Shift<>FLastKeyDownShift)
    -    or (AControl<>FLastKeyDownSender) then begin
    +    if (Key <> FLastKeyDownKey) or (Shift <> FLastKeyDownShift) or (AControl <> FLastKeyDownSender) then
    +    begin
           // a key up, without key down
           //debugln('TApplication.ControlKeyUp key was handled in key down or in key up');
    -      exit;
    +      Exit;
         end;
     
         // handle special navigation keys
    @@ -2021,9 +2024,10 @@
       Shift: TShiftState);
     begin
       if (Key in [VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN]) and (Shift = []) and
    +     (AControl.Perform(CM_WANTSPECIALKEY, Key, 0) = 0) and
    +     (AControl.Perform(LM_GETDLGCODE, 0, 0) and DLGC_WANTARROWS = 0) and
          (anoArrowToSelectNextInParent in Navigation) and AControl.Focused and
    -     (AControl.Parent <> nil) and
    -     (AControl.Perform(CM_WANTSPECIALKEY, Key, 0) = 0) then
    +     Assigned(AControl.Parent)  then
       begin
         // traverse controls inside parent
         AControl.Parent.SelectNext(AControl, Key in [VK_RIGHT, VK_DOWN], False);
    @@ -2079,17 +2083,17 @@
     var
       Form: TCustomForm;
     begin
    -  if (Shift = []) and (Key = VK_ESCAPE) then begin
    +  if (Shift = []) and (Key = VK_ESCAPE) and
    +     (AControl.Perform(CM_WANTSPECIALKEY, Key, 0) = 0) and
    +     (AControl.Perform(LM_GETDLGCODE, 0, 0) and DLGC_WANTALLKEYS = 0) and
    +     (anoEscapeForCancelControl in Navigation) then
    +  begin
         Form := GetParentForm(AControl);
    -    if Form<>nil then begin
    -      if (anoEscapeForCancelControl in Navigation) then begin
    -        if (Form.CancelControl <> nil) then
    -        begin
    -          //debugln('TApplication.ControlKeyUp VK_ESCAPE ', Acontrol.Name);
    -          Form.CancelControl.ExecuteCancelAction;
    -          Key := VK_UNKNOWN;
    -        end;
    -      end;
    +    if Assigned(Form) and Assigned(Form.CancelControl) then
    +    begin
    +      //debugln('TApplication.ControlKeyUp VK_ESCAPE ', Acontrol.Name);
    +      Form.CancelControl.ExecuteCancelAction;
    +      Key := VK_UNKNOWN;
         end;
       end;
     end;
    @@ -2100,23 +2104,25 @@
       Form: TCustomForm;
       lDefaultControl: TControl;
     begin
    -  if (Shift = []) and (Key = VK_RETURN) then begin
    +  if (Shift = []) and (Key = VK_RETURN) and
    +     (AControl.Perform(CM_WANTSPECIALKEY, Key, 0) = 0) and
    +     (AControl.Perform(LM_GETDLGCODE, 0, 0) and DLGC_WANTALLKEYS = 0) and
    +     (anoReturnForDefaultControl in Navigation) then
    +  begin
         //DebugLn(['TApplication.DoReturnKey ',DbgSName(AControl)]);
         Form := GetParentForm(AControl);
    -    if Form<>nil then begin
    -      if anoReturnForDefaultControl in Navigation then
    +    if Assigned(Form) then
    +    begin
    +      lDefaultControl := Form.ActiveDefaultControl;
    +      if lDefaultControl = nil then
    +        lDefaultControl := Form.DefaultControl;
    +      if Assigned(lDefaultControl)
    +        and ((lDefaultControl.Parent = nil) or (lDefaultControl.Parent.CanFocus))
    +        and lDefaultControl.Enabled and lDefaultControl.Visible then
           begin
    -        lDefaultControl := Form.ActiveDefaultControl;
    -        if lDefaultControl = nil then
    -          lDefaultControl := Form.DefaultControl;
    -        if (lDefaultControl <> nil)
    -          and ((lDefaultControl.Parent = nil) or (lDefaultControl.Parent.CanFocus))
    -          and lDefaultControl.Enabled and lDefaultControl.Visible then
    -        begin
    -          //debugln('TApplication.ControlKeyUp VK_RETURN ', Acontrol.Name);
    -          lDefaultControl.ExecuteDefaultAction;
    -          Key := VK_UNKNOWN;
    -        end;
    +        //debugln('TApplication.ControlKeyUp VK_RETURN ', Acontrol.Name);
    +        lDefaultControl.ExecuteDefaultAction;
    +        Key := VK_UNKNOWN;
           end;
         end;
       end;
    @@ -2126,8 +2132,9 @@
       Shift: TShiftState);
     begin
       if (Key = VK_TAB) and ((Shift - [ssShift]) = []) and
    -     (anoTabToSelectNext in Navigation) and AControl.Focused and
    -     (AControl.Perform(CM_WANTSPECIALKEY, Key, 0) = 0) then
    +     (AControl.Perform(CM_WANTSPECIALKEY, Key, 0) = 0) and
    +     (AControl.Perform(LM_GETDLGCODE, 0, 0) and DLGC_WANTTAB = 0) and
    +     (anoTabToSelectNext in Navigation) and AControl.Focused then
       begin
         // traverse tabstop controls inside form
         AControl.PerformTab(not (ssShift in Shift));
    Index: lcl/include/buttoncontrol.inc
    ===================================================================
    --- lcl/include/buttoncontrol.inc	(revision 38269)
    +++ lcl/include/buttoncontrol.inc	(working copy)
    @@ -50,12 +50,6 @@
       if Assigned(OnChange) then OnChange(Self);
     end;
     
    -procedure TButtonControl.CMWantSpecialKey(var Message: TLMessage);
    -begin
    -  // button controls do not want any special keys
    -  Message.Result := 0;
    -end;
    -
     procedure TButtonControl.Click;
     begin
       DoOnChange;
    @@ -66,6 +60,8 @@
     begin
       inherited Create(TheOwner);
       ControlStyle := ControlStyle-csMultiClicks-[csAcceptsControls,csCaptureMouse];
    +  AccessibleRole := larButton;
    +  AccessibleDescription := 'Button';
     end;
     
     { TButtonActionLink }
    Index: lcl/stdctrls.pp
    ===================================================================
    --- lcl/stdctrls.pp	(revision 38269)
    +++ lcl/stdctrls.pp	(working copy)
    @@ -417,6 +417,7 @@
         property AutoSize;// Note: windows has a fixed height in some styles
         property BidiMode;
         property BorderSpacing;
    +    property BorderStyle;
         property CharCase;
         property Color;
         property Constraints;
    @@ -853,8 +854,8 @@
         property AutoSize;
         property AutoSelect;
         property BidiMode;
    +    property BorderSpacing;
         property BorderStyle;
    -    property BorderSpacing;
         property CharCase;
         property Color;
         property Constraints;
    @@ -1057,7 +1058,6 @@
         procedure SetChecked(Value: Boolean); virtual;
         procedure DoOnChange; virtual;
         procedure Click; override;
    -    procedure CMWantSpecialKey(var Message: TLMessage); message CM_WANTSPECIALKEY;
       protected
         property Checked: Boolean read GetChecked write SetChecked stored IsCheckedStored default False;
         property ClicksDisabled: Boolean read FClicksDisabled write FClicksDisabled;
    
    wantspecialkey.diff (12,685 bytes)

Relationships

has duplicate 0022704 resolvedMaxim Ganetsky Lazarus SQL Window closes when hit ENTER key 
has duplicate 0023047 closedBart Broersma Packages Strings Editor Dialog hides at each "Enter" button press 
related to 0022732 closedPaul Ishenin Lazarus WantReturn ignored in TMemo 

Activities

Bart Broersma

2012-08-17 23:29

developer   ~0061688

Confirmed on WinMe.
The Enter gets processed by the memo before it gets closed.
NB. 1.1 doesn't have this behaviour.

Bart Broersma

2012-08-18 00:30

developer   ~0061689

procedure TCustomMemo.CMWantSpecialKey(var Message: TCMWantSpecialKey) isn't called when Enter key is pressed in RC1 (it is in trunk), and message.result isn't set appropriately.

Bart Broersma

2012-08-18 00:53

developer   ~0061691

Last edited: 2012-08-18 14:09

Maybe r32150 and possibly r37142 needs to be merged to RC1?

2012-08-18 14:42

 

wantspecialkey.diff (12,685 bytes)
Index: components/synedit/synedit.pp
===================================================================
--- components/synedit/synedit.pp	(revision 38269)
+++ components/synedit/synedit.pp	(working copy)
@@ -4575,7 +4575,7 @@
       Message.Result := 0;
   end
   else
-    inherited CMWantSpecialKey(Message);
+    inherited;
 end;
 
 procedure TCustomSynEdit.ScanRanges(ATextChanged: Boolean = True);
Index: lcl/forms.pp
===================================================================
--- lcl/forms.pp	(revision 38269)
+++ lcl/forms.pp	(working copy)
@@ -1460,10 +1460,12 @@
     function IsRTLLang(ALang: String): Boolean;
     function Direction(ALang: String): TBiDiMode;
   public
+    // on key down
     procedure DoArrowKey(AControl: TWinControl; var Key: Word; Shift: TShiftState);
+    procedure DoTabKey(AControl: TWinControl; var Key: Word; Shift: TShiftState);
+    // on key up
     procedure DoEscapeKey(AControl: TWinControl; var Key: Word; Shift: TShiftState);
     procedure DoReturnKey(AControl: TWinControl; var Key: Word; Shift: TShiftState);
-    procedure DoTabKey(AControl: TWinControl; var Key: Word; Shift: TShiftState);
 
     property Active: boolean read GetActive;
     property ApplicationType : TApplicationType read FApplicationType write FApplicationType;
Index: lcl/controls.pp
===================================================================
--- lcl/controls.pp	(revision 38269)
+++ lcl/controls.pp	(working copy)
@@ -1278,7 +1278,6 @@
     procedure CMParentShowHintChanged(var Message: TLMessage); message CM_PARENTSHOWHINTCHANGED;
     procedure CMVisibleChanged(var Message: TLMessage); message CM_VISIBLECHANGED;
     procedure CMTextChanged(var Message: TLMessage); message CM_TEXTCHANGED;
-    procedure CMWantSpecialKey(var Message: TLMessage); message CM_WANTSPECIALKEY;
     procedure CMCursorChanged(var Message: TLMessage); message CM_CURSORCHANGED;
   protected
     // drag and drop
@@ -1889,7 +1888,6 @@
     procedure SetTabStop(NewTabStop: Boolean);
     procedure SetUseDockManager(const AValue: Boolean);
     procedure UpdateTabOrder(NewTabOrder: TTabOrder);
-    function  WantsKeyBeforeInterface(Key: word; Shift: TShiftState): boolean;
     procedure Insert(AControl: TControl);
     procedure Insert(AControl: TControl; Index: integer);
     procedure Remove(AControl: TControl);
Index: lcl/include/wincontrol.inc
===================================================================
--- lcl/include/wincontrol.inc	(revision 38269)
+++ lcl/include/wincontrol.inc	(working copy)
@@ -5610,46 +5610,6 @@
 end;
 
 {------------------------------------------------------------------------------
-  Method: TWinControl.WantsKey
-  Params: CharCode - the key to inspect whether it is wanted
-  Returns: true if key is wanted before the interface handles it.
-
-  Checks if control wants the passed key to handle before the interface.
- ------------------------------------------------------------------------------}
-function TWinControl.WantsKeyBeforeInterface(Key: word; Shift: TShiftState
-  ): boolean;
-var
-  lWantKeys: dword;
-{ values for lWantKeys
-           0 - if not wanted
-           1 - if wanted, but is special (arrow)
-           2 - if wanted, but is special (tab)
-           4 - if wanted, but is special (all)
-           8 - if wanted, is normal key
-}
-begin
-  // For Delphi compatibility we send a LM_GETDLGCODE message to the control
-  // asking if it wants to handle the key.
-  // We don't define a default handler for LM_GETDLGCODE,
-  // so the default return is 0.
-  // Note: Contrary to Delphi/win32api, we don't know what keys are special,
-  // different widgetsets may have different sets of special keys;
-  lWantKeys := Perform(LM_GETDLGCODE, 0, 0);
-  if (lWantKeys and DLGC_WANTALLKEYS) <> 0 then
-  begin
-    lWantKeys := DLGC_WANTALLKEYS;
-  end else begin
-    case Key of
-    VK_TAB: 
-      lWantKeys := lWantKeys and DLGC_WANTTAB;
-    VK_UP, VK_LEFT, VK_DOWN, VK_RIGHT:
-      lWantKeys := lWantKeys and DLGC_WANTARROWS;
-    end;
-  end;  
-  Result := (lWantKeys<>0);
-end;
-
-{------------------------------------------------------------------------------
   TWinControl DoKeyDownBeforeInterface
   
   returns true if handled
Index: lcl/include/control.inc
===================================================================
--- lcl/include/control.inc	(revision 38269)
+++ lcl/include/control.inc	(working copy)
@@ -275,7 +275,8 @@
   begin
     FLastSearchIndex := 1;
     FLastSearchInSubcontrols := True;
-    Result := TWinControl(OwnerControl).Controls[0].GetAccessibleObject();
+    if (TWinControl(OwnerControl).ControlCount > 0) then
+      Result := TWinControl(OwnerControl).Controls[0].GetAccessibleObject();
   end;
 end;
 
@@ -295,7 +296,7 @@
   end
   else
   begin
-    if TWinControl(OwnerControl).ControlCount < FLastSearchIndex then
+    if TWinControl(OwnerControl).ControlCount > FLastSearchIndex then
     begin
       Result := TWinControl(OwnerControl).Controls[FLastSearchIndex].GetAccessibleObject();
       Inc(FLastSearchIndex);
@@ -1116,15 +1117,6 @@
   TextChanged;
 end;
 
-procedure TControl.CMWantSpecialKey(var Message: TLMessage);
-begin
-  // by default control does not want to handle VK_TAB itself
-  if Message.wParam = VK_TAB then
-    Message.Result := 0
-  else
-    Message.Result := 1;
-end;
-
 procedure TControl.CMCursorChanged(var Message: TLMessage);
 begin
   if not (csDesigning in ComponentState) then
Index: lcl/include/application.inc
===================================================================
--- lcl/include/application.inc	(revision 38269)
+++ lcl/include/application.inc	(working copy)
@@ -1671,7 +1671,8 @@
     // handle navigation key
     DoTabKey(AControl, Key, Shift);
     DoArrowKey(AControl, Key, Shift);
-  end else
+  end
+  else
     FLastKeyDownSender := nil;
   //DebugLn(['TApplication.ControlKeyDown Sender=',DbgSName(Sender),' Key=',Key,' Shift=',dbgs(Shift)]);
   FLastKeyDownKey := Key;
@@ -1683,21 +1684,23 @@
 var
   AControl: TWinControl;
 begin
-  if Key=VK_UNKNOWN then exit;
+  if Key = VK_UNKNOWN then exit;
 
-  if Sender is TWinControl then begin
-    AControl:=TWinControl(Sender);
+  if Sender is TWinControl then
+  begin
+    AControl := TWinControl(Sender);
     //debugln('TApplication.ControlKeyUp A ',DbgSName(AControl),' Key=',dbgs(Key),' Shift=',dbgs(Shift));
-    if FLastKeyDownKey=VK_UNKNOWN then begin
+    if FLastKeyDownKey = VK_UNKNOWN then
+    begin
       // key was already handled in key down
       //debugln('TApplication.ControlKeyUp key was handled in key down');
-      exit;
+      Exit;
     end;
-    if (Key<>FLastKeyDownKey) or (Shift<>FLastKeyDownShift)
-    or (AControl<>FLastKeyDownSender) then begin
+    if (Key <> FLastKeyDownKey) or (Shift <> FLastKeyDownShift) or (AControl <> FLastKeyDownSender) then
+    begin
       // a key up, without key down
       //debugln('TApplication.ControlKeyUp key was handled in key down or in key up');
-      exit;
+      Exit;
     end;
 
     // handle special navigation keys
@@ -2021,9 +2024,10 @@
   Shift: TShiftState);
 begin
   if (Key in [VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN]) and (Shift = []) and
+     (AControl.Perform(CM_WANTSPECIALKEY, Key, 0) = 0) and
+     (AControl.Perform(LM_GETDLGCODE, 0, 0) and DLGC_WANTARROWS = 0) and
      (anoArrowToSelectNextInParent in Navigation) and AControl.Focused and
-     (AControl.Parent <> nil) and
-     (AControl.Perform(CM_WANTSPECIALKEY, Key, 0) = 0) then
+     Assigned(AControl.Parent)  then
   begin
     // traverse controls inside parent
     AControl.Parent.SelectNext(AControl, Key in [VK_RIGHT, VK_DOWN], False);
@@ -2079,17 +2083,17 @@
 var
   Form: TCustomForm;
 begin
-  if (Shift = []) and (Key = VK_ESCAPE) then begin
+  if (Shift = []) and (Key = VK_ESCAPE) and
+     (AControl.Perform(CM_WANTSPECIALKEY, Key, 0) = 0) and
+     (AControl.Perform(LM_GETDLGCODE, 0, 0) and DLGC_WANTALLKEYS = 0) and
+     (anoEscapeForCancelControl in Navigation) then
+  begin
     Form := GetParentForm(AControl);
-    if Form<>nil then begin
-      if (anoEscapeForCancelControl in Navigation) then begin
-        if (Form.CancelControl <> nil) then
-        begin
-          //debugln('TApplication.ControlKeyUp VK_ESCAPE ', Acontrol.Name);
-          Form.CancelControl.ExecuteCancelAction;
-          Key := VK_UNKNOWN;
-        end;
-      end;
+    if Assigned(Form) and Assigned(Form.CancelControl) then
+    begin
+      //debugln('TApplication.ControlKeyUp VK_ESCAPE ', Acontrol.Name);
+      Form.CancelControl.ExecuteCancelAction;
+      Key := VK_UNKNOWN;
     end;
   end;
 end;
@@ -2100,23 +2104,25 @@
   Form: TCustomForm;
   lDefaultControl: TControl;
 begin
-  if (Shift = []) and (Key = VK_RETURN) then begin
+  if (Shift = []) and (Key = VK_RETURN) and
+     (AControl.Perform(CM_WANTSPECIALKEY, Key, 0) = 0) and
+     (AControl.Perform(LM_GETDLGCODE, 0, 0) and DLGC_WANTALLKEYS = 0) and
+     (anoReturnForDefaultControl in Navigation) then
+  begin
     //DebugLn(['TApplication.DoReturnKey ',DbgSName(AControl)]);
     Form := GetParentForm(AControl);
-    if Form<>nil then begin
-      if anoReturnForDefaultControl in Navigation then
+    if Assigned(Form) then
+    begin
+      lDefaultControl := Form.ActiveDefaultControl;
+      if lDefaultControl = nil then
+        lDefaultControl := Form.DefaultControl;
+      if Assigned(lDefaultControl)
+        and ((lDefaultControl.Parent = nil) or (lDefaultControl.Parent.CanFocus))
+        and lDefaultControl.Enabled and lDefaultControl.Visible then
       begin
-        lDefaultControl := Form.ActiveDefaultControl;
-        if lDefaultControl = nil then
-          lDefaultControl := Form.DefaultControl;
-        if (lDefaultControl <> nil)
-          and ((lDefaultControl.Parent = nil) or (lDefaultControl.Parent.CanFocus))
-          and lDefaultControl.Enabled and lDefaultControl.Visible then
-        begin
-          //debugln('TApplication.ControlKeyUp VK_RETURN ', Acontrol.Name);
-          lDefaultControl.ExecuteDefaultAction;
-          Key := VK_UNKNOWN;
-        end;
+        //debugln('TApplication.ControlKeyUp VK_RETURN ', Acontrol.Name);
+        lDefaultControl.ExecuteDefaultAction;
+        Key := VK_UNKNOWN;
       end;
     end;
   end;
@@ -2126,8 +2132,9 @@
   Shift: TShiftState);
 begin
   if (Key = VK_TAB) and ((Shift - [ssShift]) = []) and
-     (anoTabToSelectNext in Navigation) and AControl.Focused and
-     (AControl.Perform(CM_WANTSPECIALKEY, Key, 0) = 0) then
+     (AControl.Perform(CM_WANTSPECIALKEY, Key, 0) = 0) and
+     (AControl.Perform(LM_GETDLGCODE, 0, 0) and DLGC_WANTTAB = 0) and
+     (anoTabToSelectNext in Navigation) and AControl.Focused then
   begin
     // traverse tabstop controls inside form
     AControl.PerformTab(not (ssShift in Shift));
Index: lcl/include/buttoncontrol.inc
===================================================================
--- lcl/include/buttoncontrol.inc	(revision 38269)
+++ lcl/include/buttoncontrol.inc	(working copy)
@@ -50,12 +50,6 @@
   if Assigned(OnChange) then OnChange(Self);
 end;
 
-procedure TButtonControl.CMWantSpecialKey(var Message: TLMessage);
-begin
-  // button controls do not want any special keys
-  Message.Result := 0;
-end;
-
 procedure TButtonControl.Click;
 begin
   DoOnChange;
@@ -66,6 +60,8 @@
 begin
   inherited Create(TheOwner);
   ControlStyle := ControlStyle-csMultiClicks-[csAcceptsControls,csCaptureMouse];
+  AccessibleRole := larButton;
+  AccessibleDescription := 'Button';
 end;
 
 { TButtonActionLink }
Index: lcl/stdctrls.pp
===================================================================
--- lcl/stdctrls.pp	(revision 38269)
+++ lcl/stdctrls.pp	(working copy)
@@ -417,6 +417,7 @@
     property AutoSize;// Note: windows has a fixed height in some styles
     property BidiMode;
     property BorderSpacing;
+    property BorderStyle;
     property CharCase;
     property Color;
     property Constraints;
@@ -853,8 +854,8 @@
     property AutoSize;
     property AutoSelect;
     property BidiMode;
+    property BorderSpacing;
     property BorderStyle;
-    property BorderSpacing;
     property CharCase;
     property Color;
     property Constraints;
@@ -1057,7 +1058,6 @@
     procedure SetChecked(Value: Boolean); virtual;
     procedure DoOnChange; virtual;
     procedure Click; override;
-    procedure CMWantSpecialKey(var Message: TLMessage); message CM_WANTSPECIALKEY;
   protected
     property Checked: Boolean read GetChecked write SetChecked stored IsCheckedStored default False;
     property ClicksDisabled: Boolean read FClicksDisabled write FClicksDisabled;
wantspecialkey.diff (12,685 bytes)

Bart Broersma

2012-08-18 14:43

developer   ~0061697

Last edited: 2012-08-18 23:45

Possible patch uploaded, also merges 37159.
(I just kept on trying by hand until it worked)

PS. I made the diff against branches/fixes_1_0, I hope that is the correct one?

Bart Broersma

2012-08-22 14:22

developer   ~0061809

Last edited: 2012-08-22 14:23

Set severity to block: it is a regression, and it makes parts of the OI unusable and can lead to strange effects in existing programs that use a TMemo and a button with .Default = True on any form.
Feel free to disagree.

Vincent Snijders

2012-08-29 09:17

manager   ~0061960

I set LazTarget, so it shows up the filters covering Lazarus, Lazarus packages and Lazarus patches.

Bart Broersma

2012-08-30 00:19

developer   ~0061974

Fixed.

Issue History

Date Modified Username Field Change
2012-08-17 22:20 William de Oliveira Ferreira New Issue
2012-08-17 22:20 William de Oliveira Ferreira Widgetset => Win32/Win64
2012-08-17 23:29 Bart Broersma LazTarget => -
2012-08-17 23:29 Bart Broersma Note Added: 0061688
2012-08-17 23:29 Bart Broersma Status new => confirmed
2012-08-17 23:30 Bart Broersma Target Version => 1.0.0
2012-08-18 00:30 Bart Broersma Note Added: 0061689
2012-08-18 00:53 Bart Broersma Note Added: 0061691
2012-08-18 14:09 Bart Broersma Note Edited: 0061691
2012-08-18 14:42 Bart Broersma File Added: wantspecialkey.diff
2012-08-18 14:43 Bart Broersma Note Added: 0061697
2012-08-18 18:52 Bart Broersma Note Edited: 0061697
2012-08-18 23:45 Bart Broersma Note Edited: 0061697
2012-08-22 14:22 Bart Broersma Note Added: 0061809
2012-08-22 14:22 Bart Broersma Severity tweak => block
2012-08-22 14:23 Bart Broersma Note Edited: 0061809
2012-08-23 00:14 Maxim Ganetsky Relationship added has duplicate 0022704
2012-08-29 09:17 Vincent Snijders LazTarget - => 1.0
2012-08-29 09:17 Vincent Snijders Note Added: 0061960
2012-08-29 09:18 Vincent Snijders Relationship added related to 0022732
2012-08-29 19:45 Mattias Gaertner Fixed in Revision => 38427
2012-08-29 19:45 Mattias Gaertner LazTarget 1.0 => 1.0.2
2012-08-29 19:45 Mattias Gaertner Assigned To => Mattias Gaertner
2012-08-29 19:45 Mattias Gaertner Status confirmed => resolved
2012-08-29 19:45 Mattias Gaertner Resolution open => fixed
2012-08-30 00:19 Bart Broersma Status resolved => closed
2012-08-30 00:19 Bart Broersma Note Added: 0061974
2012-08-30 00:19 Bart Broersma Fixed in Version => 1.0.1 (SVN)
2012-10-03 12:35 Bart Broersma Relationship added has duplicate 0023047