Launching Word x64 in Delphi - delphi

I am currently working on very old project, which is based on Delphi 5. When I am trying to open new Word document on x64 system, I recive this error:
According to MSDN, the source of problem might be the version of my Office (x64). In application we use TWordApplication object to manage Word invoking. Is there any solution for that problem? On Office x86 everything works fine.
This is part of the code:
Word := TWordApplication.Create(nil);
Word.ConnectKind := ckNewInstance;
Word.AutoQuit := True;
Word.Connect;
Word.Options.CheckSpellingAsYouType := False;
Word.Options.CheckGrammarAsYouType := False;
Word.Options.SuggestSpellingCorrections := False;
Word.Options.CheckGrammarWithSpelling := False;
Word.Options.ShowReadabilityStatistics := False;
Word.Options.IgnoreInternetAndFileAddresses := False;
Word.Options.IgnoreUppercase := True;
Word.Options.IgnoreMixedDigits := True;
Word.Options.ReplaceSelection := True;

The problem appears to be in the VBA code attached to your document rather than the Delphi code. Specifically a hidden module named API is implicated. Perhaps this is in a template or an add-in or an auto start.
Hidden modules are protected which suggests that you may not be able to modify the module. You could try contacting the author of the protected module or perhaps removing whatever it is that introduced this module.
Reverting to 32 bit Office is an easier solution. This will require you to uninstall 64 bit Office first since the two editions do not co-exist.

Related

Load TGPBitmap from MemoryStream

I have been asked to correct an issue (not related to this question) in a legacy Delphi program. After fixing some issues with missing components, I am now stuck with some GDI Plus functionality, which stops me from compiling the program. One of the functions where this is used is:
function TDownLoadItem.LoadRawBitmapFromStream(var bm: TBitmap): Boolean;
var
image: TGPBitmap;
begin
Result := False;
if Content.Size = 0 then
exit;
// NOTE: Content is a TMemoryStream, declared globally.
image := GDIPlusHelper.LoadBitmapFromStream(Content); // <== This is where the problem is....
try
bm.Width := image.GetWidth;
bm.Height := image.GetHeight;
with TGPGraphics.Create(bm.Canvas.Handle) do
try
DrawImage(image, 0, 0, image.GetWidth, image.GetHeight);
Result := True;
finally
Free;
end;
finally
image.Free;
end;
end;
I think (not sure) the last Delphi version used was 2006, I am on Delphi Rio 10.3.
Online I have managed to find GDI+ 1.2, but this does not solve the problem. The procedure LoadBitmapFromStream does not exit in these libraries. GDIPlusHelper was apparently renamed to GDIPlusHelpers and most code has changed from classes to interfaces. I suspect an older edition of the GDI Plus libraries were used, but I cannot find these.
Reworking the code would be too complex as it would require Content to be an IStream instead of a TMemoryStream. Also, simply using a TBitmap is not feasible either as other code (not shown) uses functionality specific to TGPBitmap (e.g. RotateFlip).
Any suggestions on how to fix/work around this? Thanks in advance!

Create TVirtualTable via Code only without drop component

Recently i want to export data using TscExcelExport.
If i'm using TVirtualTable using Design Component, it works perfectly.
EmpVT.First;
EmpVT.Filtered := False;
while not EmpVT.Eof do
begin
//Salary Virtual Table
VirtualTableBankTransferListExport.Append;
VirtualTableBankTransferListExport.FieldByName('EMPID').AsInteger := EmpVT.FieldByName('EMPID').AsInteger;
VirtualTableBankTransferListExport.FieldByName('EMPBANKGROUPNO').AsInteger := EmpVT.FieldByName('BANKGROUPNO').AsInteger;
VirtualTableBankTransferListExport.FieldByName('EMPTRANSBANKACCNAME').AsString := EmpVT.FieldByName('EMPBANKACCNAME').AsString;
VirtualTableBankTransferListExport.FieldByName('EMPTRANSBANKACCNO').AsString := EmpVT.FieldByName('EMPBANKACCNO').AsString;
VirtualTableBankTransferListExport.FieldByName('BANKACCNO').AsString := EmpVT.FieldByName('BANKACCNO').AsString;
VirtualTableBankTransferListExport.FieldByName('PERIOD').AsString := PaySlipPeriod;
VirtualTableBankTransferListExport.FieldByName('BANKNAME').AsString := EmpVT.FieldByName('BANKNAME').AsString;
VirtualTableBankTransferList.FieldByName('TRANSFERAMOUNT').AsInteger := 0;//Format('%s%s%.*d', [EmpVT.FieldByName('REGIONCODE').AsString,EmpVT.FieldByName('EMPCODE').AsString,4,EmpVT.FieldByName('EMPCODE').AsInteger]); //EmpVT.FieldByName('EMPCODE').AsString;
VirtualTableBankTransferListExport.FieldByName('BANKID').AsString := EmpVT.FieldByName('BANKID').AsString;
VirtualTableBankTransferListExport.FieldByName('TBANKNAME').AsString := EmpVT.FieldByName('TBANKNAME').AsString;
VirtualTableBankTransferListExport.FieldByName('BANKLOCATION').AsString := EmpVT.FieldByName('BANKLOCATION').AsString;
VirtualTableBankTransferListExport.Post;
EmpVT.Next;
end;
scExcelExport1.WorksheetName := 'Bank Transfer List';
scExcelExport1.Dataset:=VirtualTableBankTransferListExport;
scExcelExport1.ExportDataset;
scExcelExport1.Disconnect;
What is the correct way to create TVirtualTable via Code only without dropping TVirtualTable in form?
Thank you for your help.
Install CnWizards (more features but less stable) or GExperts IDE (more polished but less features) add-on
They both have "Component-To-Code" wizard.
So you would select your component, run this command from the menu and would get the pure Pascal sources of creating it.
PS. Actually there might be several components, not a single one: fields are usually components of their own.

Is there a version of Async Pro which works with Delphi XE3?

I want to use Async Pro in my Delphi XE3. I found a version A407 on SourceForge, which seems to be the latest. When I try to install the runtime package A407_R100.bpl I get an error that a data length is longer than 2GB. When I fix this (with some guesswork) I get 4 other errors. I can try to fix those as well, but I'm afraid I will have to patch so much of the code that it won't work anymore.
Is there a version of Async Pro which works with XE3? Or at least clear and proven instructions how to patch the code?
update
Here I found an AsyncPro library which seems to be more up-to-date; at least the packages are named A407_*140.bpl instead of A407_*100.bpl. I still had a couple of errors in this part of the code in AwAbsPd.pas:
procedure InitializeUnit;
var
TmpDateSeparator : char;
TmpDateFormat : string[15];
TmpDateTime : TDateTime;
begin
{Set Unix days base}
TmpDateFormat := ShortDateFormat;
TmpDateSeparator := DateSeparator;
DateSeparator := '/';
ShortDateFormat := 'mm/dd/yyyy';
TmpDateTime := StrToDateTime('01/01/1970');
UnixDaysBase := Trunc(TmpDateTime);
DateSeparator := TmpDateSeparator;
ShortDateFormat := TmpDateFormat;
Although SysUtils is in the "uses" clause I got errors that ShortDateFormat and DateSeparator weren't defined. So I hard-coded them:
procedure InitializeUnit;
var
TmpDateSeparator : char;
TmpDateFormat : string[15];
TmpDateTime : TDateTime;
// added stevenvh
var
DateSeparator: char;
ShortDateFormat: String;
ShortTimeFormat: String;
// end addition
begin
// added stevenvh
DateSeparator := '-';
ShortDateFormat := 'yyyy-mm-dd';
ShortTimeFormat := 'HH:mm:ss';
// end addition
{Set Unix days base}
TmpDateFormat := ShortDateFormat;
TmpDateSeparator := DateSeparator;
DateSeparator := '/';
ShortDateFormat := 'mm/dd/yyyy';
TmpDateTime := StrToDateTime('01/01/1970');
UnixDaysBase := Trunc(TmpDateTime);
DateSeparator := TmpDateSeparator;
ShortDateFormat := TmpDateFormat;
Nearly there! Both runtime and designtime packages compile, but when I try to install the designtime package I get an error that "01/01/1970" is not a valid date. This is not an error in the above code, because it remains the same "01/01/1970" when I change the date in the code.
Turns out there is only 1 other file which includes "01/01/1970" as text, but this is a .ocx file, so I'm not sure how or even if I should patch this.
Acording to this blog post:
http://blog.kassebaum.eu/?p=379
Async Proffesional is currently maintained by Roman Kassebaum but only for latest versions of RAD studio (both Delphi and CBuilder).
The menioned blog links to next source forge page:
http://sourceforge.net/projects/turbopowerasyncprofessionalnew/?source=navbar
Infromation on the page indicates that the project is closed and that it moved to github but no link is provided.
After doing some searching on GitHub I found the projects page
https://github.com/TurboPack/AsyncPro
Anyway since Roman Kassebaum is maintaing the project to be compatible with newest Delphi version it might not work for you.
So I strongly recomend you get in contact with Roman Kassebaum as he will best know which version should you use with your Delphi XE3 instalation or what needs to be fixed to make it compatible.
The official AsyncPro version moved to GitHub. You can find it under TurboPack. It supports the latest Delphi and C++Builder version.
I also created a branch for XE3. You can find it under TurboPack XE3.
Use FormatSettings.ShortDateFormat, FormatSettings.DateSeparator, ... instead of introducing your own variables. That would be closest to the original.
A cleaner approach would be using the date/time functions with a formatsettings overload instead of temporarily changing the global formatsettings.

FastReport4: OnBeforePrint never executes on frxReport.ShowPreparedReport

I'm using Delphi XE5.
On my GroupFooter I try to hide several memos in a conditional is met
procedure GroupFooter1OnBeforePrint(Sender: TfrxComponent);
begin
ShowMessage('a');
if <frxDB."total_payment"> <= 0 then begin
Memo27.Visible := False;
Memo28.Visible := False;
Memo29.Visible := False;
Memo30.Visible := False;
end;
end;
This is my calling code in Delphi
Report.LoadFromFile(CurDir+'reports/invoice/'+ReportName);
if Report.PrepareReport then
Report.ShowPreparedReport;
I found that the OnBeforePrint event never fires when the report was showing after frxReport.ShowPreparedReport command, but when I tries to preview it in the designer, it works just as normal.
I keep wondering what did I miss.
Anyone can help?
Thanks
I recently found out that this is due to FastReport 4 demo version that is bundled along with Embarcadero RAD Studio XE5. The full version works perfectly, but any fr3 file created from demo-bundled version can't be opened in full version.

Word automation does only work for administrator, or with a delay after creating word.application

We have a program made in Borland Delphi that uses Word automation to create documents.
On an installation (terminal server) we are only able to get the Word automation to work when running as local administrator.
When runnnig as anoter user we get an error message "Opdracht mislukt -2146824090" (its dutch version of Office), wich I guess is translated to "Operation failed" or "Command failed".
The user has read/write access to the folder where the program try to put the new document.
Office 2010
64bits Windows server 2008 R2 standard
The applicaion is 32bit windows application.
If I add a delay (500ms) after the word.application is created, everything works as normall.
WordApp := CreateOleObject('Word.Application');
sleep(500);
Doc := WordApp.documents.Open(sFile,EmptyParam,true);
Anybody knows why the CreateOleObject command now returns before the Word application can be used?
If you want to track out that, you could use a tool like ProcessMonitor to trace the Word automation executions till the point which you can use the app.
Seems some kind of rights check is taking place - but half a second seems too much time just for this.
You could try to open the Document a few times, or is Word totally borked after it gave the error?
WordApp := CreateOleObject('Word.Application');
while True do
begin
try
Doc := WordApp.documents.Open(sFile,EmptyParam,true);
Break;
except
on E: EOleSysError do
begin
// raise error if it's not the expected "Command failed" error
if E.ErrorCode <> -2146824090 then
raise;
end;
end;
end;
Edit:
Please see my answer here which provides a better solution and an explanation why this happens.
The administrator account working wihtout delay, seems not to have anything with rights to do, but that Word happens to start much faster with this account than the normal domain user accounts.
I can live with the delay workaround, but if anyone knows a better way please let me know.
I realize this thread is quite old, but I solved this issue by making sure to close the document before quitting (oleDocument.Close). By doing so there is no need for any type of delays, etc. See Delphi code snippet below.
Example:
oleWord := Unassigned;
oleDocument := Unassigned;
Screen.Cursor := crHourGlass;
try
oleWord := CreateOleObject('Word.Application');
oleWord.Visible := False;
oleWord.DisplayAlerts := False;
oleDocument := oleWord.Documents.Open(Worklist.Filename);
oleDocument.SaveAs(Worklist.Filename, wdFormatDOSTextLineBreaks);
oleDocument.Close;
oleWord.Quit(False);
finally
oleDocument := Unassigned;
oleWord := Unassigned;
Screen.Cursor := crDefault;
end;

Resources