Warum wird das Fenster nicht angezeigt?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Warum wird das Fenster nicht angezeigt?

Beitrag von thosch »

Hallo,

ich probiere gerade eine Grafikbibliothek aus und steh auf dem sprichwörtlichen Schlauch. Ich poste das Problem dennoch hier, nicht in API & Plattformspezifisches. Weil es wahrscheinlich mit der Bibliothek zusammenhängt. Die stellt kein standardmäßiges API für Freepascal dar.

Hier erst mal der Code des Projektes:

Code: Alles auswählen

 
program GFXWinTest;
 
{$mode delphi}{$H+}
 
uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, Sysutils, windows,
 
  mygfxlib //Meine Grafikbibliothek, die ich testen will
 
  { you can add units after this };
 
var mywnd: HWND;
 
function MyWindowProc(wnd: HWND; msg: UINT; w: WPARAM; l: LPARAM): LRESULT; stdcall;
var
  dc: HDC;
  ps: TPaintStruct;
  rr: TRect;
begin
 
  case msg of
    WM_PAINT:
      begin
        dc := BeginPaint(wnd, ps);
 
        GetClientRect(wnd,rr);              //Clientbereich des Fensters ermitteln
 
        Ellipse(dc,100,100,200,200);     //Test, ob Ellipse gezeichnet wird
 
        rr.Left:=4; rr.top := 300;
 
        rr.right := 200; rr.Bottom:=318;
 
        DrawText(dc,PChar('Irgendein Text'),32,rr,DT_LEFT);     //Test, ob der Text erscheint
 
        DrawFocusRect(dc,rr);       //Test, ob das Rechteck gezeichnet wird
 
        EndPaint(wnd,ps);
 
      end;
    WM_QUIT: PostQuitMessage(0);
  end;
  Result := DefWindowProc(wnd,msg,w,l);
end;
 
procedure WinGFXActionProc;
var msg: TMsg;
begin
  //ShowWindow(mywnd, SW_SHOWNORMAL);
 
  if GetMessage(msg,0,0,0) then
  begin
    TranslateMessage(msg);
    DispatchMessage(msg);  //hier External SIGSEGV, wenn ich testhalber für diese 3 Funktionen eigene Versionen schreibe.
        //Im jetzigen Beispiel verwende ich aber die Originale dieser Funktionen,
        //da kommt keine Exception, aber mein Fenster wird nicht angezeigt. Warum ist das so?
  end;
end;
 
procedure WinGFXInitProc;
var
  wc: TWndClassEx; wnd: HWND;
begin
  wc.cbSize          := SizeOf(TWndClassEx);
  wc.Style           := CS_HREDRAW or CS_VREDRAW;
  wc.lpfnWndProc     := @MyWindowProc;
  wc.cbClsExtra      := 0;
  wc.cbWndExtra      := 0;
  wc.lpszMenuName    := nil;
  wc.lpszClassName   := 'Hauptfenster';
  wc.hIconSm         := 0;
 
  RegisterClassEx(wc);
 
  wnd := CreateWindowEx(0,'Hauptfenster','Testanwendung', WS_CAPTION,100,50,800,600,0,0,0,nil);
 
  ShowWindow(wnd{HWND(WindowPtr)}, SW_SHOWNORMAL);
end;
 
begin
  gfxActionProc := @WinGFXActionProc;
  gfxSetupAfterInitProc := @WinGFXInitProc;
  InitGFXSystem(1024,768);
end.
 



Hier noch die Prozedur InitGFXSystem():

Code: Alles auswählen

 
procedure InitGFXSystem(XResolution, YResolution: dword);
begin
 
   //.... einleitender Code, der aber mit meinem Problem wohl nichts zu tun hat
 
  gfxIsInGraphMode:=true;
 
    gfxSetupAfterInitProc;  //Hier registiere ich meine Fensterklasse und will das Fenster letzlich anzeigen
 
  StartFPScounter;
  inc(gfxFrames);
 
  while not gfxDone do begin
 
    if not gfxIsInGraphMode then gfxDone:=true;
 
   if PeekMessage(@gfxAMessage, 0 , 0, 0, PM_REMOVE) then begin  //Wenn Message anliegt, diese Verarbeitung
 
    TranslateMessage(gfxAMessage);
    DispatchMessage(gfxAMessage);
 
   end else begin                                                                            //sonst meine eigene
 
    if gfxUseOpenGL then begin
 
 
      gfxActionProc;   //Hier ist meine eigene Message-Queue-Abfrage drin
 
      if gfxUseMouse then if gfxUseCustomMousePointer then
 
     //.... weiterer Code
 


Wenn ich das Programm starte, erscheint ein Fenster mit schwarzem Hintergrund und dem Mauszeiger. Ich will aber auch mein Fenster anzeigen, was jedoch fehl schlägt. Warum?

Dir Prozedur InitGFXSystem() legt die Grafikauflösung fest und startet nach den nötigen Initialisierungen des Grafiksystems die gfxSetupAfterInitProc, das ist ein Prozedurzeiger, dem ich meine WinGFXInitProc zugewisen habe, damit mein Code aufgerufen wird.

Es gibt noch eine gfxActionProc, einen Procedurzeiger, dem ich meine WinGFXActionProc zugewisen habe.

Erreichen will ich die Anzeige meines Fensters in meinem GFX Grafikfenster. Danach soll meine eigene Messageverarbeitung aus WinGFXAcionProc resp. gfxActionProc verwendet werden.


Ich erhalte aber nur das Grafikfenster mit schwarzem Hintergrund. Aber mein Fenster erscheint nicht.

.

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

Re: Warum wird das Fenster nicht angezeigt?

Beitrag von siro »

Hallo thosch

wnd ist eine Lokale Variable die nach dem Verlassen von WinGFXInitProc verloren geht
Muss die nicht Global sein ?

Probiere mal welchen Wert Dir die Funktion RegisterClassEx zurückgibt, ist es 0 dann ist schon was faul...

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

thosch
Beiträge: 324
Registriert: Mo 10. Jul 2017, 20:32

Re: Warum wird das Fenster nicht angezeigt?

Beitrag von thosch »

Habe ich gemacht:

[code]

var myatom: ATOM;

myatom := RegisterClassEx(wc);

Im Fenter "Überwachte Ausdrücke" ist der Wert vor dem Aufruf 0, nache dem Aufruf <evaluating>. Habe dann Rechtsklick auf dem Wert (Zeile mit dem blauen Cursor auf myatom) gemacht, dort Eigenschaften ausgewählt. Im erscheinenden Fenster dann Anzeige als Dezimalwert ausgewählt und, Oh Schreck, der Wert ist nach Aufruf von RegisterClassEx tatsächlich immer noch gleich 0. Wie kann das sein. Bis da hin habe ich doch mit meiner Grafikbibliothek außer sie zu initialisieren und mein Fenster zu registrieren, noch gar nichts gemacht. RegisterClassEx ist doch eine ganz gewöhnliche Windows API Funktion.

Den Fensterhandle als globale Variable im Hauptprogramm definieren bringt auch nichts.

Was läuft hier falsch?

Die Grafikbibliothek initialisiert ein eigenes Fenster. Aber das Meine sollte doch trotzdem angezeigt werden. Auch wenn ich den Parent meines Fensters auf 0 setze.

.

Antworten