Delphi - E2003 Undeclared Identifier Issue - delphi

I've got a really bizarre issue occurring in the Delphi XE2 IDE.
In one package, I have the following classes declared:
TCommandInfo = class
private
fParameters : TCommandParameters;
// other fields...
public
property Parameters : TCommandParameters read fParameters;
// other properties...
end;
TReceiveCommand = class(TCommand)
// other fields and properties
private
fInfo : TCommandInfo;
public
property Info : TCommandInfo read fInfo;
end;
TReceiveErrorCommand = class(TReceiveCommand);
TReceiveDataCommand = class(TReceiveCommand)
// procedures and properties defined, etc.
end;
Now in a completely different package which depends on the package above, I have this member function:
procedure DoDataCommand;
var
cmd : TReceiveDataCommand;
success : Boolean;
params : TCommandParameters;
begin
cmd := TReceiveDataCommand.Create;
success := cmd.Initialize;
if success then begin
// #### ERROR HERE ####
params := cmd.Info.Parameters;
end;
end;
What I'm seeing is that when trying to compile the dependent package, I get an E2003 error saying "Undeclared identifier: 'Info'" and when I CTRL+CLICK on the TReceiveDataCommand to take me to the declaration, the IDE jumps to a different location in the containing packages source file.
I have this very same code running on my machine at work and this works without fail. I'm wondering if there are some lingering BPL's lurcking around somewhere however I've had a good clear out.
It seems odd that the IDE takes me to the wrong location when trying to jump to the TReceiveDataCommand class source.
Any suggestions please?

The TReceiveCommand type is defined in a different package. The compiler uses the .dcp file to resolves names in that different package. If Info is not recognised then clearly the .dcp file that the compiler is finding does not match the source code in the question.
The logical conclusion is that the compiler is finding an out of date .dcp file.

I have had this happen only when I migrated from Xe6 to xe7. It was linking in both the xe6 stuff and xe7. As the project conversion/migration had not done its job. I would check the paths in the dproj files.
And now for a completely obvious question - have you rebuilt ?

Related

Delphi ZeosLib [Incompatible types: 'TZConnection' and 'TZAbstractConnection']

I have a system in Delphi 7 with zeos 6 in wich i use the following function:
function zIncCodeByYear (zQry : TZquery; ....): String;
var
zConLocal, zConOriginal : TZConnection;
...
begin
bActive := zQry.Active;
zConOriginal := zQry.Connection;
This always worked fine, Now I need to convert this system to Delphi Seatle and, consequently, to Zeos trunk (7.2), after to install this version, in time compile, I get the error:
[dcc32 Error] zeosfuncs.pas(265): E2010 Incompatible types: 'TZConnection' and 'TZAbstractConnection'
What happens? how to get the connection from zquery in this version?
You can simply use ZAbstractConnection and casting to TZConnection does not make a difference for you. Whatever you do is not wrong in this specific case.
With the help of TZConnection a few properties such as Database, Protocol, ... are being published. In the base class TZAbstractConnection those are public.
You haven't really provided much code. But presumably Zeos changed the type of TZQuery.Connection to TZAbstractConnection. So it should suffice for you to change your local variable declaration as follows:
var
zConLocal, zConOriginal : TZAbstractConnection;
And also remember the principle: Program to an interface, not an implementation (Unfortunately the accepted answer on that question is brilliantly amusing, but wrong. At least the answer I linked is correct.)

Delphi: missing interface declarations for UI Automation methods

Such a basic question, but I'm stuck...
I'm trying to get started with UI Automation using Delphi 2007 (Win32) on Windows 7. It seems I don't have declarations for some of the methods and types I need to use. I have .NET Framework 4.x installed on this machine, but I imported a type library from C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\UIAutomationClient.dll...which in UIAutomationClient_TLB.pas I see is:
UIAutomationClientMajorVersion = 1;
UIAutomationClientMinorVersion = 0;
I'm not sure if that's the problem (wrong version). I can declare the following with no problem:
var
UIAuto: IUIAutomation;
Element: IUIAutomationElement;
But methods of IUIAutomationElement appear to be missing. For instance, there's nothing in the interface declaring the method:
IUIAutomationElement.TryGetCurrentPattern()
...which, according to msdn.microsoft.com is an interface method going back to at least .NET 3.0.
Where / how do I get the necessary interface declarations? Is this possibly a registration problem? If so, what needs to be registered, and how?
Ultimately, I'm wanting to play with retrieving text from controls via UI Automation with something like the following, but technically speaking, I think you have to get code to compile before you can consider it a failure. ;)
var
UIAuto: IUIAutomation;
Element: IUIAutomationElement;
RetVal: HResult;
APattern: AutomationPattern; //not defined!
ValuePattern : ValuePattern; //not defined!
begin
UIAuto := CoCUIAutomation.Create;
Element := UIAuto.GetFocusedElement(RetVal);
if Assigned(Element) then begin
if Element.TryGetCurrentPattern(ValuePattern.Pattern, APattern) then begin //not defined!
Result := ValuePattern.Current.Value; //not defined!
...
end;
It looks like you have imported the .net assembly.
From native code it is best to import the native COM type library. The steps are:
Component | Import Component.
Import a Type Library.
Select UIAutomationClient which is implemented in UIAutomationCore.dll.
This imports a type library and creates a unit named UIAutomationClient_TLB.
The method that you need is IUIAutomationElement.GetCurrentPattern. The TryGetCurrentPattern method in the .net version of the interface is simply a convenience method that indicates failure with a boolean return value rather than by raising an exception. When you call IUIAutomationElement.GetCurrentPattern you will need to check the HRESULT return value to detect failure.
You are importing a .NET class as a COM object. In .NET, classes and methods have to be explicitly declared as COMVisible=True to be accessible via COM. Without seeing how UIAutomationClient.dll actually exports its AutomationElement class, my guess would be that its TryGetCurrentPattern() method is not declared a COM-visible.
The IUIAutomationElement interface exported from UIAutomationCore.dll, on the othe hand, does not have a TryGetCurrentPattern() method.

Delphi F2084 Internal Error: AV07953449-R26D7474C-0

In my project, i'm trying to connect one more UNIT, named Lang_Unit.pas with some classes and procedures, but, while compiling the Project, Delphi gives unknown error called "[dcc32 Fatal Error] Lang_Unit.pas(5): F2084 Internal Error: AV07953449-R26D7474C-0".
And the point is that, what if i will close my project, or remove this connected UNIT, error is not getting away.
And if i will create clear default VCL Application, its still gives this error.
And only when i'm restarting my Delphi 2010, error is getting away.
But, if i will try to edit something in the code, this error is comes again...
What is problem ? Everything was works fine, im not touched nothing.
I've just turned off my PC, then after some time turned it ON and opened my Project and edited my code, then i see this error...
If Its will help, here is my Lang_Unit.pas code :
unit Languages_UNIT;
interface
Uses
System.Generics.Collections, IniFiles;
Type
TLanguages_List = Class
private
LangType:string;
LangDescription:string;
LangFile:TIniFile;
public
Constructor Create(LType,LDes:string; LFile:TiniFile);
Function GetLangType:string;
Function GetDescription:string;
Function GetStructure:TIniFile;
End;
TLanguages_Controller = Class
public
Function GetStructureByType(RequestedType:string; LangList:TObjectList<TLanguages_List>):TIniFile;
Function TypeExists(RequestedType:string; LangList:TObjectList<TLanguages_List>):Boolean;
Procedure LoadLanguage(RequestedType:string; LangList:TObjectList<TLanguages_List>);
End;
implementation
uses Unit1;
Constructor TLanguages_List.Create(LType,LDes:string; LFile:TiniFile);
Begin
LangType:=LType;
LangDescription:=LDes;
LangFile:=LFile;
End;
Function TLanguages_List.GetLangType:string;
Begin
Result:=LangType;
End;
Function TLanguages_List.GetDescription:string;
Begin
Result:=LangDescription;
End;
Function TLanguages_List.GetStructure:TIniFile;
Begin
Result:=LangFile;
End;
Function TLanguages_Controller.GetStructureByType(RequestedType:string; LangList:TObjectList<TLanguages_List>):TIniFile;
var
i:integer;
Begin
For i := 0 to LangList.Count-1 Do
Begin
IF(LangList[i].GetLangType=RequestedType) Then
Begin
Result:=LangList[i].GetStructure;
Break;
End;
End;
End;
Function TLanguages_Controller.TypeExists(RequestedType:string; LangList:TObjectList<TLanguages_List>):Boolean;
var
i:integer;
GOTYA:Boolean;
Begin
GOTYA:=False;
For i := 0 to LangList.Count-1 Do
Begin
IF(LangList[i].GetLangType=RequestedType) Then
Begin
GOTYA:=True;
Break;
End;
End;
IF(GOTYA) Then
Result:=True
Else
Result:=False;
End;
Procedure TLanguages_Controller.LoadLanguage(RequestedType:string; LangList:TObjectList<TLanguages_List>);
var
i:integer;
SLS:TIniFile;//SELECTED LANGUAGE STRUCTURE
CS:string;//CURRENT SECTION
Begin
//GET SELECTED LANGUAGE STRUCTURE
For i := 0 to LangList.Count-1 Do
Begin
IF(LangList[i].GetLangType=RequestedType) Then
Begin
SLS:=LangList[i].GetStructure;
Break;
End;
End;
//START LOADING SELECTED LANGUAGE
//TABS SECTION LOAD
CS:='TABS';
SD_DEFNAME:=SLS.ReadString(CS,'Speed_Dials','Speed_Dials');
Form1.goleft.Hint:=SLS.ReadString(CS,'Back','Back');
Form1.goright.Hint:=SLS.ReadString(CS,'Forward','Forward');
REFLESHBTN_TEXT:=SLS.ReadString(CS,'Reflesh','Reflesh');
STOPBTN_TEXT:=SLS.ReadString(CS,'Stop','Stop');
//PAGE_POPUP SECTION LOAD
CS:='PAGE_POPUP';
Form1.ChromiumPopup.Items[0].Caption:=SLS.ReadString(CS,'Forward','Forward');
Form1.ChromiumPopup.Items[1].Caption:=SLS.ReadString(CS,'Back','Back');
Form1.ChromiumPopup.Items[2].Caption:=SLS.ReadString(CS,'Reflesh','Reflesh');
Form1.ChromiumPopup.Items[3].Caption:=SLS.ReadString(CS,'Copy_Link','Copy Link');
Form1.ChromiumPopup.Items[4].Caption:=SLS.ReadString(CS,'Save','Save');
Form1.ChromiumPopup.Items[5].Caption:=SLS.ReadString(CS,'Print','Print');
Form1.ChromiumPopup.Items[6].Caption:=SLS.ReadString(CS,'view_source','View Source');
Form1.ChromiumPopup.Items[7].Caption:=SLS.ReadString(CS,'code_debug','Code Debug');
End;
end.
Internal error means that the compiler itself is in a 'confused' state.
The way to get out of this is to:
Save your code in a safe location for later reference.
Restart Delphi
Revert the source code to the last known good state by undoing your last edits, or by loading a temp save file.
You can find the previous files in the _backup folder.
Make sure to set file type to any file.
In order to have Delphi generate a save file upon compilation you need to enable autosave
It's a good idea to have Delphi keep more than the default 10 saves. I like to set it to the max: 90.
Just keep restarting Delphi, and compile a previous version, until the internal error goes away.
Then you just recreate the code in a slightly different manner.
(You did save the original code right?)
I also had this problem (in Delphi 10 Berlin). It started shortly after I changed the name of a component in a frame. It also seemed very persistent. However I found the by right clicking the project and selecting 'Clean' followed by 'Build' solved the problem.
I had this issue with my system drive's memory less than 300mb left. It was especially choking in the cache folder. Prior to this error I had a sensible error (fatal error DBG) when I was attempting to recurse already async functions into a larger async function in a big multi threaded application. The compiler just gave up!(perhaps for circular references and too many subfunctions of a function) The two errors may not be related. But after freeing the system drive to about 2 Gigs upon restart and correcting the above mistake, I did a clean then it compiled just fine.
In my case, the solution for the F2084 error code was to change the encoding from ANSI to UTF8.
In my case, I made several packages that related one to another, and all were built as design and run time packages. But one day, I changed some of them to run-time only packages. After that I experienced this kind of error. It took me hours to realize that I should rebuilt all other related packages. After doing that, the error was away eventually.

Does Delphi incremental linker correctly track distinct types?

An example with types with the same identity (TLevel and integer)
unit UnitType;
interface
type
TLevel = integer;
TObj = class
public
procedure Test(Level: TLevel);virtual;
end;
There's another unit where another object inherits from this object (Notice integer instead of TLevel, but this is not a problem since they're not distinct)
unit UnitOther;
interface uses UnitType;
type
TInhObj = class(TObj)
public
procedure Test(Level: integer);override;
end;
Everything compiles as usual.
Now I modify TLevel type to be distinct
TLevel = type integer;
and try to compile, but everything compiles fine.
I go to UnitOther and change something unrelated (even just resave it). Now I have "declaration of Test differs from previous declaration" in unit UnitOther
Is this correct actions or a bug that was fixed in latest versions of Delphi? (mine is 5)
I'm using Delphi XE and it still behaves exactly as you described. One workaround is to periodically run the Build event (i.e. before you commit your code). This isn't a very eloquent solution but at least it will allow the changed typed to be detected without having to touch all the files that use it.

Trouble with THTML file GDIPL2A.pas

Running a project and was getting an error saying
"Not enough actual parameters"
The error is in "C:\Program Files\PBear\HTMLComponents\package\GDIPL2A.pas".
The mistake pointed three times to "inherited Create;" lines 260,270 and 278 . In the file "GDIPL2A.pas".the Code is:-
var
err: integer;
begin
inherited Create;
err := GdipCreateBitmapFromScan0(W, H, 0, PixelFormat32bppARGB, nil, fHandle);
if err <> 0 then
raise EGDIPlus.Create('Can''t create bitmap');
end;
I was wondering why it would show an error in "THTML" files, WHICH ARE NOTHING BUT FILES FROM THE INSTALLATION of THTML.I did not even touch THTML files.
Kindly help
Thanks and Regards
Vas
A "Not enough actual parameters" error on "inherited Create;" means that you're trying to call an inherited constructor but it not supplying any parameters. Check the class you're inheriting from and you'll see a Create that requires some parameters. (If the base class doesn't have one, check its parent, and its parent and so on. You'll find one eventually.) It should be pretty obvious once you find the constructor declaration what you need to pass to it.
Your call needs to look something like:
inherited Create(param1, param2);
I have THTML, and it indeed includes GDIPL2A.pas, which is a wrapper around GDIPlus; apparently THTML uses GDIPlus to display embedded images or something.
A quick look at the declaration of TGPImage and TGpBitmap shows the constructor declarations of each:
// TGpImage
public
constructor Create(FileName: string; TmpFile: boolean = False); overload;
constructor Create(IStr: IStream); overload;
// TGpBitmap
public
constructor Create(W, H: Integer); overload;
constructor Create(IStr: IStream); overload;
You'll see that all of the constructors takes at least one or two parameters; your call to inherited Create passes none. However, since the call to inherited is in another constructor it should work (and indeed does on my machine; I just tried rebuilding one of the demos from THTML and it recompiled GDIPL2A.pas fine), You've got something else going on, like a different version of GDIPL2A in your path that the compiler is using instead of the one you're seeing in the IDE's editor.
As to your question, I answered it in the first paragraph above. It's reporting the error in THTML because that's the copy of GDIPL2A that the compiler is using, which may not be the one your code is expecting it to use.
You can fix that by either:
Reordering units in the uses clause of your code so that all calls that cause GDIPL2A to compile are using the same one;
Copy the GDIPL2A your code thinks it's using into your project's source folder, so it will be compiled from there. This will probably break THTML if you're using it in that same project, so be ready for that;
Find and resolve the competing copies of GDIPL2A so that there's only one copy available on the compiler's search path;
Remove the THTML path from your project's search and library paths, if you're not using it in your problem project. You can also, using Project|Options|Packages, prevent THTML from even being loaded when you open the project if you'd like, to make your project load faster.
I don't know if anybody read this anymore but my problem occurred during installing of ThtmlViewer. My solution was to edit the GDIPL2A.pas file. I just added an emty string and a false boolean, so the 3 create statements looked like this:
inherited Create('', False);
And then everything worked fine (at least so far)
(I have an old Delphi 4 on an old Windows Xp on an old PC, not connected to internet)
Kindly
Erling

Resources