Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Probleme mit AlphaBlend


nabbl - Fr 12.12.08 15:11
Titel: Probleme mit AlphaBlend
Hallo liebe Delphianer,

Ich sitze im Moment an einem kleinen Problem. Ich möchte gerne ein Form via Alphablend und Alphablendvalue ausblenden lassen.

Dazu benutze ich folgenden Code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
  frm1.AlphaBlendValue := 200;
  for i:=200 downto 0 do
  begin
    frm1.AlphaBlendValue := i;
    Application.ProcessMessages;
    delay(speed_in_ms);
  end;

Das Problem ist nur, dass die CPU-Auslastung tierisch in die Höhe schnellt und ich weiß nicht, warum. Könnt Ihr mir auf die Sprünge helfen?

Danke

Nabbl

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


Delete - Fr 12.12.08 15:14

Wie sieht die Delay-Prozedur aus?


nabbl - Fr 12.12.08 15:15

Das ist die von negaH:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure Delay(Milliseconds: Integer);
var
  Tick: DWord;
  Event: THandle;
begin
  Event := CreateEvent(nil, False, False, nil);
  try
    Tick := GetTickCount + DWord(Milliseconds);
    while (Milliseconds > 0and
          (MsgWaitForMultipleObjects(1, Event, False, Milliseconds, QS_ALLINPUT) <> WAIT_TIMEOUT) do
    begin
      Application.ProcessMessages;
      if Application.Terminated then Exit;
      Milliseconds := Tick - GetTickcount;
    end;
  finally
    CloseHandle(Event);
  end;
end;


Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


Delete - Fr 12.12.08 15:19

Die verwendet intern doch bereits Application.ProcessMessages, Du moppelst also doppelt.


nabbl - Fr 12.12.08 15:23

Auch ein einmaliger Aufrauf von
Application.ProcessMessages ändert nichts an der CPU-Auslastung :(


Delete - Fr 12.12.08 15:27

Und wenn Du Delay mal testhalber gegen Sleep austauschst?


nabbl - Fr 12.12.08 15:28

gleiches Problem...


Delete - Fr 12.12.08 15:32

Dann ist Delay schonmal nicht Schuld ;). Spricht denn etwas dagegen, einen Timer zu verwenden?


nabbl - Fr 12.12.08 15:34

Sagen wir es mal so: Ich habe die Funktion bereits in einen Thread ausgelagert, also prinzipiell nichts anderes gemacht als ein Timer tun würde. Ich mache das so, weil die Prozedur auch kurze Zeit hintereinander ausgeführt werden kann:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
procedure FlashBangSub(speed_in_ms: integer);
var i: integer;
begin
  if (flashs) then begin
    nextflash := true;
  end;
  flashs := true;
  frmBackground.AlphaBlendValue := 200;
  for i:=200 downto 0 do
  begin
    if not(flashs) then exit;
    frmBackground.AlphaBlendValue := i;
    delay(speed_in_ms);
    if (nextflash) then
    begin
      if (i = 150then flashs := false;
      nextflash := false;
      flashs := false;
      FlashBang(speed_in_ms);
      break;
      exit;
    end;
  end;
  flashs := false;
end;

// Flashbang
procedure Flashbang(speed_in_ms: integer);
begin
  ThreadHandle:=CreateThread(nil0, TFNThreadStartRoutine(@FlashBangSub), @speed_in_ms, 0, ThreadID);
  if ThreadHandle<>0 then CloseHandle(ThreadHandle);
end;


Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


Delete - Fr 12.12.08 15:37

Du weißt aber, dass die VCL nicht threadsafe ist? Für den Zugriff aus einem Thread heraus auf ein VCL-Objekt sollte man Synchronize verwenden.


nabbl - Fr 12.12.08 15:41

Nö, wusste ich nicht.
Danke. Werde mir das mal anschauen :)