Unable to open file 'STDCTRLS.OBJ' - delphi

First of all, sorry for my bad english.
I started with Delphi today, created a simple form example named test.
unit teste;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm2 = class(TForm)
Edit1: TEdit;
Label1: TLabel;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
end.
I searched at google, then here and did not find an answer for this problem, I´m not able to run it, because the logs return these errors:
[ILINK32 Error] Fatal: Unable to open file 'STDCTRLS.OBJ'
I had no idea how to fix it, could you help me?
Thanks!
best regard´s.

It looks like you've created a C++Builder project, but written/pasted in Delphi code. Delphi doesn't use ILINK at all, and it doesn't use STDCTRLS.OBJ (it would complain about StdCtrls.dcu instead).
Since you have no functional code in the project, I'd just start over. Use File|Close All, and don't save changes. Then use File|New|VCL Forms Application - Delphi for Win32, and hit F9 to see if you can run that project.

Make sure the IDE's search paths are configured correctly, and that the project has correct references to the RTL and VCL packages.

Related

Delphi database microsoft odbc manager data source name not found and not default driver

I am getting this error with my delphi code below after following this tutorial: Delphi 7: ADO, need basic coding example . I have seen other solutions however I am unsure what they really mean or what I should actually do. I was wondering if someone could see if there was an obvious problem or explain what I should be checking. Error I am getting on the ADOConnection1:=TADOConnection.create(nil) line.
[Microsoft][ODBC MANAGER] data source name not found and default driver not specfied
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,ADODB,Stdctrls, DB;
type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
procedure createdb;
procedure closedb;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
Procedure TForm1.createdb;
var
nameDB:string;
connectionstring:string;
begin
connectionstring:='Provider=Microsoft.ACE.OLEDB.12.0;Data
Source=E:\Project;';
namedb:='Project1db.accdb';
ADOConnection1:=TADOConnection.Create(nil);
ADOConnection1.LoginPrompt:=false;
ADOConnection1.Connected:=true;
ADOConnection1.Execute('CREATE DATABASE IF NOT EXISTS
Project1db.accdb',cmdtext);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
createdb;
closedb;
end;
Procedure TForm1.closedb;
begin
ADOConnection1.Free;
end;
end.
Assuming your Project1db.accdb already exists in E:\Project, the way to set
up your AdoConnection is as follows:
In the IDE, click your AdoConnection and set its LoginPrompt property to False.
Click the [...] button in the ConnectionString property
In the ConnectionString pop-up, click the Use Connection String radiobutton then
click the Build button below it.
On the Provider tab, set the Provider type to
Microsoft.ACE.OLEDB.12.0
On the Connection tab, set the Data Source to
e:\Project\Project1db.accdb
Then click the Test Connection button. You should get a pop-up confirming that
the connection succeeded.
If the Project1DB.accdb file doesn't already exist, you could use #Victoria's for example this link to create it or use MS Access to do it. But you will still need something like your existing code to open the database.
As I said in a comment, you shouldn't be calling ADOConnection1 := TAdoConnection.Create(Nil) so delete that line and the one ADOConnection1.Free. I hope you can understand now that you can use the Object Inspector to configure the AdoConnection, etc.
Btw, I'm sorry if my comment on one of your questions yesterday confused you into trying to use ODBC (which is fine if you are the administrator of your machine but can be trickier if you aren't). To use an existing ODBC datasource, you would need to set the AdoConnection's Provider type to something like Microsoft OLE DB Provider for ODBC Drivers, rather than any of the Access-specific providers - ODBC is a generic way of working with various different types of database (including Access). Btw, you can use an ODBC dsn to create an Access database, as an alternative to creating the database using the ADOX objects as per the article #Victoria linked.

DELPHI exception calls EAccess Violation

There was a question similar to this however the user was using something way more advanced so I was quite confused.
This is the procedure the exception flares up. Specifically on the ADOCon.connected line. I am using the dbgo stuff and Microsoft access for my database.
The exception I am getting is: EAcessViolation. I'm wondering what mistake I've made to cause it and how to solve it. I have run the procedure on both with a pre-existing database and a new one. When there is a pre-existing database the exception is one the 19th line and without it is on the 14th line. As a user has mentioned, I have read the documentation however I am still confused on how to solve the error. The error is definitely here as this is the first piece of access I call.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,DB, ADODB,ComObj;
type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
ADOCom:TADOcommand;
ADOCon:TADOConnection;
ADOQ:TADOQuery;
nameDB:string;
db:OLEVariant;
begin
namedb:='Brill.accdb';
if not fileexists(namedb) then
begin
db:=createOLEObject('ADOX.Catalog');
db.create('Provider=Microsoft.ACE.OLEDB.12.0;Data Source='+nameDB+';');
db:=null;
ADOCon.connectionstring:='Provider=Microsoft.ACE.OLEDB.12.0;Data Source='+
nameDB+';';
ADOCon.connected:=True;
ADOCon.loginprompt:=False;
end
else
ADOCon.connectionstring:='Provider=Microsoft.ACE.OLEDB.12.0;Data Source='+
nameDB+';';
end.
Your code is riddled with errors.
When you declare variables of a particular class type in your code, you're responsible for creating an instance of that class and assigning it to the variable before using it, and cleaning up when you're finished with it.
var
ADOCon: TAdoConnection;
ADOCom:TADOcommand;
ADOQ:TADOQuery;
begin
ADOCon := TADOConnection.Create(nil);
try
// Set up connection properties here
ADOQ := TADOQuery.Create(nil);
try
// Set up ADOQ properties and use query here
finally
ADOQ.Free;
end;
finally
ADOCon.Free;
end;
end;
Also, your use of the db: OleVariant (and all code related to it) is doing absolutely nothing. You get an instance, assign properties to that instance, and then throw it away, which means you can just delete that variable and the three lines of code related to it entirely; they serve zero purpose.
Of course, the better solution than any of the above is to add a TDataModule to your form, drop a TADOConnection and TADOQuery on it, set the properties in the Object Inspector or the OnCreate of the datamodule. You can then move that datamodule into the list of available forms, move it up to be created before your main form, and have access from anywhere in your app that uses that datamodule, and the datamodule will free everything properly when you exit your application. It also separates all of the database code from your user interface, cleaning up your code considerably.

Can't load package %s error while installing a package

I'm testing on Delphi 2007 and my groupproject is composed by 2 packages.
PackageRun.bpl
It's marked as "runtime only" and contains a unit named "uMyTestRun.pas" in which is defined an empty TFrame descendant:
unit uMyTestRun;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TMyTest = class(TFrame)
private
{ Private declarations }
public
{ Public declarations }
end;
implementation
{$R *.dfm}
end.
PackageDes.bpl
It requires PackageRun.bpl, it's marked as "designtime only" and contains a unit named "uMyTestDes.pas" in which I wrote the following code:
unit uMyTestDes;
interface
uses
Classes,
uMyTestRun;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('MyComponents', [TMyTest]);
end;
end.
Output directories of both packages are in Library paths (Inside there are bpl, dcp and dcu).
Trying to install PackageDes.bpl (Component, Install Packages..., Add...), I'm getting the following error:
Can't load package C:\<...>\PackageDes.bpl. Impossibile trovare il
modulo specificato.
The last part of the message is in my OS's language, in english it should be something like "Can't find specified module". (My OS is Windows 10 Pro 64bit).
PackageDes.bpl is exactly in the same path shown in the error message (C:\<...>\PackageDes.bpl).
After some tests, I found that the error disappear by removing the following line from uMyTestDes.pas unit:
RegisterComponents('MyComponents', [TMyTest]);
Is there something wrong in my code/projects/environment?
Run Process Monitor from http://SysInternals.com and set the filters to intercept only file operations ( toolbar rightmost buttons ) of your Delphi IDE process (check the process name in TaskManager or shortcut properties (it is bds.exe for Delphi XE2), then add the filter similar to Include / Process Name / Ends With / bds.exe ).
Then clear the log in PM, switch to Delphi and try to load the package, then as soon as error pops up switch back to PM and stop capturing events. Try to do it fast as you can, for example do not waste your time closing error box.
Now you would get a trace of file I/O activity of Delphi loading the package of yours (and some other background activity noise - the faster you do the less noise there'd be). In that trace look for all the errors and see where and which package Delphi tries to find.
You can also try Microsoft Dependency Walker or similar tools to se if your Design-Time BPL has all the DLL-dependency tree resolvable. Personally I usually use Unreal/Total commander with FileInfo plugin or ntCore CFF Explorer.
Easy way to solve this issue is to add a post build action to your run time project:
copy "$(OUTPUTDIR)\$(OUTPUTFILENAME)" "$(BDSCOMMONDIR)\Bpl"
The command above copies your run time file to the default IDE Bpl location.
I had a similar issue. In my case I had the same library name in a different Delphi version BPL path. I found out the solution for my issue looking at the comments above, so this is only a reminder for basic things to check:
BPL path have to be included in your OS path variable;
Search for a BPL module with the same name in other OS path before the right one (mutiple Delphi version installations).
Try to change the register procedure to uMyTestRun unit.
unit UMyTestRun;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;
type
TMyTest = class(TFrame)
private
{ Private declarations }
public
{ Public declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('MyComponents', [TMyTest]);
end;
end.
Now, the package will install correctly.
Regards.

EFilererror exception in Delphi 7

I have registered the package TMS Unicode Component Pack in my Delphi 7 containing TNT components.
This package contains a class named TTntCustomComboBox which I use to create my own custom component named Combobox2 :
unit Combobox2;
interface
uses
Windows, Messages, Classes, Graphics, Controls, StdCtrls, ImgList, ActiveX, SysUtils, TntStdCtrls, TntWindows;
type
TCombobox2 = class(TTntCustomComboBox)
...
procedure Register;
begin
RegisterComponents('Standard', [TCombobox2]);
end;
...
I've added this component (TCombobox2) to the package dclusr.dpk.
Compiling dclusr.dpk works but installing the package raises an exception :
Registration procedure Combobox2.Register in package C:\program files\Delphi7\Projects\Bpl\dclusr.bpl raised an exception class EFilererror : A class named TTntCustomComboBox already exists
So, how do I fix that ?
Thanks for help.
The error message indicates that your package is trying to register a component that is already registered, namely TTntCustomComboBox.
It's not obvious from the details that you have provided why this would happen. One possible reason would be if you included the TNT components in your package instead of referencing that in your package's requires clause. Another possible reason would be if your Register function attempted to register TTntCustomComboBox. This could happen if your actual declaration of TCombobox2 was like so:
TCombobox2 = TTntCustomComboBox;
Put {$WEAKPACKAGEUNIT ON} after unit caption.

Access to public methods and properties inside a Delphi BPL

I have an application that loads a BPL that as inside a simple form.
This form is an optional option of the main application.
The BPL loads correctly, the form is shown correctly, but I don’t know how to access the public methods and properties of the form inside the bpl.
Can anyone provide a simple example?
my code:
// Load the BPL on aplication Load
LoadPackage( 'About.bpl' );
// CAll for TForm1 inside the About.BPL
var
AClass: TClass;
AForm: TForm;
begin
AClass := GetClass('TForm1');
if AClass <> nil then
begin
Application.CreateForm(TComponentClass(AClass), AForm);
AForm.Show;
end;
// The unit TForm1 inside the BPL package
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
PublicMthd;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
Procedure TForm1.PublicMthd;
Begin
ShowMessage('Inside call');
End;
initialization
RegisterClass(TForm1);
finalization
UnRegisterClass(TForm1);
end.
How can i access "PublicMthd" in Tform1 ?
One of the interest of having TOptionalForm in a dynamically loaded bpl (assuming this from the "optional" bit)) is to avoid for your application to hold the definition of the TOptionalForm class specifically (it's in the unit contained in the package and only there).
That means that your application cannot know anything about it unless you use either:
- a shared base Class
- an Interface declaring the properties and methods you want to access
- some basic RTTI to access published properties and methods
- some extended RTTI to access public properties and methods (if you have D2010 or later)
- some external routines from the bpl accepting a base class parameter (or TObject/pointer) typecasting it as TOptionalForm internally.
This is very vague and general and more precision about your code would be needed to refine...
If you need to load the BPL dynamically, you should use - as already metioned by François:
an abstract class (which is more Delphi-like or)
an interface (which I consider cleaner and have better experience with)
placed into an interface-only unit used by both the main application and the form BPL.
I use an intermediate "contract/interface" BPL, statically used by both the main application and the dynamically loaded ones.
In the case of interface usage, may also look at the $WEAKPACKAGEUNIT directive to further decouple the BPL fom the application.
To comment on the comments - by using DLL exports or RTTI, you would basically bypass the whole point of BPLs, which is type and namespace sharing.

Resources