Opening rtf file in Delphi generates error - delphi

I am loading a RichEdit file using the following code:
RichEdit1.Lines.LoadFromFile('xxx.rtf');
This works well. However when I use the TOpenDialog like this:
with DlgOpen do if Execute then RichEdit1.Lines.LoadFromFile(FileName);
I run into a problem. The file loads alright but leaves the following error message on the desktop:
I am using Delphi 2010. The rtf file was generated using Microsoft Word 2007 and I am running Win10.
How can I get rid of the error message?

If you can't prevent the previewer to lock the file you want to read, I would work around it by not loading directly that file but a copy of it.
uses IOUtils;
....
....
var TempFile: string;
....
if DlgOpen.Execute then
begin
TempFile := IncludeTrailingPathDelimiter(TPath.GetTempPath) + 'Temp.rtf';
CopyFile(PChar(DlgOpen.FileName), PChar(TempFile), False);
RichEdit1.Lines.LoadFromFile(TempFile);
DeleteFile(TempFile);
end;

Related

Delphi - Using OLE causes error in Word

Delphi XE6. I have an application for text snippets, which are stored in a local Database (ABS DB). Some snippets may be straight text, others may include formatting. If the snippets include formatting, the snippets are MS Word format.
The user can view the snippets in two ways, inside my app, or by calling MS-Word, and having the snippet loaded there automatically, - IT IS THE SAME SNIPPET ..
Issue: If the snippet is loaded into a TOLEContainer in my app, it displays fine without a problem... If the snippet gets spawned off into MSWord, I get an error...
"We're sorry. We can't open because we found a problem with its contents." I click on OK, and then get "Word found unreadable content in . Do you want to recover the contents of this document?..." I clik OK, and everything displays fine.
My general processing flow for the "spawn off MS WORD" is...
// FN is a temp file name
FileStream := TFileStream.Create(FN, fmCreate);
BlobStream := dm_text.tEntries.CreateBlobStream(dm_text.tEntries.FieldByName('ANSWER_FMT'), bmRead);
FileStream.CopyFrom(BlobStream, BlobStream.Size);
BlobStream.Free;
FileStream.Free;
// Now open default association, which will be Word
ShellExecute(Handle, 'open', PWideChar(FN), nil, nil, SW_SHOWNORMAL);
This flow is nearly identical for the In place viewing... other than a few commands for the TOleContainer.
OleWord.Enabled := True;
FileStream := TFileStream.Create(FN, fmCreate);
BlobStream := tEntries.CreateBlobStream(tEntries.FieldByName('ANSWER_FMT'), bmRead);
FileStream.CopyFrom(BlobStream, BlobStream.Size);
BlobStream.Free;
FileStream.Free;
OleWord.LoadFromFile(FN);
OleWord.DoVerb(ovInPlaceActivate);
Any ideas why this is happening? This happens on MULTIPLE versions of MSWord.
ADDITIONAL INFO:
Both routines look at the same data, pulled from the exact same row/column in my DB. What I do is create a TEMP file, and then load either via TOleContainer, which loads it fine, or via ShellExecute, which gives an error. However, if I manually load the TEMP file for the OLE Container into MSWord, I get the same error.
So - possibilities...
1). My data is corrupted, i.e. how I save it is wrong...but Word can correct it.
2). I have a setting somehow so that OLEContainer doesn't show the error but Word does.
It is because when using OleContainer.SaveToFile or SaveAsDocument, you are not creating a docx file, but an OleObject containing a docx file. When using OleContainer.SaveToFile with UseOldStreamFormat = True, there is even a Delphi specific header added. Word fortunatly detects this and gives you the option to restore the file.
If you want a valid word-document, then activate the OleContainer (OleContainer.DoVerb(ovPrimary) and then save the document via Word itself (OleContainer.OleObject.SaveAs(MyFileName, wdFormatDocument, EmptyParam, EmptyParam, False).
After that you can store the resulting file in your database.

CopyFile docx makes hidden conversion to doc

i got a Delphi 7 program which has to copy a docx file. I'm using the Windows API CopyFile function. The problem is that this function seems to make a hidden conversion to the older doc format.
First thing: the file size increases after the copy.
Second: When opening the file in Office 2007 i got an error message stating that: Check your permissions to the document or disk, check free disk space.
And than the strange thing: if i change in TotalCommander the extension of the copied file from docx to doc it opens normally. So it seems to make a hidden conversion dont know why.
Tested on two different computers. Both Win XP Prof SP3, Office 2007 Prof Plus SP2
Any ideas?
Function body is below:
function TDlgNowySzablon.PobierzPlikNaDoc() : string;
var
openDlg : TOpenDialog;
begin
Result:='';
openDlg:=TOpenDialog.Create(self);
openDlg.Filter:='Dokumenty Microsoft Word (*.doc;*docx)|*.doc;*.docx';
if openDlg.Execute then begin
Result := IObsSzab.GetTempFullFileName( ExtractFileExt(openDlg.FileName) );
if not CopyFile(PChar(openDlg.FileName),PChar(Result),true) then begin
Result:='';
end;
end;
openDlg.Free;
end;
Try changing your code as follows:
Result := IObsSzab.GetTempFullFileName('.tmp');
Result := ChangeFileExt(Result, ExtractFileExt(openDlg.FileName));
I think your GetTempFullFileName function is truncating .docx to .doc. It's all guesswork though!
The CopyFile function does not modify the contents of the file.

Delphi 7 and Excel 2007 Open File Error

I am having difficulty opening a EXCEL 2007 in Delphi 7 It works for Office 2003 and below but the wonderful people at microsoft have sent an update or something and the delphi app fell over just earlier this month.
oE := GetActiveOleObject('Excel.Application');
oE.Workbooks.Open(Filename:=sFilename, UpdateLinks:=false, ReadOnly:=true); //Error
I get the following error:
'c:\Temp\Book1.xls' could not be
found. Check the spelling of the file
name, and verify that the file
location is correct.'#$A#$A'If you are
trying to open the file from your list
of most recently used files, make sure
that the file has not been renamed,
moved, or deleted'
Yet if I run the same command in VBA there is no problem.
I know this sounds stupid, but have you manually confirmed that the file exists at that location?
What exactly is the contents of sFileName, is it the full path or only the filename? When it is only the filename, maybe Excel can't find it because its current working directory is something else. If you are only passing the filename, try the full path instead.
the full code for the lookers :
uses ComObj; ..
procdure startExcel;
var
oE:Variant;
begin
try
oE := GetActiveOleObject('Excel.Application');
except
oE := CreateOleObject('Excel.Application');
end;
oE.Workbooks.Open(filename, false, false);
oE.Visible := True;
end;
source

embedded file into delphi exe application (not as a separate file from the appliaction)

i want to embedded a file (any kind of type) to my exe application and be able to extract in the remote to use it, i know how do it by embedded into resource,but i don't want to place the files in the app directory, i want to store all files (like .rec) into my exe, in c# it is possible to store as text file and then read it by FileStream but in Delphi the resource files is separate from the exe file.
is there any solution to do this ? Thanks a lot!
You should make an .rc file and add that to your project. The content of the RC file is like:
FIXED48 IMAGE ..\Resources\Fixed48x48.png
MENU16 IMAGE ..\Resources\Menu16x16.png
TICK SOUND ..\Resources\Tick.wav
PING SOUND ..\Resources\Ping.wav
Now after you do a build you can load one of these fikles using a TResourceStream:
procedure TdmReportGeneral.InsertLogo(Memo: TStringList; View: TfrView);
var
S: TResourceStream;
begin
if (View is TfrPictureView) and (View.Name = 'Logo') then begin
S := TResourceStream.Create( 0, 'FIXED48', 'IMAGE' );
try
// do something useful... TfrPictureView(View).Picture.MetaFile.LoadFromStream( S );
finally
S.Free();
end;
end;
end;
You should be able to get the Delphi compiler to link your resource into your EXE by adding it as a {$R myresource.res} pragma in a unit in your project. You can then get a handle to it via a call to FindResource when you need to read it.
This article takes you through the appropriate steps.
DelphiDabbler has a great article on this very topic. They even include 2 example projects for download that show how to embed a file as a resource, and how to read it back.
You can download a worked example that
demonstrates what we've described here
– it uses the above code. The zip file
contains a pair of projects. The first
is a program that embeds a supplied
rich text file in a resource file. The
second program includes the resource
file and displays the rich text in a
rich edit component as above.

Open an ANSI file and Save a a Unicode file using Delphi

For some reason, lately the *.UDL files on many of my client systems are no longer compatible as they were once saved as ANSI files, which is no longer compatible with the expected UNICODE file format. The end result is an error dialog which states "the file is not a valid compound file".
What is the easiest way to programatically open these files and save as a unicode file? I know I can do this by opening each one in notepad and then saving as the same file but with the "unicode" selected in the encoding section of the save as dialog, but I need to do this in the program to cut down on support calls.
This problem is very easy to duplicate, just create a *.txt file in a directory, rename it to *.UDL, then edit it using the microsoft editor. Then open it in notepad and save as the file as an ANSI encoded file. Try to open the udl from the udl editor and it will tell you its corrupt. then save it (using notepad) as a Unicode encoded file and it will open again properly.
Ok, using delphi 2009, I was able to come up with the following code which appears to work, but is it the proper way of doing this conversion?
var
sl : TStrings;
FileName : string;
begin
FileName := fServerDir+'configuration\hdconfig4.udl';
sl := TStringList.Create;
try
sl.LoadFromFile(FileName, TEncoding.Default);
sl.SaveToFile(FileName, TEncoding.Unicode);
finally
sl.Free;
end;
end;
This is very simple to do with my TGpTextFile unit. I'll put together a short sample and post it here.
It should also be very simple with the new Delphi 2009 - are you maybe using it?
EDIT: This his how you can do it using my stuff in pre-2009 Delphis.
var
strAnsi : TGpTextFile;
strUnicode: TGpTextFile;
begin
strAnsi := TGpTextFile.Create('c:\0\test.udl');
try
strAnsi.Reset; // you can also specify non-default 8-bit codepage here
strUnicode := TGpTextFile.Create('c:\0\test-out.udl');
try
strUnicode.Rewrite([cfUnicode]);
while not strAnsi.Eof do
strUnicode.Writeln(strAnsi.Readln);
finally FreeAndNil(strUnicode); end;
finally FreeAndNil(strAnsi); end;
end;
License: The code fragment above belongs to public domain. Use it anyway you like.

Resources