I did it by creating OLE object with Delphi in 2000/NT/XP as following:
Voice := CreateOLEObject('SAPI.SpVoice');
Voice.speak(...)
But this does not work in Vista, how can I make my program simply speak some text in Vista?
I just tried (D2009 on Vista Home Premium) with the following code and it works!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComObj;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Voice: Variant;
begin
Voice := CreateOLEObject('SAPI.SpVoice');
Voice.speak('Hello World');
end;
end.
FYI, there is a nice paper on using speech in Delphi programming by Brian Long...
(Very) Late Update:
For why it might not work in Vista and give an EZeroDivide exception outside the IDE, see this other SO question: Delphi SAPI Text-To-Speech
Related
I've downloaded Delphi XE7 and having some problems with accessing another Units...
I need to call procedures from another units, so I'll give a very basic illustration, simple program...
This is code from main Unit1 with form and button1:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, Unit2;
type
TForm1 = class(TForm)
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
ShowMessage('Hello');
end;
end.
And this is the code from Unit2:
unit Unit2;
interface
implementation
uses Unit1;
end.
Now, how is it possible to make procedure Button1Click like in Unit2 to showmessage let's say HelloFromUnit2 when button1 on form1 is clicked? Unit2 is codeUnit without anything..
Use the build in procedure for calling the Click handler
Leave form 1 the way it is:
unit Unit2;
interface
implementation
uses
Unit1;
procedure Click;
begin
if Assigned(Form1) then
Form1.Button1.Click;
end;
end.
Add a procedure declaration to the public section of TForm1, like this
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
Procedure SayHello;
end;
...
procedure TForm1.SayHello;
begin
ShowMessage('Hello');
end;
end.
Then in Unit2 you would call this procedure. You would have to ensure that Form2 has already been instantiated - or create a new instance for your call.
Do not use this mechanism for event handlers!
The header of your post doesn't match the question in the text
"Call Button1Click in Form1/Unit1 from Unit2" vs.
"Now, how is it possible to make procedure Button1Click like in Unit2 to showmessage let's say HelloFromUnit2 when button1 on form1 is clicked?"
I answer the question in the text (as I understand it). If this is not what you intended, you might want to rephrase the question in the text.
Add, to Form1.Button1Click, a call to a new procedure in unit2
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Hello');
SayHelloFromUnit2; // <---- add this
end;
In unit2 add the following to the interface section:
procedure SayHelloFromUnit2;
and to the implementation section
uses Vcl.Dialogs;
procedure SayHelloFromUnit2;
begin
ShowMessage('Hello from unit2');
end;
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. :)
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.
I've downloaded free DBX driver from here.
I am trying to make it work since two days now, without success.
Here is the snapshot of my code:
unit uMainForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, SqlExpr, WideStrings, DBXDynalink, DB;
type
TMainForm = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
procedure TMainForm.Button1Click(Sender: TObject);
var C: TSQLConnection;
begin
C := TSQLConnection.Create(Self);
try
C.DriverName := 'FirebirdConnection';
C.LibraryName := 'dbxfb4d12.dll';
C.VendorLib := 'fbclient.dll';
C.GetDriverFunc := 'getSQLDriverFIREBIRD';
C.Params.Add('User_Name=SYSDBA');
C.Params.Add('Password=masterkey');
C.Params.Add('Database=C:\MyDB.fdb');
C.Open;
if C.Connected then
ShowMessage('Connection is active')
finally
C.Free;
end;
end;
After running the test I am receiving error: "Unable to load fbclient.dll(ErrorCode 22). It may be missing from the system path."
I have required libraries in my application path, I have them even in the System32 path. I am not using dbxdrivers.ini and dbxconnections.ini.
So what is going on here? I have Delphi 2009 with latest updates.
Thanks for your time.
Did you also try to put the fbclient.dll file in the same folder as the executable?
Sometimes it's necessary to have the fbclient.dll renamed to gds32.dll. It might do the trick.
After adding a IdUDPServer to my form and trying to put some code into the OnUDPRead event, I'm not able to add any component to my form at design time, nor can I run the application.
is there any way to solve this ?
There are two bugs with this event handler. To fix them, you can
remove the System. from TArray<System.Byte> (in the interface and implementation)
add IdSocketHandleto the uses list in the interface
I have not investigated further but after these changes the code can be compiled.
So the full code would like be
unit Unit12;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,
IdSocketHandle, // <-- added
IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient, IdUDPServer;
type
TForm12 = class(TForm)
IdUDPClient1: TIdUDPClient;
IdUDPServer1: TIdUDPServer;
procedure IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
AData: TArray<Byte>; ABinding: TIdSocketHandle);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form12: TForm12;
implementation
{$R *.dfm}
procedure TForm12.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
AData: TArray<Byte>; ABinding: TIdSocketHandle);
begin
//
end;