Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi C++ WndProc Funktion in Delphi übersetzen (https://www.delphipraxis.net/52912-c-wndproc-funktion-delphi-uebersetzen.html)

mirage228 6. Sep 2005 16:59


C++ WndProc Funktion in Delphi übersetzen
 
Hallo,

Ich habe mir diese WndProc in C++ angeschaut:
http://www.codeproject.com/buglist/MDIFlick.asp

Diese Funktion bewirkt, dass das Flickern beim Wechseln von maximierten MDI Fenstern aufhört.

Code:
LRESULT CChildFrame::WindowProc(UINT message,
                       WPARAM wParam, LPARAM lParam)
{
    if(message==WM_NCPAINT || message==WM_SIZE)
    {
        BOOL bMax;
        CMDIFrameWnd* pParentFrame = (CMDIFrameWnd*)GetParentFrame();
        if(pParentFrame)
        {
            CMDIChildWnd* pChildFrame = pParentFrame->MDIGetActive(&bMax);
            if(bMax)
            {   
                if(message==WM_NCPAINT) // non client area
                    return 0;
                   
                if(message==WM_SIZE) // client area
                {
                    if(wParam==SIZE_MAXIMIZED &&
                       pChildFrame==this) // active and maximized
                      return CMDIChildWnd::WindowProc(message, wParam, lParam);

                    SetRedraw(FALSE);
                    LRESULT ret =
                      CMDIChildWnd::WindowProc(message, wParam, lParam);
                    SetRedraw();
                    return ret;
                }
            }
        }
    }
    return CMDIChildWnd::WindowProc(message, wParam, lParam);
}
Leider habe ich nicht genügend MFC bzw. C++ Kenntnisse, um den Code vernünftig übersetzen.

Das habe ich "übersetzt", es funktioniert jedoch nicht korrekt (der NC Bereich wird gar nicht gezeichnet und beim Wiederherstellen wird auch nicht korrekt gezeichnet):

Delphi-Quellcode:
procedure TMDIChild.WndProc(var Msg: TMessage);
var
  Max: Boolean;
  Parent: TForm;
  MDI  : TForm;
begin
  if (Msg.Msg = WM_NCPAINT) or (Msg.Msg = WM_SIZE) then
  begin
    Parent := Application.MainForm; // ParentFrame gibt es in Delphi nicht, nehme einfach den MDI Parent
    MDI := Parent.ActiveMDIChild; // Aktives MDI Child
    if MDI = nil then
    begin
      inherited WndProc(Msg);
      Exit;
    end;
    Max := MDI.WindowState = wsMaximized; // = pParentFrame->MDIGetActive(&bMax); ?
    if Max then
    begin
      case msg.Msg of
        WM_NCPAINT:
          Msg.Result := 0;
        WM_SIZE:
          begin
            if ((msg.WParam = SIZE_MAXIMIZED) or (msg.WParam = SIZE_RESTORED))
              and (MDI = Self) then // pChildFrame==this ? 
            begin
              inherited WndProc(Msg);
              Exit;
            end;
            SendMessage(Handle, WM_SETREDRAW, Integer(False), 0);
            inherited WndProc(Msg);
            SendMessage(Handle, WM_SETREDRAW, Integer(True), 0);
          end;
        end;
    end;
  end else
    inherited WndProc(Msg);
end;
Kann mir jemand auf die Sprünge helfen?

mfG
mirage228

[edit]Als "Offene Frage" markiert.[/edit]

Olli 1. Okt 2005 13:38

Re: C++ WndProc Funktion in Delphi übersetzen
 
Ganz so einfach kommst du da auch nicht weg. Soweit ich den urspr. Code verstehe, ist es eine spezifische MFC-Lösung. Die ist nicht einfach übertragbar, weil du nämlich nicht die anderen ("unsichtbaren") Eigenschaften des MFC-Frameworks hast.

Union 1. Okt 2005 13:49

Re: C++ WndProc Funktion in Delphi übersetzen
 
Hast Du es schon mal mit Delphi-Referenz durchsuchenLockWindowUpdate versucht?

mirage228 1. Okt 2005 16:52

Re: C++ WndProc Funktion in Delphi übersetzen
 
Hi,

Danke für eure Antworten. Schade, dass sich das nicht so einfach übertragen lässt, ich schaue, wie ich dieses Problem dennoch lösen kann.

Was wäre denn der Unterschied von LockWindowUpdate() zu WM_SETREDRAW. Im Prinzip dürfte es bei dem Code ohnehin keinen Unterschied machen, da das Zeichnen während des Aufrufs eh verhindert wird.
Ich glaube aber, dass ich die ganze Struktur nochmal umarbeiten muss, da sich das ganze ja auf MFC spezifische Dinge stütz.
Falls einer von euch noch eine Idee zur Umsetzung hat, immer nur her damit :)

mfG
mirage228

Union 1. Okt 2005 18:46

Re: C++ WndProc Funktion in Delphi übersetzen
 
Hi, hast Du mal ein Beispiel, wo das Flickern besonders heftig auftritt ? Ich habe festgestellt (mit einer neuen leeren MDIApp), dass die Fenster nur dann Flimmern, wenn man über das Window-Menü umschaltet. Wird Strg-F6 verwendet, so flimmert nichts.

mirage228 2. Okt 2005 08:10

Re: C++ WndProc Funktion in Delphi übersetzen
 
Zitat:

Zitat von Union
Hi, hast Du mal ein Beispiel, wo das Flickern besonders heftig auftritt ?

Also das Flickern tritt bei einem Wechsel über das Fenster Menü oder einem manuellem Wechsel per Code bei mir auf. Ob das, was man da an Flickern sieht, "heftig" ist kann ich jetzt nicht sagen, da ich keinen Vergleich dazu habe.

Zitat:

Ich habe festgestellt (mit einer neuen leeren MDIApp), dass die Fenster nur dann Flimmern, wenn man über das Window-Menü umschaltet. Wird Strg-F6 verwendet, so flimmert nichts.
Genau so ist es bei mir auch. Benutze ich das Fenster-Menü oder schalte ich per Code (ich habe mit einer Toolbar eine Art "Tabliste" erstellt, damit man sich dort die Fenster aussuchen kann) um, dann tritt das flickern auf.
Wechsele ich per F6 trit kein Flickern auf. Nun würde mich interessieren, wie ich das auch per Code machen, so wie es Windows macht...

mfG
mirage228

Union 2. Okt 2005 08:53

Re: C++ WndProc Funktion in Delphi übersetzen
 
Jetz flimmert es bei mir nicht mehr:
Delphi-Quellcode:
procedure TMDIChild.FormCreate(Sender: TObject);
var
   AStyle : integer;
begin
   AStyle := GetWindowLong(Handle, GWL_EXSTYLE);
   SetWindowLong(Handle, GWL_EXSTYLE, AStyle or WS_CLIPCHILDREN);
end;
Und so schaltest Du zum nächsten Fenster um:
Delphi-Quellcode:
procedure TMainForm.WindowNextExecute(Sender: TObject);
begin
    SendMessage(ClientHandle, WM_MDINEXT, 0, 0);
end;

mirage228 2. Okt 2005 09:15

Re: C++ WndProc Funktion in Delphi übersetzen
 
Hi,

Also beim ersten Code ist bei mir weiterhin ein flimmern zu erkennen, auch wenn es nicht mehr so deutlich ist...
Der zweite Code funktioniert korrekt, jedoch kann ich damit kein beliebiges Fenster aktivieren.

Mit diesem Code funktioniert es bei mir auch manuell:
Delphi-Quellcode:
  LockWindowUpdate(Self.Handle);
  MdiChildren[i].BringToFront;
  MdiChildren[i].SetFocus;
  LockWindowUpdate(0);
Ich schaue aber noch, ob man es auch anders lösen könnte.

mfG
mirage228


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:35 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