2010-03-11 8 views
6

Zum Beispiel muss ich zwei Tasten in Laufzeit deaktivieren. Nachdem ich die erste Taste deaktiviert hatte, wurde es grau, die zweite - es wurde auch grau. Aber ich weiß nicht, wie man die Neulackierung gleichzeitig macht!Wie man Kontrollen gleichzeitig ändert, ohne jedes neu zu streichen?

Ich brauche etwas wie folgt aus:

  1. das Formular einfrieren (deaktivieren Neulackierung)
  2. disable erste Schaltfläche
  3. disable zweite Schaltfläche
  4. aktivieren Formular Neulackierung

Wie zu Implementieren Das?

Antwort

10

Schauen Sie sich die Win32 API WM_SETREDRAW Nachricht an. Zum Beispiel:

SendMessage(Handle, WM_SETREDRAW, False, 0); 
Button1.Enabled := False; 
Button2.Enabled := False; 
SendMessage(Handle, WM_SETREDRAW, True, 0); 
InvalidateRect(Handle, nil, True); 
+1

Klar ungetestet (funktioniert nicht und kompilieren nicht einmal) – Deltics

+0

ich WM_SETREDRAW in mehreren Projekten verwenden, es funktioniert gut. Außerdem verwenden VCL-Komponenten, die Begin/EndUpdate() -Methoden verwenden, intern WM_SETREDRAW. –

+0

Es hat in diesem Fall nicht funktioniert ... * 1) * FALSE und TRUE sind keine gültigen Parameter für SendMessage() [Integer erforderlich] * 2) * Nach dem Ändern der FALSE und TRUE-Parameter auf 0 bzw. 1, so dass es Kompiliert und funktioniert wie beabsichtigt Das Formular wird am Ende nicht neu gezeichnet - die Schaltflächen bleiben sichtbar "aktiviert", es sei denn/bis verdeckt und dadurch gezwungen, neu zu streichen * 3) * selbst wenn es funktioniert hätte, versuchen/endlich de rigeur * 4) * Auch wenn es funktioniert hätte, wäre es immer noch sinnlos gewesen, wenn man auf die Verarbeitung der Nachricht für das Gemälde angewiesen wäre. – Deltics

5

Nachrichten können nicht bis Ihr Antrag bearbeitet werden, um eine Nachrichtenschleife wieder eintritt, so wird jeder Versuch, ändern/aktualisieren Steuerzustand, der auf die Nachrichtenverarbeitung beruht innerhalb einer einzigen Sequenz von Code nicht funktionieren, das nicht der Fall ist "pumpen" Nachrichten.

Glücklicherweise ist die VCL steuert typischerweise ein Mittel zur Kraft liefern Neulackierung ohne Nachrichten gewartet verarbeitet wird, über die Update-Methode:

Button1.Enabled := False; 
Button2.Enabled := False; 
Button1.Update; 
Button2.Update; 

Dies funktioniert unabhängig von Form Neulackierung deaktivieren zu müssen. Das Formular wird nicht neu gezeichnet, bis Ihre Anwendung trotzdem in eine Nachrichtenschleife eintritt. Daher ist das Deaktivieren des Formularanstrichs und das erneute Aktivieren innerhalb einer einzigen Prozedur, die selbst keine Nachrichtenverarbeitung verursacht, Zeitverschwendung.

Dies ist möglicherweise nicht genau gleichzeitige Neulackierung der beiden Schaltflächen, aber wirklich gleichzeitige Malerei von zwei separaten Kontrolle ist unmöglich, ohne in Multithreaded GUI Malcode, die ich denke, weit über den Rahmen dieses Problems. Das Aufrufen von Update auf zwei Schaltflächen wird so ähnlich wie Sie es benötigen.

+0

Synchrone Nachrichten werden sofort verarbeitet. Asynchrone müssen die Nachrichtenwarteschlange gepumpt werden. –

+0

Nur wenn der HWND, an den die Nachricht gesendet wird (SendMessage), von demselben Thread erstellt wurde, der die Nachricht sendet. Ansonsten ist die Nachricht immer noch synchron, aber das Empfangsfenster verarbeitet nur die Nachricht, wenn sie die Nachrichtenwarteschlange pumpt. Während Sie möglicherweise eine synchrone PAINT-Nachricht senden, ist die Verarbeitung dieser Nachricht möglicherweise auf asynchrone Nachrichten angewiesen, die vom PAINT-Handler stammen. cont ... – Deltics

+0

... die Folge der Unzuverlässigkeit synchronen Nachrichten, die wirklich synchron (oder sofort) verarbeitet werden, ist, dass, wenn Sie eine Routine aufrufen möchten, die normalerweise als Antwort auf eine Nachricht aufgerufen wird, und zwar synchron Der zuverlässigste Weg, dies zu tun, besteht darin, diese Routine einfach synchron aufzurufen und sich nicht auf Messaging zu verlassen. Umgekehrt ist Messaging unter anderen Umständen der bevorzugte und zuverlässigere Mechanismus. :) – Deltics

-1

Dies könnte helfen: Die API LockWindowUpdate (Handle: HWND) sperrt Zeichnung an das Handle und Kinder.

ex:

 
procedure TForm1.ColorButtons(); 
begin 
    LockWindowUpdate(Self.Handle); 
    // Make some stuff 
    LockWindowUpdate(0); 
end; 

Sobald der gesperrte Griff zurückgesetzt wird, wird die Komponente

+6

Siehe http://blogs.msdn.com/b/oldnewthing/archive/2007/02/19/1716211.aspx und http://blogs.msdn.com/b/oldnewthing/archive/2007/02/20 /1726880.aspx und http://blogs.msdn.com/b/oldnewthing/archive/2007/02/21/1735472.aspx und http://blogs.msdn.com/b/oldnewthing/archive/2007/02 /22/1742084.aspx und http://blogs.msdn.com/b/oldnewthing/archive/2007/02/23/1747713.aspx, um zu sehen, warum es keine gute Idee ist. –

2

Die obige Entscheidung mit WM_SETREDRAW verwendet keine untergeordneten Fenster aktualisieren.

Stattdessen empfehle ich RedrawWindow:

RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_ALLCHILDREN); 
Verwandte Themen