I've written a Vcl Metro application with several forms that I have to open sequentially.
I'm using Rad Studio 10.1 Berlin
I've added a button on every form to miminize application if user need it.
The issue happens when:
1) Open main form
2) Open second form
3) Open third form
4) Minimize application
5) Restore application.
At point 5 (when click on desktop bar to maximize application) the application will show Form2 instead of form3
The code
//On Main form (Form1)
procedure TForm1.Button2Click(Sender: TObject);
begin
if not Assigned(form2) then
form2:=tform2.Create(self);
form2.show;
form2.BringToFront;
end;
//On Second form (Form2)
procedure TForm2.Button2Click(Sender: TObject);
begin
if not Assigned(form3) then
form3:=tform3.Create(self);
form3.show;
form3.BringToFront;
end;
//On third Form
procedure TForm3.Button1Click(Sender: TObject);
begin
APPLICATION.Minimize;
end;
Related
Delphi 10.4 FMX desktop project
I create a form and set its FormStyle to StayOnTop. The window works as expected, staying on top of other windows in the project.
But when the app goes into the background, this form stays on top of all other apps. How do get this window to go into the background like all the other windows in the project?
did you try to make OnActivate and OnDeactivate on **MainForm** ? :
procedure TForm1.FormActivate(Sender: TObject);
begin
if Assigned(Form2) then
Form2.FormStyle := TFormStyle.StayOnTop;
end;
procedure TForm1.FormDeactivate(Sender: TObject);
begin
if Assigned(Form2) then
Form2.FormStyle := TFormStyle.Normal;
end;
This is my first post here so please forgive me if I am not doing it right.
I am using Delphi 7 on my Windows 10 machine. When I use the TOpenDialog I get garbage in the filename property on close. This is what I get back þƒ‡uÔÁ™ßðæRw. I created a simple form with a button and a edit box to show the problem here. Could someone please assist me.
The code is below.
procedure TForm1.Button1Click(Sender: TObject);
begin
opendialog1.Execute();
end;
procedure TForm1.OpenDialog1Close(Sender: TObject);
begin
edit1.Text := opendialog1.FileName;
end;
Don't use the OnClose event of the dialog. That is invoked after the underlying dialog object, which owns the file name data, has been destroyed.
Instead respond to the dialog when Execute returns.
procedure TForm1.Button1Click(Sender: TObject);
begin
if opendialog1.Execute() then
edit1.Text := opendialog1.FileName;
end;
Note that you must also test the return value of Execute to handle the user cancelling the dialog.
I have developed an android app that will run in some Asus Android 7 tablets in a firm but I find a very weird behavior. This application is very small and easy; it has:
A button to store 2 string values taken from 2 edits
A TTabControl with 3 pages and each of them has a TWebBrowser inside.
A button on the top to execute some javascript code.
You can see a picture here taken from win32. Below there is the code which is pretty easy and (I guess) without errors. I am under firemonkey of course.
type
TForm1 = class(TForm)
// ... declarations ...
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
FLinea: string;
list: TStringList;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
//I take the text from the 3 edits you can see above (picture) and I save a txt file
procedure TForm1.Button1Click(Sender: TObject);
var salva: TStringList;
begin
/*just for debug purpose...*/
if ( (Length(EditLinea.Text) > 0) and (Length(EditOperatore.Text) > 0) and (Password.Text = 'abc123') ) then
begin
FLinea := TPath.Combine(TPath.GetHomePath, 'operatore.txt');
salva := TStringList.Create;
salva.Add(EditLinea.Text);
salva.Add(EditOperatore.Text);
salva.SaveToFile(FLinea);
ShowMessage('Saved! Restart the app.');
end
else
begin
ShowMessage('Wrong password!');
end;
end;
//when I press the STOP button above I execute a javascript function that is defined in the page loaded in the browser
procedure TForm1.Button2Click(Sender: TObject);
begin
WebBrowser.EvaluateJavaScript('stopExec();');
end;
//Here I just check if a txt file exists and I load it
procedure TForm1.FormCreate(Sender: TObject);
begin
//HERE I CHECK IF THERE IS A TXT FILE THAT I NEED TO LOAD
FLinea := TPath.Combine(TPath.GetHomePath, 'operatore.txt');
if (FileExists(FLinea)) then
begin
list := TStringList.Create;
list.LoadFromFile(FLinea);
LabelImpiegato.Text := 'OPERATORE '+list.Strings[1];
WebBrowser.URL := 'www.aaa.com/loader.php?linea='+list.Strings[0]+'&operat='+list.Strings[1];
WebBrowser.EnableCaching := false;
WebBrowser.Navigate;
end
else
begin
//error
TabControl.Visible := false;
Error.Visible := true;
end;
end;
Problem: the application works correctly but after some time (in general 10/15 min) it crashes. The error message is "The application has suddenly stopped". Could it be something wrong with my code?
I really doubt that it might be a power-saving configuration on the tablet. I really don't know what to do because I was looking for something like a form OnException property but no luck.
Could it be the javascript code that clashes with TWebBrowser? Look:
function start() {
myVar = setInterval(myTimer, 1000);
myVar2 = setInterval(orologio, 1000);
}
Basically that is a function that is called when the page opens (body onload) and the setInterval is like the delphi TTimer. With a period of 1000ms it executes the function on 1st argument. It works perfectly on Firefox and as Win32 app.
I have solved my problem, this is an issue that is not related to Delphi (or javascript). The application crashes due to an update of Google's Webview service that is causing problems on applications like the one I have (applications with a web browser inside).
I have uninstalled the updates on Google's webview and now the application works properly. Of course Delphi's TWebBrowser relies on the webview service and so uninstalling the update was the solution.
As I typed this question I realize that it probably should.
Docking a form to a TPageControl calls FormShow when form.Create() is called and when form.ManualDock(pagecontrol,pagecontrol.alClient) is called.
Un-docking the form also calls show and I assume this is because the form is actually 'reset' when you dock/undock?
If this is as designed I'll just refactor the code I dont want to fire there to onCreate (unless that is bad design).
If should or not is more philosophical than technical question. The TForm.OnShow event is fired by performing control message CM_DOCKCLIENT which is used also by the ManualDock function. Internally this message calls the CM_SHOWINGCHANGED what fires the event itself.
In the following example I will use two forms, Form1 (with a page control and a button) and Form2 (empty and dockable). I presume that both are auto created.
The following code is a proof that the OnShow event is fired by the CM_DOCKCLIENT control message. Clicking on the button, the CM_DOCKCLIENT message is performed and Form2's OnShow event is fired.
Code for Form1
procedure TForm1.FormShow(Sender: TObject);
begin
Form2.Show;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
DockObject: TDragDockObject;
begin
DockObject := TDragDockObject.Create(Form2);
try
// sending the CM_DOCKCLIENT message internally performs also the
// CM_SHOWINGCHANGED message which triggers the TForm.OnShow event
PageControl1.Perform(CM_DOCKCLIENT, WPARAM(DockObject), LPARAM(SmallPoint(0, 0)));
finally
DockObject.Free;
end;
end;
And Form2 has only the OnShow event handler
procedure TForm2.FormShow(Sender: TObject);
begin
ShowMessage('FormShow');
end;
An easy workaround is not to dock the Form2 manually by its own (in the OnShow event) but dock it by the creator or let's say by the form which displays it. In my previous example I've displayed the Form2 in the Form1.OnShow event, so I can easily dock it manually there.
procedure TForm1.FormShow(Sender: TObject);
begin
Form2.Show;
Form2.ManualDock(PageControl1);
end;
procedure TForm2.FormShow(Sender: TObject);
begin
// no manual docking of this form by itself
end;
This seems to only happen in IE6
I have an activex form written in Delphi 7. A dialogue window opened from within the activex control in IE6 gets displayed on the taskbar - the users (for some reason) do not want the dialogue to show in the taskbar.
So I set the dialogue's borderStyle to bsToolwindow. This hides the dialogue from the taskbar but also has the (side-) effect of hiding IE from the task list in windows, which means that you cannot <alt>Tab back to IE if you tabbed away.
Question: How to hide the activex pop-up dialogue from the taskbar but still have IE6 listed in the tasklist?
Set the owner window of your form to be the activex form (or perhaps the ie window). You can achieve this f.i. by passing the activex form as the owner component while you're creating your form and overriding CreateParams of the instantiated form:
// in the activex form's unit
procedure TActiveFormX.Button1Click(Sender: TObject);
var
f: TForm;
begin
f := TForm1.Create(Self);
f.BorderStyle := bsToolWindow;
f.Show;
end;
// in the dialog unit
type
TForm1 = class(TForm)
private
protected
procedure CreateParams(var Params: TCreateParams); override;
[...]
[...]
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WndParent := TCustomForm(Owner).Handle;
end;