Forum > LCL

How to show form w/out focusing it?

<< < (2/3) > >>

Arioch:
Remember, which form had focus, then show your form, then show that prior form to make it have the focus back

zamtmn:

--- Quote from: Arioch on September 26, 2022, 03:52:37 pm ---Remember, which form had focus, then show your form, then show that prior form to make it have the focus back

--- End quote ---
It doesn't work well. Main form title has time to blink due to the loss of focus. I need such forms for toolbars and, for example, TMyComboBox implementations

Arioch:
At least on Windows/Native there is precious little you can do

the best would be, in LCL terms,

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---    NewForm.PopupMode := pmAuto;    NewForm.Visible := True;    OldForm.SetFocus; 
Still flickers with caption, but not for long.


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---    NewForm.PopupParent := OldForm;    NewForm.WindowState := wsMinimized;    NewForm.Visible := True;    NewForm.WindowState := wsNormal;    OldForm.SetFocus; 
This makes new form smoothly slide up, and this animation steald user attentioon, so he does not see the flicker :-)

To get it flicker-less LCL (with all the toolkits) has to be refactored so that showing and activating (getting focus) would be decoupled and TWSWinControlClass(WidgetSetClass).ShowHide(Self); either would have some flags, which of the two functions to skip.
Or should only do non-activating showing and to have an extra explicit call to SetFocus requires. Which, maybe, would cause new form flickering instead.

This probably also makes docking libraries in LCL problematic...

At least on Windows/Native the process of showing goes down to


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---class procedure TWin32WSCustomForm.ShowHide(const AWinControl: TWinControl);const  WindowStateToFlags: array[TWindowState] of DWord = ( { wsNormal     } SW_SHOWNORMAL, // to restore from minimzed/maximized we need to use SW_SHOWNORMAL instead of SW_SHOW { wsMinimized  } SW_SHOWMINIMIZED, { wsMaximized  } SW_SHOWMAXIMIZED, { wsFullScreen } SW_SHOWMAXIMIZED  // win32 has no fullscreen window state  );var  Flags: DWord;begin  if AWinControl.HandleObjectShouldBeVisible then  begin    Flags := WindowStateToFlags[TCustomForm(AWinControl).WindowState];    Windows.ShowWindow(AWinControl.Handle, Flags); 
it gets called from


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TWinControl.CMShowingChanged(var Message: TLMessage);begin  {$IFDEF VerboseShowing}  DebugLn(['TWinControl.CMShowingChanged ',DbgSName(Self),' HandleAllocated=',HandleAllocated,' ',dbgs(ComponentState)]);  {$ENDIF}  if HandleAllocated and ([csDestroying,csLoading]*ComponentState=[]) then    DoSendShowHideToInterface  else    Exclude(FWinControlFlags, wcfHandleVisible);end; .... procedure TWinControl.DoSendShowHideToInterface;...    TWSWinControlClass(WidgetSetClass).ShowHide(Self); 
Microsoft: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow

Falgs you need are either SW_SHOWNOACTIVATE or SW_SHOWNA

But TWin32WSCustomForm.ShowHide - does not have any,

Despite right above there is


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---class procedure TWin32WSCustomForm.SetShowInTaskbar(const AForm: TCustomForm;  const AValue: TShowInTaskbar); .....   // now we need to restore window visibility with saving focus  if Visible then    if Active then      ShowWindow(AForm.Handle, SW_SHOW)    else      ShowWindow(AForm.Handle, SW_SHOWNA);end; 
you can not work-arount it bypassing LCL like


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---       NeewForm.PopupMode := pmAuto;   Windows.ShowWindow( NewForm.Handle, SW_SHOWNA ); 
Doing so you would get dead empty window then as LCL only puts behavior and widgets to the window during its first-time showing and activation.


On Delphi/VCL/Windows it is not possible normally too, but there is a hack (not working in LCL)

https://stackoverflow.com/questions/700698/delphi-show-window-without-activation
https://stackoverflow.com/questions/20548321/how-can-i-make-a-form-visible-and-maximize-it-to-fill-a-secondary-monitor-withou

KodeZwerg:
On windows this works.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.Button1Click(Sender: TObject);begin  Form2.Show;  Self.SetFocus;end;

Arioch:
That's what i told above.


--- Quote from: Arioch on September 26, 2022, 03:52:37 pm ---Remember, which form had focus, then show your form, then show that prior form to make it have the focus back

--- End quote ---

But this indeed makes Form1 flicker the captionbar. Not sure how much a problem that is. But the Delphi discusisons imply that is indeed.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version