Rückkehr von wsFullScreen zu wsNormal hakt

Für Fragen von Einsteigern und Programmieranfängern...
cle
Beiträge: 30
Registriert: Mi 31. Jan 2018, 11:54
OS, Lazarus, FPC: Winux (L trunc FPC 3.3.1)
CPU-Target: 64Bit

Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von cle »

Moin,

ich würde gern ein Programm in den Fullscreen Modus und wieder zurück wechseln können. In den Fullscreen funktioniert das auch tadellos, um zurück zu wsNormal zu kommen muß ich in folgendem Beispiel allerdings zwei Mal auf den Button klicken. Im Label wird korrekt (aber eben zwei Mal hintereinander) WindowState = wsFullScreen als True angezeigt (Linux 64, gtk2):

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  if WindowState = wsFullScreen then WindowState := wsNormal else WindowState := wsFullScreen;
  Label1.Caption := BoolToStr(WindowState = wsFullScreen, true);
end
 


Kann sich jemand erklären, woran es hakt?
Beispielprogramm habe ich angehängt.

Alex
Dateianhänge
Test.zip
(127.95 KiB) 29-mal heruntergeladen

Mathias
Beiträge: 4899
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von Mathias »

Sieht fast so aus, wie du gerade ein Bug gefunden hast.

Mit einem 2, button geht es auf diese weise.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  WindowState := wsFullScreen;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  WindowState := wsFullScreen;
  WindowState := wsNormal;
end


Mache ich es aber so, dann kann ich mir den Finger am Button2 wund klicken.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  WindowState := wsFullScreen;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  WindowState := wsNormal;
end;

Ausser klicke ich mal zwischen auf den Button1, dann reagiert Button2 vielleicht später.

PS: Egal ob 1.8.4 oder Trunk, das Problem besteht bei beiden Versionen.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

siro
Beiträge: 386
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von siro »

Auf meinem Windows 10 Rechner mit Lazarus 1.8.0RC4 läuft es einwandfrei.
Auf meinem Windows 8.1 Rechner mit Lazarus 1.8.2 funktioniert es auch richtig.
Windows 10 mit Lazarus 1.8.4 geht auch

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

sstvmaster
Beiträge: 342
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: OS: Windows 10 | Lazarus: 2.0.8 + Fixes + Trunk 32bit
CPU-Target: 32Bit
Wohnort: Dresden

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von sstvmaster »

Windows 7, 32bit, 1.8.4 + Trunk 3.3.1 / 58751 funktioniert auch
LG Maik

wp_xyz
Beiträge: 3264
Registriert: Fr 8. Apr 2011, 09:01

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von wp_xyz »

Seltsam: Win 10 / Laz-trunk + fpc 3.0.4 funktioniert nicht, genauso wenig wie Win 10 / Laz 1.8.4 + fpc 3.0.4 und Win 7 / Laz trunk + fpc 3.0.4.

Ihr probiert schon das im 1.Post hochgeladene Test-Programm mit wsFullScreen aus (nicht wsMaximized, denn dieses funktioniert)?

siro
Beiträge: 386
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von siro »

Erneuter Test auf dem Firmenrechner:

Windows 7
Lazarus 1.8.2

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  WindowState := wsFullScreen;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  WindowState := wsNormal;
end;       
 


funktioniert einwandfrei

[edit]
Das angehängte Programm geht nicht.

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

wp_xyz
Beiträge: 3264
Registriert: Fr 8. Apr 2011, 09:01

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von wp_xyz »

siro hat geschrieben:Erneuter Test auf dem Firmenrechner:

Windows 7
Lazarus 1.8.2

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  WindowState := wsFullScreen;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  WindowState := wsNormal;
end;       
 

Also doch ein anderes Programm. Ich rede vom Programm, das cle ganz oben gepostet hat. Mit zwei getrennten Buttons funktioniert es auch bei mir. Und auch das alternative Hinundherschalten durch denselben Button (so wie in dem Demo-Programm) funktioniert, aber nur wenn die Bedingung umgedreht wird. Also:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  if WindowState = wsNormal then WindowState := wsFullScreen else WindowState := wsNormal;  // --> FUNKTIONIERT
  if WindowState = wsFullScreen then WindowState := wsNormal else WindowState := wsFullScreen;  // --> FUNKTIONIERT NICHT
end;

Absolut mysteriös.

siro
Beiträge: 386
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von siro »

Hab grad mal nen Breakpoint gesetzt:

Es wird im Programmlauf erstaunlicherweise zwei mal wsFullScreen
an die procedure TCustomForm.SetWindowState(Value : TWindowState);
übergeben.

jedoch nur einmal wsNormal

ordinalzahl WindowState ändert sich wie folgt:
0 wsNormal
2 wsMaximized
3 wsFullScreen
0 wsNormal
2 wsMaximized
3 wsFullScreen
Zuletzt geändert von siro am Mo 27. Aug 2018, 09:48, insgesamt 1-mal geändert.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

sstvmaster
Beiträge: 342
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: OS: Windows 10 | Lazarus: 2.0.8 + Fixes + Trunk 32bit
CPU-Target: 32Bit
Wohnort: Dresden

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von sstvmaster »

@wp_xyz
Stimmt hast Recht, ich habe auch den Fehler gemacht und das Beispiel mit 2 Buttons genommen und nicht das von cle.

Ergo das von cle geht nicht. Mit der Änderung von wp_xyz gehts.

Sorry
LG Maik

siro
Beiträge: 386
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von siro »

man setzt wsFullScreen (3)
danach steht WindowState aber erstaunlicherweise auf
wsMaximized (2)
dann stimmt natürlich die Abfrage nicht mehr.....


Schuld ist die Procedure
ShowWindow(Handle, ShowCommands[Value]);
in der Unit CustomForm.inc

Code: Alles auswählen

procedure TCustomForm.SetWindowState(Value : TWindowState);
const
  ShowCommands: array[TWindowState] of Integer =
    (SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED, SW_SHOWFULLSCREEN);
begin
  if FWindowState <> Value then
  begin
    FWindowState := Value;
    //DebugLn(['TCustomForm.SetWindowState ',DbgSName(Self),' ',ord(FWindowState),' csDesigning=',csDesigning in ComponentState,' Showing=',Showing]);
    if (not (csDesigning in ComponentState)) and Showing then
      ShowWindow(Handle, ShowCommands[Value]);        // H I E R passiert es
  end;
end;   
 


hier wird WindowState irgendwie umgesetzt.

Vor dem Aufruf von ShowWindow ist WindowState noch wsFullScreen
nach dem Aufruf ist WindowState dann wsMaximized



weitere Recherche:
function ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;
begin
Result := WidgetSet.ShowWindow(hWnd,nCmdShow);
end;


bei wsFullScreen wird an Widget.ShowWindow
nCmdShow = 11
übergeben

dann wird
TWin32WidgetSet.ShowWindow
aufgerufen und hier steht folgendes:

Code: Alles auswählen

function TWin32WidgetSet.ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;
begin
  if nCmdShow = SW_SHOWFULLSCREEN then         // hier passiert dann die Umsetzung
    nCmdShow := SW_SHOWMAXIMIZED;
  Result := Boolean(Windows.ShowWindow(hWnd, nCmdShow));
end;       
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

sstvmaster
Beiträge: 342
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: OS: Windows 10 | Lazarus: 2.0.8 + Fixes + Trunk 32bit
CPU-Target: 32Bit
Wohnort: Dresden

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von sstvmaster »

Hat das was mit dieser Funktion zu tun?

Code: Alles auswählen

function TWin32WidgetSet.ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;
begin
  if nCmdShow = SW_SHOWFULLSCREEN then
    nCmdShow := SW_SHOWMAXIMIZED;
  Result := Boolean(Windows.ShowWindow(hWnd, nCmdShow));
end;


win32winapi.inc / 3417 - 3428

Auch vorhanden in den gtk2,gtk3, carbon... winapi.inc

Code: Alles auswählen

Windows.ShowWindow(hWnd, nCmdShow)


ist in der func,inc 438 deklariert?

Code: Alles auswählen

function ShowWindow(hWnd:HWND; nCmdShow:longint):WINBOOL; external 'user32' name 'ShowWindow';
LG Maik

cle
Beiträge: 30
Registriert: Mi 31. Jan 2018, 11:54
OS, Lazarus, FPC: Winux (L trunc FPC 3.3.1)
CPU-Target: 64Bit

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von cle »

Ich wollte mich gerade daran machen, einen Bugreport zu schreiben, aber inzwischen ist hier ja einiges passiert.
Insofern sage ich zumindest mal Danke, dass ihr da tiefer reinschaut.

siro
Beiträge: 386
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von siro »

die momentan beste Lösung ist die von wp_xyz
einfach die Abfrage umdrehen:

Code: Alles auswählen

if WindowState = wsNormal then WindowState := wsFullScreen else WindowState := wsNormal;


weil wsNormal stimmt immer.

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Warf
Beiträge: 1438
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von Warf »

Der windowstate maximized ist kein Teil der Windows Forms API, sondern wird simuliert indem man den borderstyle auf None setzt und danach den Window State auf maximized. Anscheinend wurde das in Lazarus mit der Einführung von wsfullscreen nicht korrekt implementiert, und die unterliegende Implementierung von wsMaximized kommt durch

cle
Beiträge: 30
Registriert: Mi 31. Jan 2018, 11:54
OS, Lazarus, FPC: Winux (L trunc FPC 3.3.1)
CPU-Target: 64Bit

Re: Rückkehr von wsFullScreen zu wsNormal hakt

Beitrag von cle »

Wenn man das Testprogramm zuerst mit Systemmitteln maximiert, letztendlich also ein Wechsel zwischen wsMaximized und wsFullScreen, funktioniert es übrigens auch reibungslos.

Antworten