Calling "application.processmessages" from unit - "application" is undeclared - delphi

I'm using Delphi 7. I'm trying to add a procedure with a call to "application.processmessages" in a non-VCL unit. I get the error "undeclared identifier: application".
How do I reference the TApplication class from a non-vcl unit? Where in the documentation is this described? It is hard to find due to the broad use of the term "application".

Add Forms to the uses clause of your unit. Eg:
uses Forms;

Well, if you do it then your unit becomes a VCL (-dependent) unit, are you sure that's the right way to go?
Application is a global variable in the Forms unit.

Related

OTL can't be compiled under D2007

I downloaded the OTL http://www.omnithreadlibrary.com/
and compile the D2007 grouproj, install the package, without problem.
I then create a simple console application that uses OtlParallel unit, of course, I add the OtlParallel and some other pas files to the project.
But it complains that Generics.Collections is not found.
The documentation says:
High-level abstractions are implemented in the OtlParallel unit. They are all created through the factory class Parallel. High-level code intensively uses anonymous methods and generics which makes Delphi 2009 the minimum supported version.
This us of both generics and anonymous methods makes this unit completely incompatible with Delphi 2007.
If you wish to use a construct like Parallel.For with Delphi 2007 and OTL then you will have to back-port OtlParallel yourself. Without anonymous methods this is very difficult to do and achieve the same fluid style of code. You would have to use procedural types instead of anonymous methods. And you would have to implement closures manually.
So instead of using
TProc = reference to procedure;
you would use
TMethod = procedure of object;
And then to implement this you create a class or record with a parameterless method. You'll need to add whatever state is needed as members of the type, and populate those members. That is in essence a manual implementation of a closure with variable capture. And you'll need to deal with lifetime. Make sure that the instances outlive the parallel loop.
Good luck!

Which version of IMalloc should I use in Delphi?

I'm trying to refactor a Delphi 5 project in Delphi XE, to do that I need to fix some errors in a unit called BrowseDr. The error I'm getting is
[DCC Error] BrowseDr.pas(1033): E2033 Types of actual and formal var parameters
must be identical
line 1033: SHGetMalloc(FShellMalloc);
"MyShlObj":
//SHGetMalloc declaration
function SHGetMalloc(var ppMalloc: IMalloc): HResult; stdcall;
Now the IMalloc used in the declaration of FShellMalloc is derived from a OLE2.IMalloc
while the one used in "MyShlObj" is from ActiveX.IMalloc.
Is it possible alter one of them?
If yes, is it recommended?
The OLE2 unit was used by older Delphi versions, this unit was replaced by the ActiveX unit, so now you must use the ActiveX types in your new project.
The only alteration I think will work is to make sure that FShellMalloc is derived from the same interface as the one used from MyShlObj.
Modify either one to use the same IMalloc as the other.
Check your uses clause. A lot of third party code uses compiler directives to load the correct unit. Changing Compiler version will often result in the wrong file being loaded.
DFS is a classic example. Go to DFS.INC and ensure an appropriate DFS_COMPILER_xxx is defined.

getting around circular references in Delphi [duplicate]

This question already has answers here:
Delphi Enterprise: how can I apply the Visitor Pattern without circular references?
(4 answers)
Closed 8 years ago.
Is there a way of getting around circular unit references in Delphi?
Maybe a newer version of delphi or some magic hack or something?
My delphi project has 100 000+ lines of code mostly based on singleton classes. I need to refactor this, but that would mean several months of "circular reference" hell :)
I've been maintaining close to a million lines of legacy code for the past 10 years so I understand your pain!
In the code that I maintain, when I've encountered circular uses, I frequently have found that they are caused by constants or type definitions in unit A that are needed by unit B. (Sometimes it's also a small bit of code (or even, global variables) in Unit A that is also needed by unit B.
In this situation (when I'm lucky!) I can carefully extract those parts of the code into a new unit C that contains the constants, type definitions, and shared code. Then units A and B use unit C.
I post the above with some hesitance because I'm not an expert on software design and realize there are many others here who are far more knowledgeable than I am. Hopefully, though, my experience will be of some use to you.
It seems you have quite serious code design issues. Besides many signs of such issues, one is the circular unit reference. But as you said: you cannot refactor all the code.
Move all what is possible to the implementation section. They are allowed to have circular references.
To simplify this task you can use 3rd party tools. I would recommend
Peganza Pascal Analyzer - it will suggest what you can move to the implementation section. And will give you many more hints to improve your code quality.
Use the implementation section uses whenever possible, and limit what's in the interface uses clause to what has to be visible in the interface declarations.
There is no "magic hack". Circular references would cause an endless loop for the compiler (unit A requires compiling unit B which requires compiling unit A which requires compiling unit B, etc.).
If you have a specific instance where you think you cannot avoid circular references, edit your post and provide the code; I'm sure someone here can help you figure out how to get it fixed.
There is many ways to avoid circular references.
Delegates.
Way too often, an object will execute some code that should be done in an event instead than being done by the object itself. Whether it is because the programmer working on the project was too short on time(aren't we always?), didn't have enough experience/knowledge or was just lazy, some code like this eventually end up in applications. Real world exemple : TCPSocket component that directly update some visual component on the application's MainForm instead of having the main form register a "OnTCPActivity" procedure on the component.
Abstract Classes/Interfaces. Using either of them allow to remove a direct dependance between many units. An abstract class or an interface can be declared alone in its own unit, limiting dependancies to a maximum. Exemple: Our application has a debug form. It has uses on pretty much the whole application as it displays information from various area of the application. Even worse, every form that allows to show the debug form will also also end up requiring all the units from the debug form. A better approach would be to have a debug form which is essentially empty, but that has the capacity to register "DebugFrames".
TDebugFrm.RegisterDebugFrame(Frame : TDebugFrame);
That way, the TDebugFrm has no dependancies of its own (Except than on the TDebugFrame class). Any and all unit that requires to show the debug form can do so without risking to add too many dependancies either.
There are many other exemple... I bet it could fill a book of its own. Designing a clean class hierarchy in a time efficient fashion is pretty hard to do and it comes with experience. Knowing the tools available to achieve it and how to use them is the 1st step to achieve it. But to answer your question... There is no 1-size-fit-all answer to your question, it's always to be taken on a case by case basis.
Similar Question: Delphi Enterprise: how can I apply the Visitor Pattern without circular references?
The solution presented by Uwe Raabe uses interfaces to resolve the circular dependency.
Modelmaker Code Explorer has a really nice wizard for listing all the uses, including cycles.
It requires that your project compiles.
I agree with the other posters that it is a design issue.
You should carefully look at your design, and remove unused units.
At DelphiLive'09, I did a session titled Smarter code with Databases and data aware controls which contains quite few tips on good design (not limited to DB apps).
--jeroen
I found a solution that doesn't need the use of Interfaces but may not resolve every issues of the circular reference.
I have two classes in two units: TMap and TTile.
TMap contains a map and display it using isometric tiles (TTile).
I wanted to have a pointer in TTile to point back on the map. Map is a class property of TTile.
Class Var FoMap: TObject;
Normaly, you will need to declare each corresponding unit in the other unit... and get the circular reference.
Here, how I get around it.
In TTile, I declare map to be a TObject and move Map unit in the Uses clause of the Implementation section.
That way I can use map but need to cast it each time to TMap to access its properties.
Can I do better? If I could use a getter function to type cast it. But I will need to move Uses Map in the Interface section.... So, back to square one.
In the Implementation section, I did declare a getter function that is not part of my class. A Simple function.
Implementation
Uses Map;
Function Map: TMap;
Begin
Result := TMap(TTile.Map);
End;
Cool, I thought. Now, every time I need to call a property of my Map, I just use Map.MyProperty.
Ouch! Did compile! :) Did not work the expected way. The compiler use the Map property of TTile and not my function.
So, I rename my function to aMap. But my Muse spoke to me. NOOOOO! Rename the Class Property to aMap... Now I can use Map the way I intented it.
Map.Size; This call my little function, who typecast aMap as TMap;
Patrick Forest
I gave a previous answer but after some thinking and scratching I found a better way to solve the circular reference problem. Here my first unit who need a pointer on an object TB define in unit B.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, b, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
FoB: TB;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
FoB := TB.Create(Self);
showmessage(FoB.owner.name);
end;
end.
Here the code of the Unit B where TB has a pointer on TForm1.
unit B;
interface
Uses
dialogs, Forms;
type
TForm1 = class(TForm);
TB = class
private
FaOwner: TForm1;
public
constructor Create(aOwner: TForm);
property owner: TForm1 read FaOwner;
end;
implementation
uses unit1;
Constructor TB.create(aOwner: TForm);
Begin
FaOwner := TForm1(aOwner);
FaOwner.Left := 500;
End;//Constructor
end.
And here why it compiles. First Unit B declare the use of Unit1 in the implementation section. Resolving immediately the circular reference unit between Unit1 et Unit B.
But to allow Delphi to compile, I need to give him something to chew on the declaration of FaOwner: TForm1. So, I add stub class name TForm1 who match the declaration of TForm1 in Unit1.
Next, when come the time to call the constructor, TForm1 is able to pass itself has the parameter. In the constructor code, I need to typecast the aOwner parameter to Unit1.TForm1. And voilĂ , FaOwner his set to point on my form.
Now, if the class TB need to use FaOwner internally, I don't need to typecast it every time
to Unit1.TForm1 because both declaration are the same. Note that you could set the declaration of to constructor to
Constructor TB.create(aOwner: TForm1);
but when TForm1 will call the constructor and pass itself has a parameter, you will need to typecast it has b.TForm1. Otherwise Delphi will throw an error telling that both TForm1 are not compatible. So each time you call the TB.constructor you will need to typecast to the appropriate TForm1. The first solution, using a common ancestor, his better. Write the typecast once and forget it.
After I posted it, I realized that I made a mistake telling that both TForm1 were identical. They are not Unit1.TForm1 has components and methods that are unknown to B.TForm1. Has long TB doesn't need to use them or just need to use the commonality given by TForm you're okay. If you need to call something particular to UNit1.TForm1 from TB, you will need to typecast it to Unit1.TForm1.
I try it and test it with Delphi 2010 and it compiled and worked.
Hope it will help and spare you some headache.

How to access delphi function at DPR scope

I have a problem with maintenance on an old Delphi program (D7). A lot of the program logic is in the DPR file (this is not a windowed program), with some units providing things like access to the database. We need to get some debug out of the DB unit, but the debug functionality is in the DPR. We can't easily strip the debug functionality out, because it uses stuff that's unique to the DPR, like its main pipe. Separating it out would be like trying to tease apart spaghetti and meatball sauce.
So how do we call a function that's declared at the DPR scope from a subordinate used unit? What's the equivalent of the :: operator in C++ ?
Please don't tell me to redesign the app. I'd love to, but we won't be given the necessary time. Plus if we redesigned this puppy, it wouldn't be in Delphi.
You can declare a method variable in the unit that matches the signature of the function in the DPR. At the very beginning of the program you set the method variable to the function. Inside the unit you call the method variable.
Example:
(DPR)
uses
Unit1;
function DoSomething(Par: Integer): Integer;
begin
...
end;
...
begin
DoSomethingVar := DoSomething;
...
end;
(unit)
unit Unit1;
interface
...
var
DoSomethingVar: function(Par1: Integer): Integer;
...
implementation
...
SomeResult := DoSomethingVar(SomeParameter);
...
You can't. The unit hierarchy is rigid.
There are two possible options:
pull out the relevant parts of the .dpr to a new unit. Keep in mind that moving uses to the implementation can break import cycles. The createform* stuff probably isn't safe to move, that would probably upset the project manager.
or define a few callback functions (function,method types, like functionpointer in C), and move code out of the relevant unit initialization to a procedure that you call from the .dpr if necessary.
I don't know how to use functions from .dpr in other units, but if you have to change code simply change .dpr to normal unit and then use it's functions/routines in new .dpr and in others units.
.dpr is the most fundmental pascal project file.
We can use any unit files in the project, and so, you can use
the functions/procedures in the units.
If necessary, you can prefix the unit name for accessing the
function/procedure.
If the function/procedure belongs to specific class, you need
to create an instance to access the function/procedure because
it's a method.
Anyway, Delphi uses object pascal as its core, you can access
any necessary method/procedure/function/properties with legal
pascal concepts and object pascal concepts.
No matter which file you need to call it, and the only one except
is the decalaration file for some external library.

Setting Up Event Handler in Delphi 2007 and Getting "Parameter Lists Differ" Error

I'm trying to write a class in Delphi 2007 that uses a ActiveX library. The class will catch an event that the ActiveX library has to expose its own event that adds some information to the ActiveX library's event.
The bottom line is that when I assign my own procedure to the ActiveX library's event that I want to use, I get an error:
E2009 Incompatible types: 'Parameter lists differ'
I'm certain the parameter lists are the same (same number of parameters and same types) so I'm thinking I'm going about it the wrong way.
Any suggestions or can someone post some sample code of what I'm trying to do?
The first thing to check is that the thing you're trying to assign to the event property is a method. It needs to be a procedure or function that belongs to a class; it can't be a standalone subroutine.
Next, note that merely confirming that the names of the types match isn't enough. Delphi allows redefining an identifier, so the type name you see in one unit isn't necessarily referring to the same thing when you see the same identifier in another unit. The meaning can even change in the middle of a unit. For example:
unit Example;
interface
uses Windows;
var
foo: TBitmap;
implementation
uses Graphics;
var
bar: TBitmap;
end.
The foo variable has type Windows.TBitmap, a record type, whereas bar has type Graphics.TBitmap, a class type.
You can let the IDE help you diagnose this: Ctrl+click on the identifier names and let the IDE take you to their declarations. Do they take you to the same places? If not, then you can qualify the type names with the unit names. For example, we could change the bar declaration above to this:
var
bar: Windows.TBitmap;
Now it will have the same type as foo. Check for the same sort of thing in your event-handler declaration.
I used gabr's advice with the Ctrl+click and discovered that one of the parameters was a constant which I did not realize. I changed the second variable to a const and it worked fine. Thanks.

Resources