0

In our company we use a very potent descendant of TCustomButton.

For a new application I want a button that basically behaves like a "Speedbtn", which has no TabStop and especially don't steals the focus of other controls like for example a TEdit. I would love if I'm able to just maniuplate our descendant of the TCustomButton, so that I don't have to write a whole new button coomponent, for which I would have to implement many things that our descendant of TCustomButton already offers (like Corporate Design etc.)

I'm aware that this isn't an easy task, because as far as I understand, the decision that the click on the button triggers the message to focus himself ( which steals the focus of the Tedit), depends on the registry in windows ("TCustomButton.CreateParams" ??).

If a possible solution is too much of a hack, i probably won't even use it in our system, but I still would be pretty interested in it, because I'm a curious person :).

Anyway here's my example: I have a TForm which only contains a TEdit and a descendant of TCustomButton, which already has lost the functionality (which it orignally had by being a descendant of TButtonControl) to get the focus if WM_LBUTTONDOWN or WM_LBUTTONDBLCLK comes by in WndProc.

type
  TMyBtn = class (TCustomButton)
  //
  // ...  A lot of self-written stuff
  //
  protected
    procedure WndProc(var Message: TMessage); override;
  public
  //
  // ... A lot of self-written Properties
  //
  end;

type
  TForm2 = class(TForm)
    Edit1: TEdit;
    Button1: TMyBtn;
  end;

implementation

procedure TMyBtn.WndProc(var Message: TMessage);

var
  hProc : procedure (var Message: TMessage) of object;

begin
  // Skip TButtonControl.WndProc and call
  // TWinControl.WndProc instead if Message type
  // is WM_LBUTTONDOWN or WM_LBUTTONDBLCLK
  if not (csDesigning in ComponentState)  then
  begin
    case Message.Msg of
      WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
      begin
        TMethod(hProc).Code := @TWinControl.WndProc;
        TMethod(hProc).Data := Self;
        hProc( Message);
        exit;
      end;
    end;
  end;

  inherited WndProc(Message);
end;

What can I do, that the TEdit doesn't lose the focus if the TEdit has the focus and i click on the descendant of TCustomButton ( other than disabling the button or refocusing the TEdit etc.)

Many Thanks for any help in advance.

If I didn't manage to describe my question properly, feel free to ask me any questions.

  • Have you tried to change the `TabStop` property to False.`TabStop` property controls whether the control can recieve focus or not. – SilverWarior Apr 08 '19 at 08:55
  • @SilverWarior But you can still click on the button, even with `TabStop` set to false. That will still focus the button – GuidoG Apr 08 '19 at 09:04
  • 6
    @SilverWarior, your statement *"TabStop property controls whether the control can recieve focus or not"* is wrong. personally I would go with `TSpeedButton` and done with it. – kobik Apr 08 '19 at 09:07
  • Yeah I tried that. But in my test setting the TabStop property to false didn't stop the edit losing the focus. Thanks for your hint anyway. – Jonas Seufert Apr 08 '19 at 09:07
  • @Kobik Yeah that's what I'm probably going to do. As menitoned I'm just curious if there's even a solution for my task. – Jonas Seufert Apr 08 '19 at 09:17
  • @JonasSeufert, maybe there is a "solution" but it is really not trivial and could cause side effects, as the `TButton` is expected to have a focus to generate the click event. I have tried handling the `WM_SETFOCUS` by setting the focus back to the window that lost focus, but then the click event wont fire... – kobik Apr 08 '19 at 10:08
  • @Kobik Yeah, I saw your temporary answer. I think refocusing the window that lost focus can't be the solution, as due to the temporary loss of the focus I for example lose the positioning in the edit. My guess is, if there's a solution it will have something to do with how windows himself handles the button. I doubt it can be done by handling messages in some ways. Many thanks for your help anyway. – Jonas Seufert Apr 08 '19 at 10:38
  • `TCustomButton` is a windowed control. `TSpeedBtn` is a graphical control. Windowed controls change input focus, graphical controls do not. Simple as that. Nothing you can do about it that doesn't produce side effects. See related: [Is it possible to avoid a TRichEdit losing its focus when clicking a button (e.g. Bold)?](https://stackoverflow.com/questions/5707638/) – Remy Lebeau Apr 08 '19 at 14:50
  • Since you are handling windows messages yourself then maybe you might want to consider also handling the [WM_SETFOCUS](https://learn.microsoft.com/sl-si/windows/desktop/inputdev/wm-setfocus) message to read which window lost its focus to button and then manually switching focus back to that control. The thing is that you will lose focus the caret position in the process. – SilverWarior Apr 08 '19 at 21:40
  • @Remy Lebeau: Many thanks for your answer. I assumed from the beginning that your answer might be the answer that I have to live with in the end. As mentioned I wouldn't have used a too sick solution anyway. I was just curious if there's a way to manipulate the controls afterwards. – Jonas Seufert Apr 09 '19 at 07:58
  • @SilverWarior Many thanks for your answer, too. But as mentioned refocusing the edit doesn't do the trick for me. I will have to go with a new descendant of TSpeedBtn. – Jonas Seufert Apr 09 '19 at 08:00
  • I would respect Remy Lebeau's comment as an answer too. How is the code of conduct on this site, should i answer the question myself and quote Remy Lebeau or can I mark the question somehow as concluded? I didn't found an answer to this in the faq. – Jonas Seufert Apr 09 '19 at 09:04
  • 1
    Since @RemyLebeau Is not answering or still after this comment, answer your self and accept, this site is a library of Q&A after all, the main goal here is to have solutions to problems. :) – Nasreddine Galfout Apr 09 '19 at 20:20
  • @ Nasreddine Galfout: Thanks – Jonas Seufert Apr 13 '19 at 15:43

1 Answers1

0

As an answer I quote a comment of Remy Lebeau

TCustomButton is a windowed control. TSpeedBtn is a graphical control. Windowed controls change input focus, graphical controls do not. Simple as that. Nothing you can do about it that doesn't produce side effects.