AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Welche Windows-Events zum Zeichnen eines Buttons
Thema durchsuchen
Ansicht
Themen-Optionen

Welche Windows-Events zum Zeichnen eines Buttons

Ein Thema von sh17 · begonnen am 9. Dez 2005 · letzter Beitrag vom 20. Dez 2005
 
Vjay

Registriert seit: 2. Dez 2003
Ort: Berlin/Eschede
481 Beiträge
 
Delphi 7 Professional
 
#3

Re: Welche Windows-Events zum Zeichnen eines Buttons

  Alt 9. Dez 2005, 12:26
InvalidateRect erzeugt doch auch nur eine WM_PAINT ( + evtl. WM_ERASEBKGND) ...

Ich vermute, dass manche (Windowsbehandlungs-)Funktionen den Button direkt über DrawFrameControl neu Zeichnen und das Windows-Messageprinzip umgehen.

Ich habe nämlich genau das gleiche Problem.
Ein Beispiel: Wenn man in einer nicht (Manifest-) XP-Anwendung die Maustaste auf dem Button gedrückt hält, so wird dieser neu gezeichnet, aber ich erhalte nie eine Message darüber.

Evtl. hilft dir ein Funktionshook weiter, ich habe an diesem Punkt keine Lust mehr gehabt weiter zu suchen.

Weiterhelfen konnte mir damals auch niemand, da dies doch wirklich tief ins Eingemachte geht.

Ich hänge hier mal meine alte WNDProc an, die größtenteils funktioniert.
Zur Erklärung: Während die Maustasten gedrückt werden, erzeuge ich ein Overlay-Fenster, welches das Neuzeichnen des Buttons durch die Original-Wndproc verdeckt.
Es gibt zwar Funktionen um das Neuzeichenen von Fenster vorübergehend zu unterdrücken, aber von diesen kann ich nur abraten, da sie negative Nebeneffekte besitzen. Besonders wenn man in Fremdanwendungen "rumwurschtelt" sollte man sich so transparent und unauffällig benehmen wie es nur möglich ist.

Delphi-Quellcode:
// result= true = originalwndproc wird direkt aufgerufen
function TPulseButton.buttonWndProc( const handle: dWord; const Msg: cardinal; const wParam, lParam: dWord; var rueckgabe: dWord): Boolean;
begin
 result:= false;
 if MovingControlWndProc( handle, Msg, wParam, lParam) then exit;

 
   case Msg of
    WM_PAINT{, WM_NCPAINT}: begin
               if wParam= 0 then Paint
               else result:= true;
              end;
    WM_TIMER: begin
               if WParam = 999 then NextPulse
               else if WParam = 996 then
               begin
                if not isAltDown then
                begin
                 killTimer(handle, 996);
                 InvalidateRect(handle, NIL, false);
                end;
               end
               else if WParam = 998 then checkMouseOver
               else if WParam = 995 then
               begin
                killTimer(handle, 995);
                InvalidateRect(handle, NIL, false);
               end
               else result:= true;

               result:= true;
              end;
   WM_SIZE, WM_WINDOWPOSCHANGED, WM_MOVE: begin
              Rueckgabe := CallWindowProc( origWndProc, handle, Msg, wParam, lParam);
              InvalidateRect(handle, NIL, false);
             end;
   WM_LBUTTONDOWN: begin
                     if not LButtonDown then
                     begin
                      LButtonDown:= true;
                      activate;
                      createOverlayWindow;
                      Rueckgabe := CallWindowProc( origWndProc, handle, Msg, wParam, lParam);
                      destroyOverlayWindow;
                      InvalidateRect(handle, NIL, false);
                     end;
                    end;
   WM_LBUTTONUP, WM_LBUTTONDBLCLK: begin
                   if LButtonDown then
                   begin
                    LButtonDown:= false;
                    createOverlayWindow;
                    Rueckgabe := CallWindowProc( origWndProc, handle, Msg, wParam, lParam);
                    destroyOverlayWindow;
                    InvalidateRect(handle, NIL, false);
                   end;
                  end;
   WM_ENABLE, WM_RBUTTONDBLCLK, WM_SHOWWINDOW, WM_NCACTIVATE, WM_CAPTURECHANGED,
   WM_KILLFOCUS, WM_SETFOCUS, BM_SETSTATE, BM_SETSTYLE, WM_SETTEXT: begin
                  createOverlayWindow;
                  Rueckgabe := CallWindowProc( origWndProc, handle, Msg, wParam, lParam);
                  destroyOverlayWindow;
                  InvalidateRect(handle, NIL, true);
                  Paint;
                  InvalidateRect(handle, NIL, false);
                 end;
    WM_NCHITTEST: begin
                   Rueckgabe := HTCLIENT;
                   InvalidateRect(handle, NIL, false);
                  end;
    WM_MOUSEMOVE: begin
                   Rueckgabe := CallWindowProc( origWndProc, handle, Msg, wParam, lParam);
                   InvalidateRect(handle, NIL, false);
                   killTimer(handle, 998);
                   setTimer(handle, 998, 100, NIL);
                  end;
    WM_ACTIVATEPULSING: Pulsing:= boolean( wParam);
    WM_NCDESTROY: begin
                 Rueckgabe := CallWindowProc( origWndProc, handle, Msg, wParam, lParam);
                 deInitControl( handle);
                end;
   else
    result:= true;
   end;
 
end;
Dazu noch der besagte Funktionshook hat mir recht passable Ergebnisse gebracht. Ist allerdings größtenteils ungetestet. Es gibt einfach zuviele Anwendungen und Fälle.
Wer später bremst ist eher tot.
  Mit Zitat antworten Zitat
 


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 10:09 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz