Jump to content
balabuev

Popup window with focus inside.

Recommended Posts

22 minutes ago, emailx45 said:

my sample dont exceed the window limit

That is exactly the problem.

Share this post


Link to post
Guest
2 hours ago, balabuev said:

That is exactly the problem.

just assign xxx.PARENT := nil

and LEFT and TOP using SCREEN or DC coordenate

Edited by Guest

Share this post


Link to post
Quote

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.

If there is flickering going on I would guess a onchange event is looping. radio buttons calling each other after being changed by the other.   

 

The user needs to know only one window is in focus at a time.   To help the user we would still draw halo around the control using the popup, color the popup the same as launching form.    

 

Or showing form with image.picture.bitmap of a active form saved as bitmap would work when shown as toolbar. But not recommended.  

 

  

 

 

Share this post


Link to post
6 minutes ago, emailx45 said:

just assign xxx.PARENT := nil

Can you read my initial question just to understand what is all about...

Share this post


Link to post
9 minutes ago, Pat Foley said:

The user needs to know only one window is in focus at a time.

So, what is about standard combo-box with opened drop-down. You can use arrow keys to go up and down between items, while keeping main (parent) form active. I know how this is done technically, but don't you think, that conceptually this case violates your "only one window is in focus" idea?

Share this post


Link to post
  • Quote

    So, what is about standard combo-box with opened drop-down.

    The combo box drop down can only be opened in active window. 
 
  • Sad 1

Share this post


Link to post
unit mainFocused;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormClick(Sender: TObject);

    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    destructor Destroy;
  end;

var
  Form1: TForm1;

implementation
uses
  unFocused;
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  UF.IniZ(self);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  I,C: integer;
  F: TForm;
begin
  with Screen do begin
    for I := formCount - 1 downto 0 do
      begin
        F := Forms[I];
        for C := 0 to F.ComponentCount - 1 do
          if F.Components[C] is TButton then
        begin
          F.Show;
          (F.Components[C] as TButton).parent.show;
          (F.Components[C] as TButton).Show;
          caption := F.Name;
          application.ProcessMessages;
          sleep(1200);
          Break;
        end;
      end;
      end;
  end;
destructor TForm1.Destroy;
var
  I: integer;
begin
  onclick := nil;
  with Screen do begin
    for I := formCount - 1 downto 0 do
      begin

        Forms[I].close;
      end;
  end;
end;

procedure TForm1.FormClick(Sender: TObject);
begin
  Caption := 'clicked by ' + (Sender as TForm).Name;
  Self.Show;
  Button1.SetFocus;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Caption := 'Mouse over ' +  (Sender as Tcontrol).Name;
end;

end.
unit unfocused;

interface

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

type
  TfrmdrawFocused = class(TForm)
    Button1: TButton;
    Image2: TImage;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    toFocusAhead: TForm;
    procedure ForwardFocus(Sender: TObject);
    procedure IniZ(anOwnerForm: TForm);
    Destructor Destroy;
  end;

var
  UF, frmdrawFocused: TfrmdrawFocused;

implementation

{$R *.dfm}

{ TfrmUnfocused }

procedure TfrmdrawFocused.Button1Click(Sender: TObject);
begin
  beep;
end;

destructor TfrmdrawFocused.Destroy;
begin
  tofocusAhead.free;
  inherited;
end;

procedure TfrmdrawFocused.ForwardFocus(Sender: TObject);
begin
  //inherited; //squash local click
  toFocusAhead.OnClick(self);
end;

procedure TfrmdrawFocused.IniZ(anOwnerForm: TForm);
begin
  Application.CreateForm(TfrmdrawFocused, UF);
    with UF do begin
                   name := 'UF' + Screen.FormCount.ToString;
                   Caption := name;
                   setbounds(10,20,260,170);
                   toFocusAhead := anOwnerForm;
                   onclick := ForwardFocus;
                   onmousedown := nil;
                   onmouseMove := anOwnerform.OnMouseMove;
                   Color := $1E69D2;
                   show;
                 end;
end;

end.

Try these forms with aux forms Borderstyle set to  bsnormal  then no border.   

Share this post


Link to post
5 minutes ago, Pat Foley said:

Try these forms with aux forms Borderstyle set to  bsnormal  then no border.   

And what should we see?

Share this post


Link to post

runtime forms should feed mouseovers and form name back to creator form.  Perhaps what you want is a windows balloon tip.    

Share this post


Link to post
4 minutes ago, Pat Foley said:

runtime forms should feed mouseovers and form name back to creator form.  Perhaps what you want is a windows balloon tip.    

Unfortunately, this is not related to my initial question at all.

Share this post


Link to post
Guest

Am I trying to understand where all this is going to take place, in a real application?

Why would anyone want to have a PopUpMenu isolated from an application or its forms, lost in space or by the screen of a monitor?

Isn't it more obvious to just have PopupMenu as an application without any form dependency or what?

Obscure need !!!

Is there an application with this concept in the real world?

Is there any PopupMenu.exe or DLL for practical use?

I think Covid19 is poliformizing itself in an extratospheric sequence ...

Share this post


Link to post
Guest

the @balabuev I already had posts on the Idera forum, of complex and strange characters even to try to visualize where I wanted to go with its programmatic fables ... Let's see where this endeavor is going to go ... if it will lead to something !!!

Share this post


Link to post
20 minutes ago, emailx45 said:

Why would anyone want to have a PopUpMenu isolated from an application or its forms

All your messages in this topic are completely unrelated to what I'm speaking about, sorry...

Edited by balabuev

Share this post


Link to post
Guest

i think so... maybe you too?

Share this post


Link to post
Guest

present some pratice!

some code if exist

Share this post


Link to post

Here's a thought--take a screenshot and look for the mouse cursor? 

 

In the long past  screen captures may had a cursor captured in it.  Would cause great confusion with the running cursor. So the big G himself washes the imaged cursor out so you don't have too!:classic_biggrin:

 

Not exactly your question asked but a large part of why focus on active window is best.    

Share this post


Link to post
Guest

this, died on the "born",  say ... on the bay

:classic_biggrin:

Edited by Guest

Share this post


Link to post
17 minutes ago, Pat Foley said:

Not exactly your question asked but a large part of why focus on active window is best.

This is more a technical discussion. Every idea can be potentially used to confuse the user. So, the original question is simple: whether it is possible or not.

 

However, if you trying to speak about conceptual side, can you explain, why native Windows combo-box control violates this "best" way (as I already noted in one of previous messages). As well, as popup menu.

Edited by balabuev

Share this post


Link to post

I noticed that f.x. Paint.NET has the desired behaviour - and respects the Windows theme. 

Is it still possible to use something like those old-school "spy" programs to see the window class and attributes of the tool windows, to see if anything stands out - or should we assume that it is all done with custom message responses and/or custom paints? None of these have controls with dropdowns or inputs, though - as those are on the toolbar.  Not sure if that is coincidental or a design necessity.

image.thumb.png.c9f3744a6f3a21fb9bfb9d7db7a3bdf7.png

 

It also paints the captions alike when not focused.

image.thumb.png.72fd4fb1b5e07d2b1bd1c2b2341f5e7a.png

Share this post


Link to post

Photoshop also have such behavior:

 

image.thumb.png.64f497a81d000ba400f3d6d68c5d2964.png

 

Photoshop does not respect theme colors, but this is not big deal. I'm sure that Paint.NET (just like Photoshop) - are just a custom drawn non-client area of the main form. Which is fine - this seems to be the closest possible solution.

 

And - good idea about "spy" tool to realize what really happens. I thought about it yesterday too...

 

Also, I want to duplicate my simple code, cause it was hidden by other messages. It allows to keep impression that the form is always "active", even if the user clicked on another form or application. So, this way can be used to "simulate" what I need:

 

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;

 

The code works even with standard forms, without the need to custom draw form's non-client area. Also, system shadow around the form, which is slightly different in active and non-active states, is respected.

Edited by balabuev
  • Like 1

Share this post


Link to post

Using a timer and two edits on a form I've created small tool (which is not full featured "spy", of course):

 

procedure TForm11.Timer1Timer(Sender: TObject);
var
  awn: HWND;
  buf: array[0..1024] of Char;
begin
  awn := GetForegroundWindow;
  if awn <> 0 then
  begin
    GetClassName(awn, @buf, Length(buf));
    Edit1.Text := buf;
  end
  else
    Edit1.Text := '';
  Edit2.Text := IntToHex(awn, 8);
end;

 

So, clicking on different forms in Photoshop gives the following results:

 

872251274__2021-01-05_111324.thumb.png.e68100dd81cd82d547c242851f315faf.png

 

1) "Photoshop".

2) "OWL.Dock".

 

So, the conclusion: active window is changed to follow real focus, and so, main form just "simulates" its pseudo-active state.

 

I've also checked Paint.NET - same results.

  • Like 1

Share this post


Link to post

There's a difference between focus and select. To help with combobox these bits should help.  the Memo stuff 

only provides hints of selecting for your combobox

 

//CB Recipe seasoning 
Procedure TG1.SelectMemoLine(Memo : TCustomMemo) ;
Var
  LineNumber : Integer;
Begin
  LineNumber := Memo.Perform(EM_LINEFROMCHAR, Memo.SelStart, 0);
  Memo.SelStart := Memo.Perform(EM_LINEINDEX, LineNumber, 0);
  Memo.SelLength := Length(Memo.Lines[LineNumber]) ;
  Memo.SetFocus;
  ...

//CB dropdown freshened in the form  
procedure TfrmdrawFocused.remoteCBDropDown(Sender: TObject);
begin
  remoteCB.Items := myLines; 
end;

  ... 
//CB text freshened with timer or update from mainform  
remoteCB.Text := referenced editbox.text from other form.  
remoteCB.Invalidate; 

 

Edited by Pat Foley
type

Share this post


Link to post
15 minutes ago, Pat Foley said:

There's a difference between focus and select. To help with combobox these bits should help.  the Memo stuff 

only provides hints of selecting for your combobox

Can you be more descriptive? I cannot understand what you want to say?..

Share this post


Link to post
Quote

Can you be more descriptive? I cannot understand what you want to say?..

The combo box (CB) should only be used as a viewer. To set up a CB viewer do this  

This scheme lets simple Tform, TStrings, {String} to allow code reuse. 

{String} Is commented out untried but someLines will show current memo lines readily.

 

the memo.sel is not needed here. presented simply to provide message flag to find

its sisters in the source.     

in TfrmdrawFocused
...
  myLines: Tstrings;
  myCBtext: String;
..
procedure TfrmdrawFocused.IniZ(anOwnerForm: TForm;var someLines: Tstrings; {aText: string});
begin
  Application.CreateForm(TfrmdrawFocused, UF);
    with UF do begin
                   mylines := someLines;
                   {myCBtext := AText} 
                  // remoteCB.Items := someLines; does not work needs freshened 
                   {remoterCB.Text := aText}
                   name := 'UF' + Screen.FormCount.ToString;
                   Caption := name;
                   setbounds(10,20,360,270);
                   toFocusAhead := anOwnerForm;
                   onclick := ForwardFocus;
                   onmousedown := nil;
                   onmouseMove := anOwnerform.OnMouseMove;
                   Color := $1E69D2;
                   show;
                 end;
end;

ple 

Edited by Pat Foley
add code example

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

×