Entwickler-Ecke

Windows API - Vollbildmodus wechseln mit Non-VCL


Andreas Pfau - So 07.12.03 01:21
Titel: Vollbildmodus wechseln mit Non-VCL
Hallo,

ich will eine OpenGL-Anwendung sowohl normal als auch im Vollbildmodus laufen lassen, das Fenster habe ich ohne VCL erstellt.

Was für'n Code nehme ich da?


Ich habe da auch schon folgenden Code entwickelt, villeicht könnt ihr ja den so modifizieren, dass er tut:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
procedure ResizeWindow(Fullscreen: Boolean; Width, Height, Left, Top: Integer);
begin
  if (Window <> 0then
  begin
    if (Fullscreen) then
    begin
      WinFullscreen := True;

      WinWidth  := GetScreenWidth;
      WinHeight := GetScreenHeight;
      OuterWidth := WinWidth;
      OuterHeight := WinHeight;
      WinLeft := 0;
      WinTop := 0;

      // Fensterrahmen entfernen
      SetWindowLong(Window, GWL_STYLE,   Integer(WS_POPUP or WS_SYSMENU or WS_MINIMIZEBOX));
      SetWindowLong(Window, GWL_EXSTYLE, Integer(WS_EX_APPWINDOW));
    end
    else
    begin
      WinFullscreen := False;


      WinWidth  := Width;
      WinHeight := Height;

      if (WinWidth <= 0then
        WinWidth := 400;
      if (WinHeight <= 0then
        WinHeight := 400;

      OuterWidth  := WinWidth  + GetWindowBorderX;
      OuterHeight := WinHeight + GetWindowBorderY;

      WinLeft := Left;
      WinTop  := Left;

      // Fenster zentrieren
      if (WinLeft < 0then
        WinLeft := (GetScreenWidth - OuterWidth) div 2;
      if (WinTop < 0then
        WinTop := (GetScreenHeight - OuterHeight) div 2;

      // Fensterrahmen hinzufügen
      SetWindowLong(Window, GWL_STYLE,   Integer(WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX));
      SetWindowLong(Window, GWL_EXSTYLE, Integer(WS_EX_APPWINDOW or WS_EX_WINDOWEDGE));
    end;

    SetWindowPos(Window, 00000, SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or SWP_FRAMECHANGED);
    SetWindowPos(Window, 0, WinLeft, WinTop, OuterWidth, OuterHeight, 0);
    ShowWindow(Window, SW_SHOW);
  end;
end;

"Window" ist das Fensterhandle. Wenn ich vom Fenster-Modus in Vollbild wechsle ist alles OK, erst wenn ic hzurück will kommt's: Das Fenster wird zwar angezeigt, aber der Hintergrund bleibt (also das alte Fenster bleibt sichtbar). Wei kann ich Windows dazu zwingen, Den kompletten Bildschirm neu zu zeichnen? Habe das shcon iniges porbiert...


jaenicke - Mo 15.12.03 13:13
Titel: Systemereignis schicken
Hallo!

Also um ein neuzeichnen des Bildschirms zu veranlassen, kannst Du WM_PAINT an das Handle des Desktops schicken (frag mich jetzt im Moment nicht, wie das geht... :( ), alternativ, wenn Du das auch nicht weißt, kannst Du die Botschaft mit HWND_BROADCAST an alle Fenster schicken.

Und die Notlösung: Explorerfenster mit CreateProcess öffnen (mit maximized öffnen) und gleich wieder mit WM_QUIT schließen (das Handle ist ja bekannt für die Botschaftssendung).

Nach dem Handle für den Desktop muss ich mal suchen. Du könntest z.B. mal mit Spy++ nach dem Namen des Desktop-Fensters suchen.
(Dann kann einfach mit FindWindow das Fenster in Delphi erreicht werden.)

Viel Erfolg,
S.J.


Delete - Mo 15.12.03 14:33
Titel: Re: Systemereignis schicken
jaenicke hat folgendes geschrieben:

Also um ein neuzeichnen des Bildschirms zu veranlassen, kannst Du WM_PAINT an das Handle des Desktops schicken (frag mich jetzt im Moment nicht, wie das geht... :( ), alternativ, wenn Du das auch nicht weißt, kannst Du die Botschaft mit HWND_BROADCAST an alle Fenster schicken.

Nun ja. Könnte klappen.
Zitat:

Und die Notlösung: Explorerfenster mit CreateProcess öffnen (mit maximized öffnen) und gleich wieder mit WM_QUIT schließen (das Handle ist ja bekannt für die Botschaftssendung).

Grusel. Da wird mir ganz anders, wen ich mir vorstelle einige Free- und Shareware Autoren, deren Software ich benutze, könnte ähnlich programmieren. :roll: *schüttel* *luckie, der ganz schnell an was anderes denkt*
Zitat:

Viel Erfolg,

Hoffentlich nicht so.

Kuckt dir mal InvalidateRect an. Das sollte ein Fenster zum neuzeichen veranlassen.


Andreas Pfau - Mo 15.12.03 20:02

Hallo,

danke für die Tipps! Mittlerweile habe ich selber einen Weg gefunden:

Delphi-Quelltext
1:
2:
PostMessage(HWND_BROADCAST, WM_PAINT, 00);
PostMessage(HWND_BROADCAST, WM_NCPAINT, 00);

Aber @Luckie, deitn Tipp mit InvalidateRect() ist noch zuverlässiger! Danke!!! :D


G-man - Di 16.12.03 18:03

Du kannst mit Directx dein Fenster auch auf den Fullscreenmode bringen...


Andreas Pfau - Di 16.12.03 20:15

Hallo,

ja, das ginge, aber dann könnte ich ja gleich Direct3D coden. Aber ich bin OpenGL-Fan, und wenn alle Fenster korrekt neu gezeichnet werden, ist's mir recht. Trotzdem danke für deine Mitarbeit :D