Autor Beitrag
M. Raab
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 334
Erhaltene Danke: 1

WIN 7
Delphi XE
BeitragVerfasst: Do 09.01.03 17:20 
Hallo NG,

ich habe schon mal über mein Problem mit dem WINDOW finden berichtet. Nun ein weiteres Problem:

ausblenden volle Höhe 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:
procedure glKillWnd(Fullscreen : Boolean);
begin
  if Fullscreen then begin            // Wenn Vollbild in Standardauflösung zurückkehren
    ChangeDisplaySettings(devmode(nil^), 0);
    ShowCursor(True);
  end;

  // Freigabe des Device und Rendering Contexts.
  if (not wglMakeCurrent(h_DC, 0)) then
    MessageBox(0, 'Release of DC and RC failed!', 'Error', MB_OK or MB_ICONERROR);

  // Löscht Rendering Context
  if (not wglDeleteContext(h_RC)) then begin
    MessageBox(0, 'Release of rendering context failed!', 'Error', MB_OK or MB_ICONERROR);
    h_RC := 0;
  end;

  // Gibt Device Context fre
  if ((h_DC > 0) and (ReleaseDC(h_Wnd, h_DC) = 0)) then  begin
    MessageBox(0, 'Release of device context failed!', 'Error', MB_OK or MB_ICONERROR);
    h_DC := 0;
  end;

  // Schließt das Fenster
  if ((h_Wnd <> 0) and (not DestroyWindow(h_Wnd))) then begin
    MessageBox(0, 'Unable to destroy window!', 'Error', MB_OK or MB_ICONERROR);
    h_Wnd := 0;
  end;

  // Entfernt window class Registrierung
  if (not UnRegisterClass('OpenGL', hInstance)) then begin
    MessageBox(0, 'Unable to unregister window class!', 'Error', MB_OK or MB_ICONERROR);
    hInstance := 0;
  end;
end;


Mit obigen Code schließe ich das von mir erzeugte Fenster. Mit folgender Funktion öffne ich es:

ausblenden volle Höhe 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:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
function glCreateWnd(Width, Height : Integer; Fullscreen : Boolean; PixelDepth : Integer) : Boolean;
var
  wndClass : TWndClass;         // Fenster Klasse
  dwStyle : DWORD;              // Fenster Stil
  dwExStyle : DWORD;            // Erweiterter Fenster Stil
  dmScreenSettings : DEVMODE;   // Bildschirm Einstellungen (fullscreen, etc...)
  PixelFormat : GLuint;         // OpenGL Einstellungen (Pixelformat)
  h_Instance : HINST;           // aktuelle Instanz
  pfd : TPIXELFORMATDESCRIPTOR;  // Einstellungen für das OpenGL Fenster
begin
  h_Instance := GetModuleHandle(nil);       // Instanz für's Fenster holen
  ZeroMemory(@wndClass, SizeOf(wndClass));  // Daten in wndClass löschen

  with wndClass do                    // Setup der Fenster Klasse
  begin
    style         := CS_HREDRAW or    // Neuzeichenen wenn Fenster-Breite geändert
                     CS_VREDRAW or    // Neuzeichenen wenn Fenster-Höhe geändert
                     CS_OWNDC;        // Device Context exlusiv
    lpfnWndProc   := @WndProc;        // WndProc wird als Window Procedure gesetzt
    hInstance     := h_Instance;
    hCursor       := LoadCursor(0, IDC_ARROW);
    lpszClassName := 'OpenGL';
  end;

  if (RegisterClass(wndClass) = 0) then  // Fenster Klasse registrieren
  begin
    MessageBox(0, 'Failed to register the window class!', 'Error', MB_OK or MB_ICONERROR);
    Result := False;
    Exit
  end;

  // Vollbild wenn Parameter Fullscreen = true
  if Fullscreen then
  begin
    ZeroMemory(@dmScreenSettings, SizeOf(dmScreenSettings));
    with dmScreenSettings do begin              // Bildschirm Einstellungen werden festgelegt
      dmSize       := SizeOf(dmScreenSettings);
      dmPelsWidth  := Width;                    // Fenster Breite
      dmPelsHeight := Height;                   // Fenster Höhe
      dmBitsPerPel := PixelDepth;               // Farbtiefe (32bit etc)
      dmFields     := DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL;
    end;

    // Bilschirm Modus auf Vollbild setzen
    if (ChangeDisplaySettings(dmScreenSettings, CDS_FULLSCREEN) = DISP_CHANGE_FAILED) then
    begin
      MessageBox(0, 'Unable to switch to fullscreen!', 'Error', MB_OK or MB_ICONERROR);
      Fullscreen := False;
    end;
  end;

  // Wenn wir immer noch im Vollbildmodus sind....
  if (Fullscreen) then
  begin
    dwStyle := WS_POPUP or                // Popup Fenster Stil
               WS_CLIPCHILDREN            // Kein Zeichnen in Child Fenstern
               or WS_CLIPSIBLINGS;        // Kein Zeichnen in Sibling Fenstern
    dwExStyle := WS_EX_APPWINDOW;         // Fenster im Vordergrund
    ShowCursor(False);                    // Mauszeiger verstecken
  end
  else // Für Normale Fenster
  begin
    dwStyle := WS_OVERLAPPEDWINDOW or     // Überschneidung zulassen
               WS_CLIPCHILDREN or         // Kein Zeichnen in Child Fenstern
               WS_CLIPSIBLINGS;           // Kein Zeichnen in Sibling Fenstern
    dwExStyle := WS_EX_APPWINDOW or       // Fenster im Fordergrund
                 WS_EX_WINDOWEDGE;        // Erhobener Rand
  end;

  // Das oben definierte Fenster wird erstellt
  h_Wnd := CreateWindowEx(dwExStyle,      // Erweiterter Fenster Stil
                          'OpenGL',       // Name der Klasse
                          WND_TITLE,      // Fenster Titel (caption)
                          dwStyle,        // Fenster Stil
                          0, 0,           // Fenster Position
                          Width, Height,  // Größe des Fensters
                          0,              // Keine Paren-Windows
                          0,              // Kein Menü
                          h_Instance,     // die Instanz
                          nil);           // Kein Parameter für WM_CREATE
  if h_Wnd = 0 then
  begin
    glKillWnd(Fullscreen);
    MessageBox(0, 'Unable to create window!', 'Error', MB_OK or MB_ICONERROR);
    Result := False;
    Exit;
  end;

  // Den Device Kontext unseres Fensters besorgen
  h_DC := GetDC(h_Wnd);
  if (h_DC = 0) then
  begin
    glKillWnd(Fullscreen);
    MessageBox(0, 'Unable to get a device context!', 'Error', MB_OK or MB_ICONERROR);
    Result := False;
    Exit;
  end;

  // Das Pixelformat einstellen
  with pfd do
  begin
    nSize           := SizeOf(TPIXELFORMATDESCRIPTOR); // Größe des Pixel Format Descriptor
    nVersion        := 1;                    // Version des Daten Structs
    dwFlags         := PFD_DRAW_TO_WINDOW    // Buffer erlaubt zeichenen auf Fenster
                       or PFD_SUPPORT_OPENGL // Buffer unterstützt OpenGL drawing
                       or PFD_DOUBLEBUFFER;  // Double Buffering benutzen
    iPixelType      := PFD_TYPE_RGBA;        // RGBA Farbformat
    cColorBits      := PixelDepth;           // OpenGL Farbtiefe
    cRedBits        := 0;
    cRedShift       := 0;
    cGreenBits      := 0;
    cGreenShift     := 0;
    cBlueBits       := 0;
    cBlueShift      := 0;
    cAlphaBits      := 0;                    // Not supported
    cAlphaShift     := 0;                    // Not supported
    cAccumBits      := 0;                    // Kein Accumulation Buffer
    cAccumRedBits   := 0;
    cAccumGreenBits := 0;
    cAccumBlueBits  := 0;
    cAccumAlphaBits := 0;
    cDepthBits      := 16;                   // Genauigkeit des Depht-Buffers
    cStencilBits    := 0;                    // Stencil Buffer ausschalten
    cAuxBuffers     := 0;                    // Not supported
    iLayerType      := PFD_MAIN_PLANE;       // Wird Ignoriert!
    bReserved       := 0;                    // Anzahl der Overlay und Underlay Planes
    dwLayerMask     := 0;                    // Wird Ignoriert!
    dwVisibleMask   := 0;                    // Transparente Farbe der Underlay Plane
    dwDamageMask    := 0;                    // Wird Ignoriert!
  end;

  // Gibt ein unterstützes Pixelformat zurück das dem geforderten so gut wie möglich enspricht
  PixelFormat := ChoosePixelFormat(h_DC, @pfd);
  if (PixelFormat = 0) then
  begin
    glKillWnd(Fullscreen);
    MessageBox(0, 'Unable to find a suitable pixel format', 'Error', MB_OK or MB_ICONERROR);
    Result := False;
    Exit;
  end;

  // Das Pixelformat unseres Device Kontexts wird durch das neue ersetzt
  if (not SetPixelFormat(h_DC, PixelFormat, @pfd)) then
  begin
    glKillWnd(Fullscreen);
    MessageBox(0, 'Unable to set the pixel format', 'Error', MB_OK or MB_ICONERROR);
    Result := False;
    Exit;
  end;

  // OpenGL Rendering Context wird erstellt
  h_RC := wglCreateContext(h_DC);
  if (h_RC = 0) then
  begin
    glKillWnd(Fullscreen);
    MessageBox(0, 'Unable to create an OpenGL rendering context', 'Error', MB_OK or MB_ICONERROR);
    Result := False;
    Exit;
  end;

  // Der OpenGL Rendering Context wird aktiviert
  if (not wglMakeCurrent(h_DC, h_RC)) then
  begin
    glKillWnd(Fullscreen);
    MessageBox(0, 'Unable to activate OpenGL rendering context', 'Error', MB_OK or MB_ICONERROR);
    Result := False;
    Exit;
  end;

  // Initialisierung des Timers zur FPS-Berechnung
  SetTimer(h_Wnd, FPS_TIMER, FPS_INTERVAL, nil);

  // Das Fenster wird in Vordergrund gebracht
  ShowWindow(h_Wnd, SW_SHOW);
  SetForegroundWindow(h_Wnd);
  SetFocus(h_Wnd);

  // Das Fenster bekommt nochmal die Größe zugewiesen um OpenGl richtig zu initialisieren
  glResizeWnd(Width, Height);
  glInit();

  Result := True;
end;


Das Problem nun: schließe ich das Fenster mit glKillWnd(false) und öffne es dann wieder, kommt meine Fehlermeldung:
MessageBox(0, 'Failed to register the window class!', 'Error', MB_OK or
Irgendiwe wird die Klasse nicht gelöscht.

Kann jemand helfen ? Was mache ich falsch ?

Gruss

Markus
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Sa 25.01.03 18:30 
Ich bin auf dem Gebiet kein Experte, aber ich vermute stark, dass die Prozedur WinMain() nur einmal pro Klasse verwendet werden kann, order irgendwie so.

Probier mal, nur das Window zu löschen, aber die Klasse beizubehalten, und mit der alten Klasse ein neues Fenster zu srstellen.
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Sa 25.01.03 19:23 
Ändere deinen Code mal so um:
ausblenden 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:
function glCreateWnd(Width, Height : Integer; Fullscreen : Boolean; PixelDepth : Integer) : Boolean; 
...
begin
  h_Instance := GetModuleHandle(nil);       // Instanz für's Fenster holen 
  ZeroMemory(@wndClass, SizeOf(wndClass));  // Daten in wndClass löschen 
  if not GetClassInfo(h_Instance, 'Open GL', wndClass) then
  begin
    // Klasse muss erst registriert werden

    with wndClass do                    // Setup der Fenster Klasse 
    begin 
      style         := CS_HREDRAW or    // Neuzeichenen wenn Fenster-Breite geändert 
                       CS_VREDRAW or    // Neuzeichenen wenn Fenster-Höhe geändert 
                       CS_OWNDC;        // Device Context exlusiv 
      lpfnWndProc   := @WndProc;        // WndProc wird als Window Procedure gesetzt 
      hInstance     := h_Instance; 
      hCursor       := LoadCursor(0, IDC_ARROW); 
      lpszClassName := 'OpenGL'; 
    end; 

    if (RegisterClass(wndClass) = 0) then  // Fenster Klasse registrieren 
    begin 
      MessageBox(0, 'Failed to register the window class!', 'Error', MB_OK or MB_ICONERROR); 
      Result := False; 
      Exit 
    end; 
  end; // else Klasse ist bereits registriert
...

_________________
Ist Zeit wirklich Geld?