Access violation when using TcxGridColumn with property BlobEdit - delphi

Application have TcxGrid that contains some columns. One column has property BlobEdit with BlobEditKind == bekMemo. When I open BlobEdit and leave form (by Alt+Tab or just click any place out of form), I get exceprion Access Violation with text "Project Project1.exe raised exception class $C0000005 with message 'access violation at 0x00748c1c: read of address 0x00000000'".
When I tried to debug it, I found that exception was created first in TcxCustomEdit.CMEnter.
How can I avoid this problem?
I`m using Delphi XE4 Update 1 and DevExpress 13.2.2.

I updated DevExpress and problem was solved.

Related

Getting Delphi to read a database with a new version of Microsoft Access

We use a Delphi 10 programme that reads in an Access database. I do not deeply understand how it does it, except that I believe it uses units called DAO.pas and DAO_TLB.pas.
I recently upgraded from Office 2007 to Office 2016, and since then the Delphi programme is unable to read from the database; it gives the error:
Project MyProj.exe raised exception class EOleSysError with message 'Class not registered'.
I have tried to search to find how to fix this but am struggling because I don't really understand what's going on under the hood. I tried to install the Access 2016 type library, but that didn't seem to make any difference.
Extremely grateful for any help.
Thanks,
Tom
EDIT: DAO.pas is here. DAO_TLB.pas is where the error is triggered; the function which errors is:
class function CoDBEngine.Create: _DBEngine;
begin
Result := CreateComObject(CLASS_DBEngine) as _DBEngine;
end;
Where CLASS_DBEngine is a constant declared as:
CLASS_DBEngine: TGUID = '{CD7791B9-43FD-42C5-AE42-8DD2811F0419}';
I have also just noticed that, when the error occurs, if I click continue rather than break, a new error appears, saying:
Class not registered, ClassID: {CD7791B9-43FD-42C5-AE42-8DD2811F0419}
i.e. the ClassID is the CLASS_DBEngine constant.

How to display line number where an exception happens during runtime without a debugger?

I have an exception happening during runtime which is non reproducible and therefore I can't debug it in the IDE/debugger. I want to know where in the code this happens so I surrounded the code with try/except statement, inserted a 'raise exception' statement for testing & displayed the stacktrace like this to see if it works:
on e: exception do begin
showmessage(e.StackTrace);
end;
However the message displayed was empty. Why was it empty? Is there another way to know where an exception happened? Using Delphi XE.
The Exception.StackTrace documentation indicates that the default implementation returns an empty string, and that in order to use the functionality you need to provide a GetStackInfoStringProc procedure. It also suggests some implementations (both free and commercial) from third-party providers that can be used instead of writing your own.
Here's a (brief) excerpt from that documentation - visit the documentation page for the related links:
By default, StackTrace is always an empty string. If you want StackTrace to contain an actual value, you must assign GetStackInfoStringProc a procedure that can generate a string from the stack information.
Using Exception.StackTrace
In order to use the StackTrace property to obtain the stack trace for exceptions, you have to use (or implement) a stack trace provider. There are a number of third-party solutions, both commercial and free.
Some of the stack trace providers are:
JEDI Code Library (the JclDebug and the JCLHookExcept unit).
EurekaLog
madExcept
For more information on how to use some of the above third-party stack trace providers, see the following blog posts:
Working with Delphi’s new Exception.StackTrace (Tobias Gurock, 2009).
CodeVerge - How to use Exception.StackTrace (2008).
However the message displayed was empty. Why was it empty?
Like Ken said, the StackTrace property is not implemented by default, per its documentation. You have to install a 3rd party exception logger with stack trace capabilities to hook up the StackTrace property.
Is there another way to know where an exception happened?
Without a viable stack trace, you would have to obtain the memory address of the code instruction where the exception actually occurred and then compare it to the list of addresses stored in the generated .map file for your compiled executable (if enabled in the Project Options, which is also necessary for stack tracing). With that, you can deduce which function the crashing code belongs to, but not necessarily the exact line of code.
If the exception is an EExternal-derived exception (like EAccessViolation), you can get the memory address from the EExternal.ExceptionRecord field (Windows only), or the EExternal.ExceptionAddress field (*Nix/OSX/iOS). Otherwise, use the System.ExceptAddr() function.
Another solution is to use synopse framework, take a look at TSQLLog class in the documentation.
You only have to generate map file (converting to .mab by the framework) and distribute it with your application.
Add this uses in your project file: Syncommons, momrmot and synlog.
uses
Vcl.Forms,
SynCommons,
mORMot,
SynLog,
F_calc in 'F_calc.pas' {Form1};
{$R *.res}
begin
TSQLLog.Family.Level := LOG_STACKTRACE; // LOG_VERBOSE
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
A log file will be generate.
You can read it with this sample program (in the framework):
Synopse\SQLite3\Samples\11 - Exception logging\logview.dpr

EReadError "Invalid property value" runtime error in Delphi XE4

When I open a form in Delphi XE4 IDE, there is no error message. However at runtime it is throwing strange error messages such as:
Exception class EReadError with message 'Invalid property value'.
Exception class EReadError with message 'Error reading Chart1.Color:
Invalid property value'.
The form contains a TChart (TTeeChart). The stored property value is "Color = clWindow", which seems completely valid. If I copy/paste this TChart control into a blank project, the properties are the same, however at runtime there is no error.
I tried to remove the line with "Color = clWindow" from the dfm file. In this case I do not get an error message, but the TChart is not visible at runtime. (Even though it is visible at design-time. The color is shown as TBtnFace)
Then, if I resize the form a bit (this causes ExplicitWidth/Height properties to be added), I get the following errors:
Exception class EReadError with message 'Property ExplicitWidth does not exist'.
Exception class EReadError with message 'Error reading Chart1.ExplicitWidth:
Property ExplicitWidth does not exist'.
(I have another form in the project that is also using TChart, and none of these problems occur with it.)
Any ideas what is causing this problem? It seems very strange.

How to supress Entry Point Not Found error on loading Delphi package?

I maintain a program written in Delphi 6. It loads some bpl package files dynamically using SysUtils.LoadPackage. Often I change something in the program that causes a package to fail to load. When this happens a message box appears and then an exception is thrown. The message box and exception are separate.
Here's an example of the message box:
---------------------------
Connect Manager: ConnectManager.exe - Entry Point Not Found
---------------------------
The procedure entry point #Connectmanagerplugin#TConnectManagerPluginClassList#UnRegister$qqrp17System#TMetaClass could not be located in the dynamic link library ConnectManagerPack.bpl.
---------------------------
OK
---------------------------
And here's the exception:
---------------------------
Debugger Exception Notification
---------------------------
Project ConnectManager.exe raised exception class EPackageError with message 'Can't load package Projects.bpl.
The specified procedure could not be found'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------
I can't see how to stop the message box from appearing. Any ideas accepted gratefully.
Solved!
I created a copy of SysUtils.LoadPackage in my application and edited this copy to pass a second param to SafeLoadLibrary.
So the call to SafeLoadLibrary now looks like:
Result := SafeLoadLibrary(Name, SEM_FAILCRITICALERRORS);
This helped: http://msdn.microsoft.com/en-us/library/ms680621%28VS.85%29.aspx.

RLINK32: Error opening file "...\Data.DFM". Occurs the first time I build a project after opening Delphi

I get this error the first time I build/compile a particular project after opening Delphi (D6 Pro). Subsequent builds do not give the error.
I have the same issue, it was fixed by replacing {$R *.dfm} directive in the problem unit (which was not found by Delphi during first compilation) by more specific clause {$R fMain.dfm}.
The error can be caused by an exception being raised in a design component on the form. If the component is running some initialisation code which raises an exception this error will be produced. This can be shown by adding
raise Exception.CreateFmt('Test', []);
into the code of the component. Note that in D6 Pro this does not produce 'Test' in the error message. The underlying exception message is not displayed.
This is probably caused by a control that raises an exception during its creation (when the form is loaded).
How I solved this (this case was specific for me, but a very similar solution may apply to you):
First I loaded the 'broken' unit into the IDE. It didn't caused an error until I pressed F12 to see the form. The error message raised by the IDE was not very helpful, but after changing the {$R *.dfm} to {$R MainForm.dfm}, the error message changed to something more specific. More exactly, in the error report, one line was of special interest:
{MyControls_XE.bpl} StrGrdBase.TBaseStrGrid.FixCursor (Line 569, "StrGrdBase.pas" + 9) + $8
I navigated to that line and I have seen that in some conditions I was trying to set focus on the second row, while the grid had only one row.
I also got the same error on Deplhi 2010, the problem was there was a component which has not been installed in IDE, when I changed the component to the one that exists it is worked as a charm.
I've found an additional reason for this behaviour: DFM files are rejected if a property is placed below any child objects owned by the main object. In other words, a TButton object should be defined below the last property of the TPanel object that the button is placed on. Tested with D2010, compiling with bcc32

Resources