AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

InvalidateRect und 100% CPU ?

Ein Thema von EWeiss · begonnen am 24. Okt 2008 · letzter Beitrag vom 24. Okt 2008
Antwort Antwort
EWeiss
(Gast)

n/a Beiträge
 
#1

InvalidateRect und 100% CPU ?

  Alt 24. Okt 2008, 11:25
da bei mir die Button nicht neu gezeichnet werden wenn ich mit der maus drüberfahre
habe ich mich zu InvalidateRect entschlossen.

Delphi-Quellcode:
begin
  ImgW := ImgW div cardinal(StateMax);
  if IsWindowEnabled(WinHandle) then
  begin
    UseState := 1;
    if (WinHandle = GetFocus) and (StateMax > 3) then
      UseState := 4;
    GetCursorPos(CurPos);
    ScreenToClient(WinHandle, CurPos);
    InvalidateRect(WinHandle, @rc, False);
    UpdateWindow(WinHandle);
    if PtInRect(rc, CurPos) then
      if IsLButtonDown then
      begin
        if WinHandle = GetFocus() then
          if (GetCursor = LoadCursor(0, IDC_ARROW)) and (StateMax > 1) then
            UseState := 2;
      end else
      if StateMax > 4 then UseState := 5;
  end else
  if StateMax > 2 then UseState := 3;
end;
Jetzt funktioniert alles bestens aber mit gut 80-100% CPU
wenn ich mit der Maus innerhalb des Window bin.

Das kann es doch nicht sein oder ?
Hat vielleicht jemand eine lösung dafür ?

gruss Emil
  Mit Zitat antworten Zitat
Roachford
(Gast)

n/a Beiträge
 
#2

Re: InvalidateRect und 100% CPU ?

  Alt 24. Okt 2008, 11:37
InvalidateRect() bringt dir so lange keinen Vorteil, so lange du sofort mit UpdateWindow() das Paint erzwingst. InvalidateRect() würde dir Vorteile bringen, wenn du Windows die dirty areas sammeln lässt und dann kombinierte und effektivere Paint Aufrufe machen lässt.

1. InvalidateRect() ohne das UpdateWindow() dahinter
2. Das Clipping Rectangle aus der PAINTSTRUCT von BeginPaint() beachten und entsprechend BitBlt() auf dieses Rechteck beschränken und Zeichenoperationen ausserhalb des Rechtecks komplett unterlassen im Paint.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#3

Re: InvalidateRect und 100% CPU ?

  Alt 24. Okt 2008, 11:43
Zitat von Roachford:
InvalidateRect() bringt dir so lange keinen Vorteil, so lange du sofort mit UpdateWindow() das Paint erzwingst. InvalidateRect() würde dir Vorteile bringen, wenn du Windows die dirty areas sammeln lässt und dann kombinierte und effektivere Paint Aufrufe machen lässt.

1. InvalidateRect() ohne das UpdateWindow() dahinter
2. Das Clipping Rectangle aus der PAINTSTRUCT von BeginPaint() beachten und entsprechend BitBlt() auf dieses Rechteck beschränken und Zeichenoperationen ausserhalb des Rechtecks komplett unterlassen im Paint.
Habe es jetzt so geändert ..
Delphi-Quellcode:
            begin
              ImgW := ImgW div cardinal(StateMax);
              if IsWindowEnabled(WinHandle) then
              begin
                UseState := 1;
                if (WinHandle = GetFocus) and (StateMax > 3) then
                  UseState := 4;
                GetCursorPos(CurPos);
                ScreenToClient(WinHandle, CurPos);

                GetClientRect(WinHandle, rc);
                InvalidateRect(WinHandle, @rc, False);

                if PtInRect(rc, CurPos) then
                  if IsLButtonDown then
                  begin
                    if WinHandle = GetFocus() then
                      if (GetCursor = LoadCursor(0, IDC_ARROW)) and (StateMax > 1) then
                        UseState := 2;
                  end else
                  if StateMax > 4 then UseState := 5;
              end else
              if StateMax > 2 then UseState := 3;
            end;
Das bringt einiges und es wird nur der Client bereich neu gezeichnet auf dem sich
die Maus gerade befindet.
Verstehen tu ich das ganze trotzdem nicht warum bei mir das Paintevent nicht anspringt
ohne das ich über InvalidateRect gehe.

Die Main proc macht nichts besonderes..
Delphi-Quellcode:
      WM_PAINT:
      begin
        BeginPaint(WinHandle, ps);
        PaintDoubleBuffer(WinHandle, ps.hdc);
        EndPaint(WinHandle, ps);
        Result := 0;
        exit;
      end;
gruss Emil
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: InvalidateRect und 100% CPU ?

  Alt 24. Okt 2008, 12:15
Wozu das Result und das Exit am Ende?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#5

Re: InvalidateRect und 100% CPU ?

  Alt 24. Okt 2008, 12:22
Zitat von Luckie:
Wozu das Result und das Exit am Ende?
Um aus der Proc zu springen.
Da sonst meine DefWindowProc aufgerufen wird welche die WM_NCHITTEST
Messagen verarbeitet.

gruss Emil
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

Re: InvalidateRect und 100% CPU ?

  Alt 24. Okt 2008, 12:24
Und diese Nachricht soll nicht verarbeitet werden? Dann verarbeite sie doch und tue nichts. Dann wird deutlicher was du vorhast. So musste ioch die Frage stellen, das entfällt, wen du es so machst, wie ich es vorgeschlagen habe.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#7

Re: InvalidateRect und 100% CPU ?

  Alt 24. Okt 2008, 12:28
Zitat von Luckie:
Und diese Nachricht soll nicht verarbeitet werden? Dann verarbeite sie doch und tue nichts. Dann wird deutlicher was du vorhast. So musste ioch die Frage stellen, das entfällt, wen du es so machst, wie ich es vorgeschlagen habe.
Reden wir aneinander vorbei ?
Oder was willst mir damit sagen..

Meine APP Proc
Delphi-Quellcode:
function WndProc(WinHandle: HWND; Msg: UINT; wP: WParam; lP: LParam): longint;
  stdcall;
var
  ps: TPaintStruct;
  rw: PRect;
  hBut: THandle;
  imgW: cardinal;
  pMM: PMinMaxInfo;
  CaptionHeight: integer;
  p: TPoint;

begin

  with SkinEngine do
  begin

    case Msg of
      WM_GETMINMAXINFO:
      begin
        pMM := PMinMaxInfo(lP);
        pMM^.ptMinTrackSize.x := MinTrackSizeX[0];
        pMM^.ptMinTrackSize.y := MinTrackSizeY[0];
      end;
      WM_COMMAND:
      begin
        if ButtonSysCommand(WinHandle, wP) then
        begin
          Result := 0;
          Exit;
        end;
        case LoWord(wP) of
          ID_AEROCRYSTAL:
          begin
            if GetCheckButtonStatus(GetMainItem(ID_AEROCRYSTAL)) then
            begin
              SplitColorARGB(SK_AEROCOLOR, Alpha, Red, Green, Blue);
              FConfig.AeroColor[ColorARGB(GetTrackValue(GetMainItem(
                ID_TRACK_OPACITY)), RGB(Red, Green, Blue)), SK_WRITE];
              SetCheckButtonStatus(GetMainItem(ID_AERODISABLE), False);
              SetCheckButtonStatus(GetMainItem(ID_AEROBLUR), False);
              FConfig.AeroEmulate[SK_WRITE, SK_WRITE];
              FConfig.AeroBlueLevel[SK_FALSE, SK_WRITE];
              SetTrackValue(GetMainItem(ID_TRACK_BLURLEVEL), SK_AEROBLURLEVEL);

              SetTimer(WinHandle, AERO_TIMER, SK_AEROTIMERDELAY, nil);

              FConfig.UseVistaBlur[SK_FALSE, SK_WRITE];
              FConfig.UseVistaCrystal[SK_WRITE, SK_WRITE];
              FConfig.TextRendering[TextRenderingHintAntiAlias, 1];
            end else
            begin
              FConfig.TextRendering[TextRenderingDefault, 1];
              KillTimer(WinHandle, AERO_TIMER);
              FConfig.AeroEmulate[SK_FALSE, SK_WRITE];

              SetCheckButtonStatus(GetMainItem(ID_AERODISABLE), True);

              FConfig.UseVistaBlur[SK_FALSE, SK_WRITE];
              FConfig.UseVistaCrystal[SK_FALSE, SK_WRITE];
            end;
            GetWindowRect(WinHandle, rc);
            MoveBackground(rc.Left, rc.Top);
            FUpdateWindow(WinHandle, False);
          end;
          ID_AEROBLUR:
          begin
            if GetCheckButtonStatus(GetMainItem(ID_AEROBLUR)) then
            begin
              SplitColorARGB(SK_AEROCOLOR, Alpha, Red, Green, Blue);
              FConfig.AeroColor[ColorARGB(GetTrackValue(GetMainItem(
                ID_TRACK_OPACITY)), RGB(Red, Green, Blue)), SK_WRITE];
              SetCheckButtonStatus(GetMainItem(ID_AERODISABLE), False);
              SetCheckButtonStatus(GetMainItem(ID_AEROCRYSTAL), False);
              FConfig.AeroEmulate[SK_WRITE, SK_WRITE];
              FConfig.AeroBlueLevel[6, SK_WRITE];
              SetTrackValue(GetMainItem(ID_TRACK_BLURLEVEL), SK_AEROBLURLEVEL);
              SetTimer(WinHandle, AERO_TIMER, SK_AEROTIMERDELAY, nil);

              FConfig.UseVistaCrystal[SK_FALSE, SK_WRITE];
              FConfig.UseVistaBlur[SK_WRITE, SK_WRITE];
              FConfig.TextRendering[TextRenderingHintAntiAlias, 1];
            end else
            begin
              FConfig.TextRendering[TextRenderingDefault, 1];
              KillTimer(WinHandle, AERO_TIMER);
              FConfig.AeroEmulate[SK_FALSE, SK_WRITE];

              SetCheckButtonStatus(GetMainItem(ID_AERODISABLE), True);

              FConfig.UseVistaBlur[SK_FALSE, SK_WRITE];
              FConfig.UseVistaCrystal[SK_FALSE, SK_WRITE];
            end;
            GetWindowRect(WinHandle, rc);
            MoveBackground(rc.Left, rc.Top);
            FUpdateWindow(WinHandle, False);
          end;
          ID_AERODISABLE:
          begin
            if GetCheckButtonStatus(GetMainItem(ID_AERODISABLE)) then
            begin
              SetCheckButtonStatus(GetMainItem(ID_AEROBLUR), False);
              SetCheckButtonStatus(GetMainItem(ID_AEROCRYSTAL), False);
              FConfig.AeroEmulate[SK_FALSE, SK_WRITE];
              FConfig.TextRendering[TextRenderingDefault, 1];
              KillTimer(WinHandle, AERO_TIMER);

              FConfig.UseVistaBlur[SK_FALSE, SK_WRITE];
              FConfig.UseVistaCrystal[SK_FALSE, SK_WRITE];

              GetWindowRect(WinHandle, rc);
              MoveBackground(rc.Left, rc.Top);
              FUpdateWindow(WinHandle, False);
            end else
              SetCheckButtonStatus(GetMainItem(ID_AERODISABLE), True);
          end;
          ID_TRACK_OPACITY:
          begin
            if SK_AEROEMULATE <> 0 then
            begin
              SplitColorARGB(SK_AEROCOLOR, Alpha, Red, Green, Blue);
              FConfig.AeroColor[ColorARGB(lP, RGB(Red, Green, Blue)), SK_WRITE];
              GetWindowRect(WinHandle, rc);
              MoveBackground(rc.Left, rc.Top);
              FUpdateWindow(WinHandle, False);
            end;
          end;
          ID_TRACK_BLURLEVEL:
          begin
            if lP <> SK_AEROBLURLEVEL then
            begin
              FConfig.AeroBlueLevel[lP, SK_WRITE];
              if SK_AEROEMULATE = 1 then
              begin
                GetWindowRect(WinHandle, rc);
                MoveBackground(rc.Left, rc.Top);
                FUpdateWindow(WinHandle, False);
              end;
            end;
          end else
          begin
            Result := 0;
            exit;
          end;
        end;
      end;
      WM_SIZE:
      begin
        DrawBackground;
        EnumChildWindows(WinHandle, @AnchorEnum, 0);
        FUpdateWindow(WinHandle, False);
      end;
      WM_SETTEXT:
      begin
        Result := DefWindowProc(WinHandle, Msg, wP, lP);
        // Aktualisiere das Caption
        PaintBackground;
        // Nur Caption neuzeichnen
        GetClientRect(WinHandle, rc);

        GetImageSize(GetProperty(WinHandle, FORM_TopMid),
          imgW, cardinal(rc.Bottom));
        InvalidateRect(WinHandle, @rc, False);
        UpdateWindow(WinHandle);
        exit;
      end;
      WM_NCLBUTTONDBLCLK:
      begin
        if IsIconic(WinHandle) then
        begin
          p.X := LoWord(lP);
          p.Y := HiWord(lP);
          ScreenToClient(WinHandle, p);

          GetImageSize(GetProperty(WinHandle, FORM_TopMid),
            imgW, cardinal(CaptionHeight));
          if p.Y < CaptionHeight then
          begin
            if IsZoomed(WinHandle) then
              ButtonSysCommand(WinHandle, MAKELONG(ID_RESTORE, 0))
            else
              ButtonSysCommand(WinHandle, MAKELONG(ID_MAXIMIZE, 0));

            Result := 0;
            exit;
          end;
        end;
      end;
      WM_NCACTIVATE:
      begin
        hBut := GetDlgItem(WinHandle, ID_LED);
        if hBut <> 0 then
        begin
          Result := DefWindowProc(WinHandle, Msg, wP, lP);
          if MainWindow(0) = GetForegroundWindow then
            gColorCaption := SK_ACTIVECAPTION
          else
            gColorCaption := SK_INACTIVECAPTION;

          // Aktualisiere das Caption
          PaintBackground;

          // Nur Caption neuzeichnen
          GetClientRect(WinHandle, rc);
          GetImageSize(GetProperty(WinHandle, FORM_TopMid),
            imgW, cardinal(rc.Bottom));
          InvalidateRect(WinHandle, @rc, False);
          UpdateWindow(WinHandle);
          exit;
        end;
      end;
      WM_ERASEBKGND:
      begin
        Result := 1;
        exit;
      end;
      WM_PAINT:
      begin
        BeginPaint(WinHandle, ps);
        PaintDoubleBuffer(WinHandle, ps.hdc);
        EndPaint(WinHandle, ps);
        Result := 0;
        exit;
      end;
      WM_DESTROY:
      begin
        RemoveAllImageResource;
        DestroyWindowResource(WinHandle);

        PostQuitMessage(0);
        Result := 0;
        Exit;
      end;
      WM_TIMER:
      begin
        if IsCompositionEnabled = False then
        begin
          if (SK_AEROEMULATE = 1) and IsAeroLayered then
          begin
            if IsLButtonDown = False then
              IsMoving := False;
            if (IsMoving = False) or (IsLButtonDown and (IsMoving)) then
            begin
              GetWindowRect(WinHandle, rc);
              MoveBackground(rc.Left, rc.Top);
              FUpdateWindow(WinHandle, False);
            end;
          end;
        end;
      end;
      WM_NCLBUTTONDOWN:
        IsMoving := True;
      WM_MOVING:
      begin
        if IsCompositionEnabled = False then
        begin
          if (SK_AEROEMULATE = 1) and IsAeroLayered then
          begin
            rw := PRect(lP);
            MoveBackground(rw.Left, rw.Top);
            FUpdateWindow(WinHandle, False);
            Result := 1;
            exit;
          end;
        end;
      end;
    end;

    Result := skDefWindowProc(WinHandle, Msg, wP, lP);
  end;

end;
Meine Def Proc
Delphi-Quellcode:
function skDefWindowProc(WinHandle: HWND; Msg: UInt; wP: WParam; lP: lParam): longint;
  stdcall;
var
  rc: TRect;
  p: TPoint;
  CaptionHeight: cardinal;
  xF, yF, xSide, BORDER: integer;
  HITTEST: integer;

begin

  Result := DefWindowProc(WinHandle, Msg, wP, lP);

  HITTEST := 0;

  if Msg = WM_NCHITTEST then
  begin

    SkinEngine.GetImageSize(SkinEngine.GetProperty(WinHandle, FORM_TopMid),
      imgW, CaptionHeight);

    p.X := LoWord(lP);
    p.Y := HiWord(lP);

    ScreenToClient(WinHandle, p);
    if IsZoomed(WinHandle) = False then
    begin
      if Result = HTCLIENT then
      begin
        HITTEST := HTCAPTION;
        if SkinEngine.SK_DRAG_BACKGROUND = 0 then
        begin
          if (p.Y > integer(CaptionHeight)) and (CaptionHeight > 0) then
          begin
            HITTEST := HTNOWHERE;
            if WinHandle <> GetForegroundWindow then
              SetFocus(WinHandle);
          end;
        end;
        if SkinEngine.WinResizable(WinHandle) <> 0 then
          GetClientRect(WinHandle, rc);

        xF := rc.Right;
        yF := rc.Bottom;
        xSide := 0;
        BORDER := GetSystemMetrics(32);
        if ((p.X >= xF - BORDER) and ((p.Y >= yF - BORDER))) then
        begin
          HITTEST := HTBOTTOMRIGHT;
        end else
        begin
          // Linke Seite
          if (p.X <= 8) then
          begin
            if (p.X <= BORDER) then
              HITTEST := HTLEFT;
            xSide := 1;
          end;
          // Rechte Seite
          if (p.X >= xF - 8) then
          begin
            if (p.X >= xF - BORDER) then
              HITTEST := HTRIGHT;
            xSide := 2;
          end;
          // Obere Seite
          if (p.Y <= BORDER) then
          begin
            HITTEST := HTTOP;
            if (xSide = 1) then
              HITTEST := HTTOPLEFT
            else if (xSide = 2) then
              HITTEST := HTTOPRIGHT;
          end;
          // Untere Seite
          if (p.Y >= yF - BORDER) then
          begin
            if (xSide = 1) then
              HITTEST := HTBOTTOMLEFT
            else
              HITTEST := HTBOTTOM;
          end;
        end;
      end;
      Result := HITTEST;
    end else
    begin
      if p.Y < integer(CaptionHeight) then
        Result := HTCAPTION;
    end;
  end;

end;
Ich springe bei WM_PAINT raus um diese danach nicht zu verarbeiten wenn das Paint Event beendet ist.
Was ist da falsch ?

gruss Emil
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

Re: InvalidateRect und 100% CPU ?

  Alt 24. Okt 2008, 12:33
OK, jetzt habe ich es verstanden.
Michael
Ein Teil meines Codes würde euch verunsichern.
  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 21:34 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