I tried transfer of my Project from XE8 to XE10.1
DataSnap Client Module have SQLConnection1: TSQLConnection
When I set property Driver.ConnectTimeout to any value, then set Connected=true, I get error:
"SetConnectTimeout"
Without any value in Driver.ConnectTimeout set connection is OK.
What my error?
You are not doing anything wrong. Embarcadero did.
In Delphi 10 Seattle (I don't have XE8), the implementation of the Data.DbxHTTPLayer.TDSHTTPNativeClient.SetConnectTimeout method is:
procedure TDSHTTPNativeClient.SetConnectTimeout(AMilisec: Integer);
begin
FHTTP.ConnectTimeout := AMilisec;
end;
In Delphi 10.1 Berlin, the same method looks like this:
procedure TDSHTTPNativeClient.SetConnectTimeout(AMilisec: Integer);
begin
raise ENotImplemented.Create('SetConnectTimeout');
end;
I edited the source (Data.DbxHTTPLayer.pas) to:
procedure TDSHTTPNativeClient.SetConnectTimeout(AMilisec: Integer);
begin
FHTTPClient.ConnectionTimeout := AMilisec;
//raise ENotImplemented.Create('SetConnectTimeout');
end;
And it solved the problem. The original .dcu and .o initially prevented the change from actually being linked into my app, so I added Data.DbxHTTPLayer.pas to my project (this was probably not the correct way to do it).
Related
My Delphi application has a form that uses the Acrobat Reader ActiveX control for viewing pdfs. When I use the control's functions (LoadFile, gotoNextPage, gotoPreviousPage, gotoFirstPage, gotoLastPage), then close the form, I get the following error: "Access violation at address 6AF5703C. Read of address 6AF5703C". When I run the app, but do not use the control's functions, and then close the form, the app will exit without error.
Anyone know of a fix or workaround for this issue?
My app is written using Delphi 5 (legacy app). I have Adobe Acrobat Reader DC v15.016.20045 installed.
As I said in a comment to Zam, with the current version downloaded today of Acrobat Reader DC , I get the exact same error as you.
Please try this code and let us know whether it avoids the error for you, because it certainly works for me and there is no AV, either in the FormClose or afterwards.
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
Ref : Integer;
begin
Ref := AcroPdf1.ControlInterface._AddRef;
AcroPdf1.Src := '';
AcroPdf1.Free;
AcroPdf1 := Nil;
end;
This is my FormCreate, which contains my only other code.
procedure TForm1.FormCreate(Sender: TObject);
begin
AFileName := 'd:\aaad7\pdf\printed.pdf';
AcroPdf1.src := AFileName;
AcroPdf1.setZoom(200); // <- this line is to exercise the
// ControlInterface to provoke the AV on shutdown
end;
I have absolutely no idea why my FormClose avoids the AV problem, and before anybody else says so, yes, it looks mad to me, too! Hardly something that deserves the name "solution", but maybe it will suggest a proper solution to someone who knows more about COM and Ole controls than I do.
I originally included the Ref := AcroPdf1._AddRef just as an experiment. I noticed that after it, Ref's value was 9. After AcroPdf1.Src := '', calling AcroPdf1._Release in the debugger evaluator returned a value of 4. I was about to see if the AV was avoided by forcing the RefCount down by repeatedly calling _Release but then Presto!, there was no AV after my first trace into FormClose exited.
Update: I have not tested the following exhaustively, but this simplified FormClose also avoids the AV, on my system at any rate:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
Ref : Integer;
begin
Ref := AcroPdf1.ControlInterface._AddRef;
end;
Obviously, omitting the assignment to Ref shouldn't make any difference.
I'm using Delphi 10 Seattle on 64-bit Win10, btw.
The better solution is to edit the TPDF Object in "AcroPDFLib_Tlb.pas"
Just add the proper destructor to the Code to free the OLE Object:
Declaration
Type
TAcroPDF = class(TOleControl)
...
public
destructor Destroy; override; // <- New Line
...
end;
Implementation
destructor TAcroPDF.Destroy;
begin
FIntf := NIL;
inherited;
end;
I migrated a Datasnap server to XE 10.1 Berlin and now I get an error on the server when I invoke a servermethod with OUT parameters.
Object
TBtwlControlePar=class
xInDoc,
xHandmatig,
xStatus,
xVerwacht,
xAantal,
xVerwerkt,
xOnVerwerkt,
xOnverwerktInDocument,
xTotaalCustoms :Integer;
end;
function TPWAdminMethods.DOC_BTWAH_Get2(pPeriode, pMaand, pSort,pSelop,pSelOntvangen,pSelToegewezen,pSelVerwerkt: integer; pSel: string; out pControlePar: TBTWLControlePar): TResult;
ServerMethod
tmpM := TPWAdminMethodsClient.Create (DMForm.DSConnection.DBXConnection, false);
Client
FreeAndNil( fControlePar );
tmpResult := tmpM.DOC_VATLH_Get2(Jaar,sort,SelOp,SelOntvangen,SelToegewezen,SelVerwerkt,fSelection,fControlePar);
When this method is fired the server gives an error on this last line
procedure TDSMethod.Invoke(MethodInstance: TObject;
MethodValues: TDSMethodValues);
var
RContext: TRttiContext;
RType: TRttiType;
Params: TArrayOfTValue;
begin
Params := MethodValues.GetValues;
RType := RContext.GetType(MethodInstance.ClassType);
MethodValues.ReturnValue := RType.GetMethod(FMethodInfoHeader.NameFld.ToString).Invoke(MethodInstance, Params);
end;
Is it impossible to use out parameters in Delphi Berling Datasnap without the use of DBXJson?
This error message and the issue has been logged on Embarcadero's Quality Portal as RSP-14895. This was on 16May16 by someone else. That person stated "XE10 is OK".
Today (14Jun16) I added another test project to the issue. My test project is for the case of a VAR parameter. I have also provided a screenshot of the test project in action. My tests work on XE6 but fail on 10.1 Berlin.
I can't use DataSnap until this issue is fixed.
Please vote up the issue.
This follows on from my answer to this Q:
Can I change the display format for strings in the watch list?
It turns out that at some point between D7 and XE3, the implementation of the IDE's Watch Window changed from using a TListView to a TVirtualStringTree.
Although I posted an update to my answer that works with XE4 by ignoring the VST and getting the watch value from the clipboard, I'd still like to be able to get the watch value from the VST if I can. I think I know how to do that
once I have a reference to the VST but the problem is that my attempt to get one fails.
Following is an MCVE of the code I'm using in my custom package. Hopefully, what it does is self-explanatory. The problem is that the code in the block
if WatchWindow.Components[i] is TVirtualStringTree then begin
[...]
end;
never executes, DESPITE the classname "TVirtualStringTree" appearing in Memo1. Obviously the component with that classname fails the "is" test. I'm guessing that the reason is that the TVirtualTreeView compiled into the IDE is a different version that the one I'm using, v.5.3.0, which is the nearest predecessor I could find to XE4.
So, my question is, is that the likely explanation, and is there anything I can do about it? I suspect if someone can flourish the version of TVirtualStringTree that was used for XE4 from a hat, that might solve my problem.
type
TOtaMenuForm = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
WatchWindow : TForm;
VST : TVirtualStringTree;
end;
procedure TOtaMenuForm.FormCreate(Sender: TObject);
var
i : Integer;
S : String;
begin
WatchWindow := Nil;
VST := Nil;
// Iterate the IDE's forms to find the Watch Window
for i := 0 to Screen.FormCount - 1 do begin
S := Screen.Forms[i].Name;
if CompareText(S, 'WatchWindow') = 0 then begin
WatchWindow := Screen.Forms[i];
Break;
end;
end;
Assert(WatchWindow <> Nil);
if WatchWindow <> Nil then begin
Memo1.Lines.Add('Looking for VST');
for i := 0 to WatchWindow.ComponentCount - 1 do begin
Memo1.Lines.Add(IntToStr(i) + ':' + WatchWindow.Components[i].ClassName);
if WatchWindow.Components[i] is TVirtualStringTree then begin
VST := TVirtualStringTree(WatchWindow.Components[i]);
Memo1.Lines.Add('found VST');
Break;
end;
end;
if VST = Nil then
Memo1.Lines.Add('VST not found');
end;
end;
Btw, I realise that solutions that depend of implementational details of IDE are likely to be fragile, but this is just for amusement (I liked the challenge of getting string data out of a component that goes out of its way to avoid storing any).
May be You can try to use only published properties of embedded into IDE TVirtualStringTree implementation through RTTI methods to do what you want?
I have written a code with Delphi 2009 and updated my CodeGear Delphi to XE2. It compiled perfectly with Delphi 2009, but now it doesn't ! It gives me this error instead :
[DCC Error] Incompatible types: 'TFormStyle' and 'TTeeFontStyle'!
I tried creating a new Vcl Forms Application and wrote the command that generates this error :
Form1.FormStyle := FsNormal;
and it compiled perfectly too,I don't know why is this happening, although I believe there's nothing wrong with my syntax, please help, thanks.
This is the code that is not compiling :
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
begin
KeyPreview := True;
case Msg.message of
WM_KEYDOWN:
if Msg.wParam = 27 then
begin
form1.Menu:=mainmenu1;
fullscreen1.Checked:=false;
form1.formstyle:=fsnormal;
form1.BorderStyle:=bssizeable;
end
else
if msg.wParam=VK_f5 then
begin
browser.Navigate(memo2.Text);
end;
end;
end;
end;
There is name conflict with some TeeChart module, which is in "use" clause. You can write full-qualified identificator name to resolve this problem:
formstyle := Vcl.Forms.fsnormal;
P.S. Note that I deleted "form1." qualifier also. Normally it is not very useful in the form method body, and sometimes even harmful (imagine that you have multiple instances of TForm1)
In addition to the answer of MBo, I think it is better to use:
Self.formstyle := Vcl.Forms.fsnormal;
When you have multiple instances of TForm1, this will always adjust the instance you are using at that moment.
Qualify the value with the particular enum type that it comes from:
Form1.FormStyle := TFormStyle.fsNormal;
Or even:
Form1.FormStyle := Vcl.Forms.TFormStyle.fsNormal;
I have created a procedure in a dll that opens a form and then prints a report.
This procedure works perfectly from an exe.
I have wrapped the unit that contains this procedure and forms in a dll and exported the procedure as follows:
{$R *.res}
Procedure PrintTopSellers; stdcall;
begin
Form1 := TForm1.create(nil);
GetMonth := TGetMonth.create(nil);
Form1.PrintTopSellers;
end;
exports PrintTopSellers;
begin
end.
Now I call this procedure PrintTopSellers from an exe as follows:
procedure TForm1.Button5Click(Sender: TObject);
type
TRead_iButton = function :integer;
var
DLL_Handle: THandle;
Read_iButton: TRead_iButton;
Begin
DLL_Handle := LoadLibrary('c:\Catalog.dll');
if DLL_Handle <> 0 then
begin
#Read_iButton:= GetProcAddress(DLL_Handle, 'PrintTopSellers');
Read_iButton;
end;
application.ProcessMessages;
FreeLibrary(DLL_Handle);
end;
The call to the procedure works perfectly. However, after I close the calling exe, I get an access violation - "Access violation at address 00BAC89C. Read of address 00BAC89C."
Appreciate any assistance. I am using Delphi 7.
Thanks
You are creating Form1, a windowed control, in the DLL. But you never destroy it. Then you unload the DLL which unloads the code that implements the window procedures for all windows created by the DLL. Presumably when the process shuts down, the window procedures are called, but there is no code there anymore.
Fix the problem by destroying all objects that the DLL creates. It looks to me like the best approach is to do that when PrintTopSellers terminates.
Procedure PrintTopSellers; stdcall;
begin
Form1 := TForm1.create(nil);
try
GetMonth := TGetMonth.create(nil);
try
Form1.PrintTopSellers;
finally
GetMonth.Free;
end;
finally
Form1.Free;
end;
end;
In the code that loads the DLL, TRead_iButton is declared incorrectly. It should be
TRead_iButton = procedure; stdcall;
But that doesn't actually explain the problem here since the signature mismatch is benign for a parameterless procedure.
"TRead_iButton = function: integer; register;"
"Procedure PrintTopSellers; stdcall;"
Absolutely different conventions/types, ain't them ?
Make them the same.
And better ditch DLL and use packages (BPL), then compiler would make you safe from such errors
We also don't see the code neither in Form1.PrintTopSellers nor in TGetMonth. The all can leave some dangling pointers in the host exe, that would get accesses after DLL unloaded.
Show exactly chain of function calls leading to AV - it is called stack trace.
Debug info + some excaption interrupt like Jedi CodeLibrary (used by Delphi IDE) madExcept, EurekaLog, synopse log and a lot of other exist.
Display the call stack in a Delphi Win32 application
Does DLL or EXE use Runtime packages ?