no refreshing FMX Controls - delphi

I have simple fmx form(Delphi 10.2 Tokyo):
in code I show Button2 for second:
procedure TForm6.FormCreate(Sender: TObject);
begin
Button2.Visible :=false;
end;
procedure TForm6.Button1Click(Sender: TObject);
begin
Button2.Visible := true;
TTask.Create(procedure
begin
Sleep(1000);
TThread.Synchronize(nil, procedure
begin
Button2.Visible := false;
//tries
//Button2.Repaint;
//Layout1.Repaint;
//Self.InvalidateRect(Self.Bounds);
//Application.ProcessMessages;
end);
end).Start;
end;
but after button2 hides, artefact appears. Its gone after manually form resize.
How to force it to refresh?

You need to use
ShadowEfect1.UpdateParentEffects;

Related

Block form resize and show a hint when hovering

Delphi 11
How to make it so that when you hover the cursor over the resizing of the form, a cross appears with some inscription like: "Do not resize" and it was impossible to resize the form?
I need to block my first form resize when I call my second form. I'm quite new to Delphi, can you help me, please?
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show;
Form1.Caption:= 'Main';
Form1.BorderStyle:= bsSingle;
//And Form1.OnCanResize() or in some other way?
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Form1.Caption:= 'Main Form';
Form1.BorderStyle:= bsSizeable;
Form2.Hide;
end;
The question is settled.
"If you don't like the answer it's doesn't mean that it's not right. But continue to delete my comments :)"
It's so sad when professionals cannot help you but only express arrogance. Carry on, you are so funny)
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show;
Form1.Caption:= 'Main';
Form1.BorderStyle:= bsSingle;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Form1.Caption:= 'Main Form';
Form1.BorderStyle:= bsSizeable;
Form1.Cursor:= crDefault;
Form1.Hint:= '';
Form1.ShowHint:= False;
Form2.Hide;
end;
procedure TForm1.Timer1Timer(Sender: TObject); //Interval = 1
var
pt: TPoint;
Width, Heigth: Integer;
begin
GetCursorPos(pt);
if Form2.Visible then
begin
if (ScreenToClient(pt).X > ClientWidth - 10) or (ScreenToClient(pt).Y > ClientHeight - 10) then
begin
Cursor:= crNo;
Hint:= 'No resize';
ShowHint:= True;
end
else
begin
Cursor:= crDefault;
Hint:= '';
ShowHint:= False;
end;
end;
end;

Occasional stuck splash screen (win 7 embedded)

I have an application that restores windows on startup but this results in a potential flicker as each window is created and positioned.
To get around this I have the splash screen (stretched to the full size of the screen) set to "StayOnTop" and close it after the OnShow event using a TTask. The problem is that occasionally the splash screen gets stuck. If you click where buttons should be they redraw and show correctly.
I have tried to "invalidate" all WinControls but this problem still shows up.
I have never seen the problem in the debugger.
Are there any other tricks anyone can suggest to forcing a full repaint of the screen?
Here is my code to close the splash - This is in the OnShow of the main form.
aTask := TTask.Create(procedure()
begin
Sleep(800);
TThread.Synchronize(nil, procedure()
begin
fSplash.Close;
FreeAndNil(fSplash);
DoInvalidate(self);
end);
end);
aTask.Start;
Here is my attempt to invalidate everything...
Procedure DoInvalidate( aWinControl: TWInControl );
var
i: Integer;
ctrl: TControl;
begin
for i:= 0 to aWinControl.Controlcount-1 do
begin
ctrl:= aWinControl.Controls[i];
if ctrl Is TWinControl then
DoInvalidate( TWincontrol( ctrl ));
end;
aWinControl.Invalidate;
end;
Martin
You don't need to recursively invalidate everything, just invalidating the Form itself is sufficient.
If you upgrade to 10.2 Tokyo, you can now use TThread.ForceQueue() instead of TThread.Synchronize() in a TTask:
procedure TMainForm.FormShow(Sender: TObject);
begin
TThread.ForceQueue(nil, procedure
begin
FreeAndNil(fSplash);
Application.MainForm.Invalidate;
end
);
end;
If you stick with TTask, you should at least use TThread.Queue() instead:
procedure TMainForm.FormShow(Sender: TObject);
begin
TTask.Create(procedure
begin
TThread.Queue(nil, procedure
begin
FreeAndNil(fSplash);
Application.MainForm.Invalidate;
end;
end
).Start;
end;
Or, you could just use a short TTimer, like zdzichs suggested:
procedure TMainForm.FormShow(Sender: TObject);
begin
Timer1.Enabled := True;
end;
procedure TMainForm.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
FreeAndNil(fSplash);
Invalidate;
end;
Or, you could assign an OnClose event handler to the splash form to invalidate the MainForm, and then PostMessage() a WM_CLOSE message to the splash form:
procedure TMainForm.FormCreate(Sender: TObject);
begin
fSplash := TSplashForm.Create(nil);
fSplash.OnClose := SplashClosed;
fSplash.Show;
end;
procedure TMainForm.FormShow(Sender: TObject);
begin
if fSplash <> nil then
PostMessage(fSplash.Handle, WM_CLOSE, 0, 0);
end;
procedure TMainForm.SplashClosed(Sender: TObject; var Action: TCloseAction);
begin
fSplash := nil;
Action := caFree;
Invalidate;
end;
Or, use the OnDestroy event instead:
procedure TMainForm.FormCreate(Sender: TObject);
begin
fSplash := TSplashForm.Create(nil);
fSplash.OnDestroy := SplashDestroyed;
fSplash.Show;
end;
procedure TMainForm.FormShow(Sender: TObject);
begin
if fSplash <> nil then
fSplash.Release; // <-- delayed free
end;
procedure TMainForm.SplashDestroyed(Sender: TObject);
begin
fSplash := nil;
Invalidate;
end;

Determine which form in activepage, delphi

I have a mainform (frmMain) with a pagecontrol. The pagecontrol is populated at startup by several forms, let us say Form1, Form2, and Form3
procedure TForm1.FormCreate(Sender: TObject);
begin
ManualDock(frmMain.PageControl1);
show;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
ManualDock(frmMain.PageControl1);
show;
end;
procedure TForm3.FormCreate(Sender: TObject);
begin
ManualDock(frmMain.PageControl1);
show;
end;
That works great.
When I then change activepage, I want the OnActivate method called on the form corresponding to the activepage, so I tried this;
procedure TfrmMain.PageControl1Change(Sender: TObject);
begin
with pagecontrol1 do
begin
lbHeading.Caption := activepage.Caption;
with tform(activepage) do // <= This does
if assigned(onactivate) then // <= not
onactivate(self); // <= work
end;
end;
Activepage is of type TTabsheet
I found a solution:
with pagecontrol1 do
begin
with tform(activepage.controls[0]) do
if assigned(onactivate) then
onactivate(self);
end;

Delphi7, repeat sounds using Tmediaplayer

i am using delphi7. I want put a song in my program, but i don't want it to end never. I tried using a timer, but it didn't play the music:
procedure TForm1.FormCreate(Sender: TObject);
begin
timer1.enabled:=true;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var playsound,destination:string;
begin
destination:=paramstr(0);
playsound:=extractfilepath(destination)+'Soundtrack\play.wma';
mediaplayer1.FileName:=playsound;
mediaplayer1.Open;
mediaplayer1.Play; //USING TMEDIAPLAYER
end;
There are no syntax errors in this code, however the song is not running, perhaps the timer is not for that job. How should i do it? Thanks
The TMediaPlayer is a control, so you should naturally not use it unless you want precisely its GUI.
If you only want to play a audio file repeatedly, use the PlaySound function in MMSystem.pas:
PlaySound('test.wav', 0, SND_FILENAME or SND_NODEFAULT or SND_ASYNC or SND_LOOP)
Don't use a timer for this. Use the TMediaPlayer.OnNotify event instead:
procedure TForm1.FormCreate(Sender: TObject);
begin
mediaplayer1.FileName := extractfilepath(paramstr(0))+'Soundtrack\play.wma';
mediaplayer1.Notify := true;
mediaplayer1.Wait := false;
mediaplayer1.Open;
end;
procedure TForm1.MediaPlayer1Notify(Sender: TObject);
begin
case mediaplayer1.Mode of
mpOpen, mpStopped: begin
if mediaplayer1.Error = 0 then begin
mediaplayer1.Notify := true;
mediaplayer1.Wait := false;
mediaplayer1.Play;
end;
end;
end;
end;

how to add or remove windowMenu option of actionMenuBar

I want to know, how to add or remove windowMenu option of actionMenuBar component, i have a mdi aplication i can add the option but later I can't remove it
sorry my english
i have this:
//add windowmenu and works fine
procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.ActionMainMenuBar1.WindowMenu := '&Ventana';
end;
//remove windowmenu but dont work
procedure TForm2.Button2Click(Sender: TObject);
begin
Form1.ActionMainMenuBar1.WindowMenu := '';
end;
type
ActionMainMenuBarAccess = class(TActionMainMenuBar);
procedure TForm2.Button2Click(Sender: TObject);
begin
ActionMainMenuBar1.WindowMenu := '';
ActionMainMenuBarAccess(ActionMainMenuBar1).FWindowMenuItem := nil;
ActionMainMenuBarAccess(ActionMainMenuBar1).RefreshMDIMenu;
end;
See also this QualityCentral report.

Resources