Disable all Run time error messages in Delphi? - delphi

what is most standard and simple way to tell a prevent Delphi program to show ANY message windows when user run the exe?
for example this is my program with a web browser object, when site have errors that Geko component showing errors to user... i want to stop it.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleCtrls, MOZILLACONTROLLib_TLB;
type
TForm1 = class(TForm)
MozillaBrowser1: TMozillaBrowser;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses Unit1;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
MozillaBrowser1.Navigate('http://www.xeex.ir');
end;
end.

There's no way to do what you ask in general. You cannot apply a setting that will stop all error dialogs being shown.
For native Delphi exceptions, you can choose to ignore them if you wish. Not that that would be a good idea. For message boxes shown by third party code you need that code to offer a way to suppress those errors. If that mechanism exists, you can of course use it. But if no mechanism exists then you are out of luck. And every different library will use separate mechanisms.

Related

How to Pass an Object into a Second New Delphi Form

I have an object that is created on Form1 and I would like to be able to access one of its fields on Form2. I have tried to google it and nobody can give an answer that I can understand. Please excuse me but I am a novice.
Form1
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
Ttest=class
public
sName:string;
end;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
uses Unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
myObj:Ttest;
begin
myObj.Create;
myObj.sName := 'Name';
Form2.Show;
end;
end.
Form2
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm2 = class(TForm)
Button2: TButton;
procedure Button2Click(Sender: TObject);
end;
var
Form2: TForm2;
implementation
uses Unit1;
{$R *.dfm}
procedure TForm2.Button2Click(Sender: TObject);
begin
ShowMessage(myObj.sName);//This is not working
end;
end.
You have two forms that both use an object. You should define the object in a separate unit and list it in the Uses clause in the Interface section of both forms. Try using something already defined in a main library, like TStringlist, so you don't get confused with this part.
From what you're showing here, you're attempting to create an instance of that object in one form and do something with it in another form. That's a common thing to do: you may have one unit that asks for a filename and loads a file into a TStringList, then hands that over to another form or unit to deal with.
The way you're doing it, however, can be improved to reduce coupling between the two forms.
What you want to do is define a property like this in TForm2:
TForm2 = class( TForm )
. . .
private
Ftestobj : TTest; // or TStringlist
public
property testobj : TTest read Ftestobj write Ftestobj;
Then in TForm1.OnButtonClick do something like this:
form2.testobj := myobj;
form2.Show;
And then this becomes:
procedure TForm2.Button2Click(Sender: TObject);
begin
ShowMessage(Ftestobj.sName);
end;
I did a whole session in CodeRage 9 on this topic recently, in fact. It's entitled, "Have you embraced your inner plumber yet?" and it's all about moving data in and out of forms like this. (I call it plumbing code.)
Search for "coderage 9" and watch the video. At the end is a link where you can download my example code. That should keep you busy for a while. :)

Access main form from child unit in Delphi

I want to access a main form variable from a class that is called from the main from.
Something like this:
Unit1:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,Unit2, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
Chiled:TChiled;
const
Variable = 'dsadas';
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Chiled.ShowMainFormVariable;
end;
end.
Unit2:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TChiled = class
private
public
procedure ShowMainFormVariable;
end;
var
Form1: TForm1;
implementation
procedure TChiled.ShowMainFormVariable;
begin
ShowMessage(Form1.Variable);
end;
end.
if in Unit2 i add to uses Unit1 an circular errors pops up.
How to make the Unit1 to be GLOBAL?
As other answers tell, you should use one of the units in implementation section.
Suppose you chose in 'unit2' you'd use 'unit1' in implementation. then you need to devise a mechanism to tell the 'TChiled' how to access 'Form1'. That's because since you haven't used 'unit1' in interface section of 'unit2', you cannot declare the 'Form1:TForm1' variable in interface section. Below is just one possible solution:
unit2
type
TChiled = class
private
FForm1: TForm;
public
procedure ShowMainFormVariable;
property Form1: TForm write FForm1;
end;
implementation
uses
unit1;
procedure TChild.ShowMainFormVariable;
begin
ShowMessage((FForm1 as TForm1).Variable);
end;
then in unit1 you can set the Form1 property of TChiled before calling TChiled's method:
procedure TForm1.Button1Click(Sender: TObject);
begin
Chiled.Form1 := Self;
Chiled.ShowMainFormVariable;
end;
the simplest solution is to add Unit1 to a uses clause inside Unit2's implementation section as this gets around the circular reference.
However I'd suggest that this design is flawed. It is hard to see what you are trying to achieve with the sample code so it is difficult to offer any real advice.
Well, the simple naive answer is that you should add Unit1 to the uses clause of the implementation section of Unit2:
unit Unit2;
......
implementation
uses
Unit1;
.....
You can't add it to the uses clause in the interface section of Unit2 since that would create a circular reference at the interface section. In order words, the interface of Unit1 would uses Unit2, and the interface of Unit2 would use Unit1. The language does not allow that. The common solution is to use one of the units at the implementation level.
Having said that, your code is rather confused and fails in many other ways. Your problems run deeper than the circular reference. For example, what do you mean by Form1.Variable? The constant Variable is not a member of TForm1. You declare two global variables named Form1 of type TForm1. Why do you do that?
Also, you have spelled child incorrectly.
I generally create a Data Module (or any type of non-visual container) to share global variables. This way both units can use the variable without a circular reference.

DCEF TChromium Memory exception on start up

Another continuation of my previous question here.
In my previous question the project would not run and I was told that the DLL's that come with the component were simply in the wrong place. I moved them to the areas suggested (The output folder of the project I was working on) and the project did indeed run. However, a new error quickly revealed itself, as soon as TChromium attempts to navigate to any webpage, either through the defaulturl property or by use of the LoadURL procedure, the program throws a memory exception.
In particular the error notice says:
Debugger Fault Notification
Project faulted with message 'access violation at 0x00000000; read of address 0x00000000'
This particular error occurs on the end statement of the procedure that attempts to navigate.
To me this says that something is not being initialized properly, but this is simply a test project with nothing but a TChromium component and a TButton to navigate to 'http://www.google.com' on the form.
Source:
unit Test2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, cefvcl;
type
TForm1 = class(TForm)
Chromium1: TChromium;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Chromium1.Browser.getmainframe.LoadUrl('http://www.google.com');
end;
end.
Considering I can see no forum posts, or questions of this nature on this website I can only assume this is an isolated problem, probably caused by something I myself have done wrong, but for the life of me I cannot think what.
So my question is, does anyone know what is causing this error and have I simply made my project wrong?

Hide ComboBox Button Delphi without setting Style to csSimple

I am trying to hide the dropdown button in a third party component that derives from TComboBox.
I tried setting the style to csSimple, but this solution does not work for me... There is code in the third party component that checks for csSimple in various places. I would prefer not to change this code.
From what I can see from other posts, others have suggested using a different component, eg, a textbox, or covering the dropdown arrow with something to hide it. I want to avoid these solutions too.
Is there any other way? I was thinking maybe there is a way to do this with PostMessage/SendMessage, but I don't know what to pass as params.
Thank you
Serge Goncharov from AlphaControls came up with a very dark (but operational) solution to this. It involves access to the top two private variables of TDBLookupControl, FDataList and FButtonWidth.
His solution works as follows:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DBCtrls, sDBLookupComboBox, StdCtrls, sCheckBox, XPMan,
sSkinProvider, sSkinManager;
type
TForm1 = class(TForm)
DBLookupComboBox1: TDBLookupComboBox;
CheckBox1: TCheckBox;
procedure CheckBox1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
StoredWidth: integer;
implementation
{$R *.dfm}
type
TAccessLookUpCombo = class(TDBLookupControl)
public
FDataList: TPopupDataList;
FButtonWidth: Integer;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if CheckBox1.Checked then
TAccessLookUpCombo(DBLookupComboBox1).FButtonWidth := StoredWidth
else begin
StoredWidth := TAccessLookUpCombo(DBLookupComboBox1).FButtonWidth;
TAccessLookUpCombo(DBLookupComboBox1).FButtonWidth := 0;
end;
DBLookupComboBox1.Invalidate;
end;
end.
With the TAccessLookUpCombo(DBLookupComboBox1) construct, you access the parent's TDBLookupControl top values. Very ugly indeed, but it happens to work.

DUnit: How to run tests?

How do i run TestCase's from the IDE?
i created a new project, with a single, simple, form:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
private
public
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
end.
Now i'll add a test case to check that pushing Button1 does what it should:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses
TestFramework;
type
TForm1Tests = class(TTestCase)
private
f: TForm1;
protected
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestButton1Click;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
//todo
end;
{ TForm1Tests }
procedure TForm1Tests.SetUp;
begin
inherited;
f := TForm1.Create(nil);
end;
procedure TForm1Tests.TearDown;
begin
f.Free;
inherited;
end;
procedure TForm1Tests.TestButton1Click;
begin
f.Button1Click(nil);
Self.CheckEqualsString('Hello, world!', f.Caption);
end;
end.
Given what i've done (test code in the GUI project), how do i now trigger a run of the tests? If i push F9 then the form simply appears:
Ideally there would be a button, or menu option, in the IDE saying Run DUnit Tests:
Am i living in a dream-world? A fantasy land, living in a gumdrop house on lollipop lane?
Adding a TestCase to the main project is not the way to go. You should create a separate TestProject (you can have it in the same ProjectGroup as the main project), add a TestCase and run.
I agree with Uwe Raabe, but sometimes it can be useful to have a 'hidden' link within your app to run the DUnit GUI. I use:
TGUITestRunner.runRegisteredTests;
Call this from your button at the DUnit GUI will open for you to manually run and view test output.
For example, if you hold down a special key combination when opening the software's own "Control Panel", you get some advanced entries:
I like the idea of having a 'Run DUnit tests' command in the IDE.
It could be implemented by checking for a DUnit project in the same folder, having the same name as the current project:
Project1.dpr -> the software under test
Project1.Tests.dpr => the DUnit test app
In this case, the IDE should enable the Run DUnit tests command.
After executing the tests, a list of all failed tests should be displayed which allows to jump to the source line where a test failed.
If tests caused memory leaks, a list of all leaks should be displayed which allows to jump to the source line where the memory leak has been created
(DUnit can be configured to detect memory leaks and fail tests when one has been found)

Resources