AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Problem mit eigener MDI-ClientWndProc
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit eigener MDI-ClientWndProc

Ein Thema von DelphiKlaus · begonnen am 6. Mär 2007
Antwort Antwort
DelphiKlaus

Registriert seit: 18. Okt 2006
100 Beiträge
 
Delphi 6 Professional
 
#1

Problem mit eigener MDI-ClientWndProc

  Alt 6. Mär 2007, 12:31
Hallo,

ich habe seit einiger Zeit ein Problem mit einer MDI-Anwendung, die ich für einen Kunden geschrieben habe.

Eine Anforderung des Kunden besteht darin, dass während der Login-Phase des Programms innerhalb des MDI-Clientbereichs eine Bitmap gezeigt wird; eine andere Anforderung besagt, dass in Abhängigkeit von bestimmten Systemzuständen, die sich von Programmstart bis zur Beendigung nicht ändern, die Farbe des Clientbereichs auf rot, blau oder blaugrün gesetzt werden soll. Und nebenbei sollen noch die Scrollbars im Clientbereich entfernt werden.

Dies hab ich nach Suche in diesem Forum folgendermassen realisiert. In der FormCreate-Methode des MDI-Parent habe ich folgenden Code eingefügt:

Delphi-Quellcode:
FClientInstance := Classes.MakeObjectInstance (ClientWndProc);
FPrevClientProc := Pointer (GetWindowLong (ClientHandle,
                                           GWL_WNDPROC));
if FPrevClientProc = Nil then
  Raise EInvalid.Create ('Fensterprozedur bestimmen ' + IntToStr (GetLastError))
else
  if SetWindowLong (ClientHandle,
                    GWL_WNDPROC,
                    LongInt (FClientInstance)) = 0 then
    Raise EInvalid.Create ('Fensterprozedur setzen ' + IntToStr (GetLastError));
Hiermit sollte ja jetzt meine eigene Fensterprozedur für das MDI-Clientwindow aktiv werden, wenn eine entsprechende Message kommt.

Und so sieht die Fensterprozedur aus:

Delphi-Quellcode:
procedure TFormMDI.ClientWndProc (var Msg : TMessage);

begin
  try
    if Msg.Msg = wm_EraseBkgnd then
      begin
        { Hintergrundfarbe des Clientbereichs setzen } 
        if fSuperVisorMode then
          Canvas.Brush.Color := clRed
        else
          if LowerCase (System) = 'prozesswertethen
            { blau wie Standarddesktop von XP }
            Canvas.Brush.Color := RGB ( 58,
                                       110,
                                       165)
          else
            { grünblau wie Standarddesktop von 95 }
            Canvas.Brush.Color := RGB ( 0,
                                       128,
                                       128);

        { Hintergrund füllen }
        FillRect (TWMEraseBkgnd (Msg).DC,
                  ClientRect,
                  Canvas.Brush.Handle);

        { ggf. Hintergrundbild anzeigen }
        if fHintergrundBild then
          begin
            ImageHintergrund.Left := (Screen.Monitors [1].Width - ImageHintergrund.Picture.Width) div 2;
            ImageHintergrund.Top := (ClientHeight - ImageHintergrund.Picture.Height) div 2;
            ImageHintergrund.Visible := True
          end;

        Msg.Result := 1
      end
    else
      begin
        if Msg.Msg = wm_NCCalcSize then
          { Scrollbars im MDI-Clientbereich verhindern }
          SetWindowLong (ClientHandle,
                         gwl_Style,
                         GetWindowLong (ClientHandle,
                                        gwl_Style) and not (ws_HScroll or ws_VScroll));

        Msg_vb.Result := CallWindowProc (FPrevClientProc,
                                         ClientHandle,
                                         Msg.Msg,
                                         Msg.wParam,
                                         Msg.lParam)
      end
  except
    { an dieser Stelle dürfen keine Fehlermeldungen ausgegeben werden, da sonst das
      Programm komplett abstürzt }

  end
end;
Das funktioniert auch alles wunderbar. Nicht nur auf einem, sondern auch auf mehreren Arbeitsplätzen. Aber alle paar Tage kommt es auf einem der Rechner zu einem Fehler: beim Erzeugen eines neuen MDI-Childwindows bleibt das Programm hängen. Es gibt viele unterschiedliche Typen von MDI-Children, und der Fehler tritt mal bei dem einen und mal bei dem anderen auf, so dass ich einen Fehler in den Children selbst eigentlich ausschliesse.

Der Fehler äussert sich so:
- Der Rahmen des MDI-Childs erscheint, der Inhalt bleibt leer.
- wenn keine Exception-Behandlung in der ClientWndProc-Methode erfolgt, bleibt das Programm komplett hängen und kann nur noch über den Task-Manager abgeschossen werden
- wenn ich in die Exception-Behandlung folgenden Code einfüge

Delphi-Quellcode:
if Msg_vb.Msg = WM_MDICreate then
  try
    Msg_vb.Result := CallWindowProc (FPrevClientProc,
                                     ClientHandle,
                                     Msg.Msg,
                                     Msg.wParam,
                                     Msg.lParam)
  except
  end
läuft das Programm nach einer Wartezeit von ein paar Sekunden in der Regel weiter und erzeugt durch den zweiten Aufruf von CallWindowProc das gewünschte Fenster
- wenn ich versuche, den aufgetretenen Fehler zu ermitteln und auszugeben, z.B. als eMail oder über eine offene Socket-Verbindung zu einem Host, stürzt das Programm gnadenlos ab.

Es hat nun keinen Zweck, dass ich meinen gesamten Quellcode hier anfüge, da damit erstens der Kunde nicht einverstanden sein wird, und zweitens ca. 300000 Zeilen wohl auch ein bißchen viel wären. Es kann natürlich sein, das da noch ein blöder Fehler drin ist, der dann ab und zu dazwischen funkt.

Aber vielleicht hat ja jemand von Euch eine Idee oder auch schon mal Probleme in diesem Umfeld gehat und kann mit Tipps geben, wie ich der Ursache dieses etwas seltsamen Verhaltens auf die Spur kommen kann.

Vielen Dank schon mal

Klaus
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:01 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz