Forum > Android
Application.processmessages does not seem to work
Kostas:
Hi!
I have managed to run Graphics32 in Android and the speed for stretching etc is very good!!
Now i have the following problem:
I am trying to do some animations.
I am calling for every frame of the animation 'Application.processmessages'.
But the GUI is not getting refreshed.
The code is the following:
for i := 1 to 40 do
begin
aDice.Roll;
DrawDice(aDice); // This will draw the correct Dice bitmaps (TBitmap32) on a Graphics32 Image
Application.ProcessMessages;
sleep(25); // Wait 25 ms for this frame
end;
The animation works right in Custom Drawn Interface when running on Win32
Am i doing something wrong?
How to get the Gui refreshed in android?
2. Is it possible to play sounds in Android and how?
Thanks in advance
felipemdc:
Android does not support Application.ProcessMessages by design, so it cannot be implemented in the LCL. In general you cannot take too long to exit a event handler in Android or else it will ask the user to kill the process as it is not responding, so using Sleep() in the main thread is a bad idea.
What you should do instead is handle the OnPaint event of your form, or other control, and draw 1 frame there.
Add a TTimer which calls Form.Invalidate or Control.Invalidate periodically to get an animation.
About sound, first research which APIs are available in the SDK and NDK. You can access SDK Java APIs via JNI. NDK APIs can be accessed via C headers converted to Pascal.
meanderix:
Hi Kostas,
--- Quote from: Kostas on June 14, 2012, 08:25:51 am ---Now i have the following problem:
I am trying to do some animations.
I am calling for every frame of the animation 'Application.processmessages'.
--- End quote ---
As Felipe suggested, you need to use timers for animations. If you're using a TPaintBox32 instance then you can call TPaintBox32.Repaint inside the OnTimer event handler (and then you can redraw your frame in the TPaintBox32.OnPaint handler.)
A different option, which might be slightly faster (if you want to control the whole screen via Graphics32), would be to use TForm.OnPaint and a separate paint buffer. Below are some of the changes I did to Graphics32's GradLinesEx example in order to get good performance:
--- Code: ---uses
LazCanvas, customdrawnint, LCLProc, ... ;
procedure TFormGradientLines.FormPaint(Sender: TObject);
var
LazCanvas: TLazCanvas;
W, H: Integer;
begin
LazCanvas := TLazCanvas(Canvas.Handle);
W := LazCanvas.Width;
H := LazCanvas.Height;
Buffer.SetSize(W, H);
RepaintBuffer;
Buffer.DrawTo(Canvas.Handle, 0, 0);
end;
procedure TFormGradientLines.Timer1Timer(Sender: TObject);
begin
Repaint;
end;
function TFormGradientLines.MyDisableFormBackgroundDrawingProc(AForm: TCustomForm): Boolean;
begin
Result := AForm = Self; // disable drawing only for self
end;
procedure TFormGradientLines.FormCreate(Sender: TObject);
begin
Buffer := TBitmap32.Create;
FadeCount := 0;
DrawPasses := 2;
CDWidgetset.DisableFormBackgroundDrawingProc := @MyDisableFormBackgroundDrawingProc;
end;
procedure TFormGradientLines.RepaintBuffer;
var
I, J: Integer;
P: PColor32;
begin
for J := 0 to DrawPasses - 1 do
for I := 0 to High(Lines) do
begin
Lines[I].Advance(1);
Lines[I].Paint;
end;
if FadeCount > 0 then
begin
if Pass = 0 then with Buffer do
begin
P := @Bits[0];
for I := 0 to Width * Height -1 do
begin
BlendMem($10000000, P^);
Inc(P);
end;
EMMS;
end;
Dec(Pass);
if (Pass < 0) or (Pass > FadeCount) then Pass := FadeCount;
end;
end;
--- End code ---
Edit: I also made some changes to GR32_Backends_LCL_CustomDrawn. The problem here is that you get the wrong colors (BGRA instead of ARGB.) This has been discussed a bit in the GR32 newsgroups and it seems this is a problem with some other backends as well. A solution might be to have conditional defines that would adjust the TColor32Entry record to either ARGB or BGRA memory layout.
--- Code: ---procedure TransferBits(Src, Dst: TLazIntfImage; X, Y, XSrc, YSrc,
SrcWidth, SrcHeight: Integer); overload;
var
I, H: Integer;
Depth: Integer;
X1, Y1, X2, Y2, SrcLine, DstLine, CopyBytes: Integer;
PSrc, PDst: PByte;
begin
Depth := Src.DataDescription.Depth shr 3;
SrcLine := Src.Width * Depth;
DstLine := Dst.Width * Depth;
PSrc := Src.PixelData;
PDst := Dst.PixelData;
if (X >= Dst.Width) or (Y >= Dst.Height) then Exit;
X1 := X;
Y1 := Y;
X2 := Min(X + SrcWidth, Dst.Width);
Y2 := Min(Y + SrcHeight, Dst.Height);
CopyBytes := (X2 - X1) * Depth;
Inc(PSrc, XSrc * Depth + SrcLine * YSrc);
Inc(PDst, X * Depth + DstLine * Y);
for I := 0 to SrcHeight - 1 do
begin
System.Move(PSrc^, PDst^, CopyBytes);
Inc(PSrc, SrcLine);
Inc(PDst, DstLine);
end;
end;
procedure TransferBits(Src, Dst: TLazIntfImage); overload;
begin
TransferBits(Src, Dst, 0, 0, 0, 0, Src.Width, Src.Height);
end;
procedure TLCLBackend.DoPaint(ABuffer: TBitmap32; AInvalidRects: TRectList;
ACanvas: TCanvas; APaintBox: TCustomPaintBox32);
var
Src, Dst: TLazCanvas;
begin
Dst := TLazCanvas(ACanvas.Handle);
Src := TLazCanvas(Canvas.Handle);
if Dst.Image is TLazIntfImage then
TransferBits(TLazIntfImage(Src.Image), TLazIntfImage(Dst.Image))
else
Dst.CopyRect(0, 0, Src, Rect(0,0,Src.Width,Src.Height));
end;
--- End code ---
Kostas:
Thanks a lot for your detailed answer!!
I will look at a later point at your changes to Graphics32.
I have actually no problem with the library.
Everything seems to draw right and also alpha blending works fine.
Also on my Smartphone. And it is really fast... :)
--- Quote from: meanderix on June 14, 2012, 03:00:37 pm ---A different option, which might be slightly faster (if you want to control the whole screen via Graphics32), would be to use TForm.OnPaint and a separate paint buffer.
--- End quote ---
Yes i already was into this way.
My Problem for the moment is that my OnPaint handler of my Form is never called...
Invalidate or Repaint does not call the FormPaint handler...
Neither on Win32 nor on Android.
I am still on testing and looking around in order to find the problem.
Any idea?
felipemdc:
--- Quote from: Kostas on June 14, 2012, 07:26:59 pm ---My Problem for the moment is that my OnPaint handler of my Form is never called...
Invalidate or Repaint does not call the FormPaint handler...
Neither on Win32 nor on Android.
I am still on testing and looking around in order to find the problem.
Any idea?
--- End quote ---
Do you have controls which completely cover the form? LCL-CustomDrawn will attempt to auto-detect this situation and if it is so, it will skip drawing the form (or for that matter any completely covered control).
Navigation
[0] Message Index
[#] Next page