Jump to content
balabuev

Popup window with focus inside.

Recommended Posts

Whether it theoretically possible in Windows to have a popup window with some focused control (child window) in it, while keeping application's main window active?

Edited by balabuev

Share this post


Link to post

Let me reformulate: You create a popup window as a TForm and show it non modal (that is just call Show). Then the popup window get's the focus. Now you want to main (parent) window keep the focus?

 

The focus in Windows terminology is the window receiving keyboard input from the user. As there is only one keyboard, there could be only one window getting the focus.

 

BUT a TForm can get hand on every key press using KeyPreview property. Nothing prevent you from sending the keystroke to the parent window for handling. You can decide if the keystroke will be handed by the popup window or not by nullifing the key code.

 

All this is particularly convoluted. Not sure it is interesting. I don't know since you didn't explained what you want to do: you talked about a solution, not a problem.

Share this post


Link to post

 

2 hours ago, FPiette said:

you talked about a solution, not a problem.

This is a theoretical question, not related to any particular problem.

 

2 hours ago, Fr0sT.Brutal said:

Generally, no AFAIK.

I think similarly, but asked here to ensure that I'm not mising something. Some combination of window styles, things like that...

 

 

Share this post


Link to post
Guest

my sample about this Popup question, using a "Form" to simulate a popup-fake, but tottaly usual.

 

In the old IDERA Forum I did something very similar to this for a user.
I simulate a "POPMENU" with a "Form" and any other controls into it. So, you can either make entries in the main form (what I called my popup-fake), or work on the controls within the popup-fake.
They will work completely independently, where each one can focus when they want without disturbing the work of the other.

 

image.thumb.png.a6ab4b6945562e81fff49014d9b44a40.png

 

hug

Share this post


Link to post

To clarify things:

 

On 12/30/2020 at 10:50 AM, FPiette said:

You create a popup window as a TForm and show it non modal (that is just call Show)

No. I'm speaking about native Windows API, and thats why I've chosen Windows API forum section. Relative to Delphi I'm more speaking about some custom combo-box like control, in which the popup window may be a descendant from TCustomControl with overridden CreateParams, ect.

 

On 12/30/2020 at 10:50 AM, FPiette said:

Then the popup window get's the focus

Yes. Which means that:

Winapi.Windows.GetFocus = MyPopupWindow.Handle // Popup window has real focus

 

On 12/30/2020 at 10:50 AM, FPiette said:

Now you want to main (parent) window keep the focus?

No. Its impossible for two windows have focus simultaneously (I'm not so stupid :classic_biggrin:). I want main window (or main form - no big difference here) to remains active:

Winapi.Windows.GetActiveWindow = MainWindow.Handle

 

However, if there no native Windows way to achieve this, the next question - what is a canonical way to "simulate"? I guess I'll need to hook main window (control's parent form) WndProc and suppress some non-client area related messages...

 

 

 

 

Edited by balabuev

Share this post


Link to post
On 1/2/2021 at 1:37 AM, David Heffernan said:

Is your question, "is it possible to change the focus without changing the active window?"

Yes, the question can be re-formulated like this.

Share this post


Link to post
5 minutes ago, Lars Fosdal said:

What about the ToolWindow window style on the popup?

I cannot understand how this relates to my question? And what is special about bsToolWindow border style (WS_EX_TOOLWINDOW in WinAPI terms)?

Share this post


Link to post

My context was:
"... have a popup window with some focused control (child window) in it, while keeping application's main window active"

Isn't that typically what a tool window does?

Win32 doc states for
WS_EX_TOOLWINDOW:

Quote

The window is intended to be used as a floating toolbar. A tool window has a title bar that is shorter than a normal title bar, and the window title is drawn using a smaller font. A tool window does not appear in the taskbar or in the dialog that appears when the user presses ALT+TAB. If a tool window has a system menu, its icon is not displayed on the title bar. However, you can display the system menu by right-clicking or by typing ALT+SPACE.

 

Share this post


Link to post

When TolWindow or some of its children got the focus, the main window will be de-activated. This is exactly the problem.

Share this post


Link to post

Ok, that is a challenge.

What kind of control is it that gets focused in the popup?

Would it be possible to deny the focus event somehow?

Share this post


Link to post
2 minutes ago, Lars Fosdal said:

Would it be possible to deny the focus event somehow?

I noted previously - the question is theoretical. I understand how native combo-box works, and how it prevents its own drop-down window from having real focus - and so, such case is not interesting.

If you want some example, imagine TMemo inside the popup. It requires real focus not only to process key events, but also, because it hides the caret in non-focused state. And there more minor differences. But, anyway, tweaking the control and redirecting events - is not a part of my question.

 

 

Share this post


Link to post

It may be that the trick required is to fake the focus color of the main form when the popup is focused, and that the main form is refocused as soon as the mouse goes outside the popup.

Share this post


Link to post

Yes, something like this. But what is interesting, why Windows does not allow to achieve this natively, without cheating.

Share this post


Link to post

Does it really matter for the user if the title bar of the main window is not focused?


The meaningfulness of the current focus color behaviour has become increasingly diluted by the Electron apps (and others) that run custom colors that doesn't respect the Theme settings at all - focused or not.

Share this post


Link to post

If we speak about combo-box like controls - yes it matters. The user percept main form de-activating/re-activating like flickering, like unwanted behavior.

Share this post


Link to post

What if you did not have a popup form as such, but instead have a frame floating in front in the form?  You could make the frame look like a form, and it would take a little extra work to make it movable - and it would not be possible to position it outside the parent form.

Share this post


Link to post

Yes. Btw, always "active" form is simple to cheat:

type
  TForm1 = class(TForm)
  private
    procedure WMNCActivate(var Message: TWMNCActivate); message WM_NCACTIVATE;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.WMNCActivate(var Message: TWMNCActivate);
begin
  Message.Active := True;
  inherited;
end;

 

Edited by balabuev

Share this post


Link to post
Guest

and, IF... (be a Form or Frame = same use)

 

image.thumb.png.6e45defec98c8ac008df9cbd658da489.png

// unit FormMain
...

implementation

var // for all unit use
  frmFramePopupMenu: TfrmFramPopup;

...
// onCreate
  frmFramePopupMenu        := TfrmFramPopup.Create(nil);
  frmFramePopupMenu.Visible := false;
  frmFramePopupMenu.Parent := self;

// onDestroy
  frmFramePopupMenu.Free;

// onKeyDown event for mouse use
procedure TfrmFormMain.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  frmFormMain.Memo1.Lines.Add(Format('my Popup Left=%d, Top=%d', [X, Y]));
  //
  if (Button = TMouseButton.mbRight) then
  begin

    if not(frmForm2MyPopMenu = nil) then // and (not frmForm2MyPopMenu.Showing)) then
    begin
      frmFramePopupMenu.Left := X;
      frmFramePopupMenu.Top  := Y;
      //
      frmFramePopupMenu.Show;
    end;
  end;

  (*
    if (Button = TMouseButton.mbRight) then
    begin
    if not(frmForm2MyPopMenu = nil) then // and (not frmForm2MyPopMenu.Showing)) then
    begin
    frmForm2MyPopMenu.Left := X;
    frmForm2MyPopMenu.Top  := Y;
    //
    frmForm2MyPopMenu.Show;
    end;
    end;
  *)
end;

 

frame unit

unit uMyFramePopup;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TfrmFramPopup = class(TFrame)
    Memo1: TMemo;
    btn_CloseMe: TButton;
    procedure btn_CloseMeClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

procedure TfrmFramPopup.btn_CloseMeClick(Sender: TObject);
begin
  Self.Visible := false;
end;

end.

 

 

hug

Edited by Guest

Share this post


Link to post
12 minutes ago, emailx45 said:

and, IF... (be a Form or Frame = same use)

You create a child form (or frame), not popup. Child window can't exceed the bounds of its parent window.

Edited by balabuev

Share this post


Link to post
Guest

my sample dont exceed the window limit, im using "formxxx.PARENT = SELF and framexxx.PARENT = SELF " then, the limit of my "form or frame" is my FormMain Client Area!

this my "FAKE-POPUP" of course! and the "focus" still on FormMain or in my Fake-popup, you decide!

 

image.thumb.png.f75d3ca03f5c72bbaff19d7d16fb2bd3.png

Edited by Guest

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×