Solved

Using File Compare in Word

Posted on 2001-07-21
12
1,084 Views
Last Modified: 2007-11-27
Does anyone have any source or info on using the file compare features in Word from withing Delphi 3/4/5/6?
What I'm trying to do is create a Delphi app that has two windows, one with original text and one with text to compare with. I want to use Word to compare the text and highlight the changes in the Delphi text controls much the same way it does in word with additions and deletions.

Lots of points available for this one... name your price!

Thanks.
0
Comment
Question by:isis071598
  • 7
  • 4
12 Comments
 
LVL 1

Author Comment

by:isis071598
ID: 6305597
Lets increase the price...I REALLY need help!
0
 
LVL 21

Expert Comment

by:gemarti
ID: 6306090
)'_'(<<<

0
 
LVL 21

Expert Comment

by:gemarti
ID: 6306203
I am not sure this if this will help, but I found that on my installation of Delphi 5 [DELPHI$]\Demos\ActiveX\olectnr
There is a project olesdi or olemdi.dpr. It shows how to embed word in your Delphi application. What I did was open the olesdi project and made some modification to it. Basically I added a second OleContainer to the display and copied the file open and file save button for and modified their code to control the second olecontainer. I then tested by opening two different files in Olecontainers 1 and 2.

maybe this will get you started?


Here is the unit that I modified...please note that this was originally an OLE Demo included with the Delphi 5 installation.


///////////////////////////////////////////////////////////


{ This sample application demonstrates the following features of the
  TOLEContainer:

  - Toolbar negotiation
  - Status bar hints while inplace editing
  - Using the TOLEContainer's dialogs including InsertObject,
    ObjectProperties and PasteSpecial.
  - Using the TOLEContainer's constructors CreateLinkToFile,
    CreateObjectFromFile.
  - Menu merging during in-place activation
}
unit sdimain;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, Buttons, ExtCtrls, Menus, OleCtnrs, StdCtrls;

type
  TMainForm = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Exit1: TMenuItem;
    Help1: TMenuItem;
    About1: TMenuItem;
    Toolbar: TPanel;
    SpeedButton1: TSpeedButton;
    LinkButton: TSpeedButton;
    CopyButton: TSpeedButton;
    CutButton: TSpeedButton;
    PasteButton: TSpeedButton;
    OpenButton: TSpeedButton;
    OpenDialog1: TOpenDialog;
    StatusPanel: TPanel;
    StatusBar: TStatusBar;
    Save1: TMenuItem;
    SaveAs1: TMenuItem;
    SaveDialog1: TSaveDialog;
    Open1: TMenuItem;
    N2: TMenuItem;
    SaveButton: TSpeedButton;
    Edit1: TMenuItem;
    Object1: TMenuItem;
    N4: TMenuItem;
    PasteSpecial1: TMenuItem;
    Paste1: TMenuItem;
    Copy1: TMenuItem;
    Cut1: TMenuItem;
    New1: TMenuItem;
    Panel1: TPanel;
    OleContainer1: TOleContainer;
    OleContainer2: TOleContainer;
    SpeedButton2: TSpeedButton;
    SpeedButton4: TSpeedButton;
    procedure Exit1Click(Sender: TObject);
    procedure Copy1Click(Sender: TObject);
    procedure Paste1Click(Sender: TObject);
    procedure Object2Click(Sender: TObject);
    procedure LinkButtonClick(Sender: TObject);
    procedure About1Click(Sender: TObject);
    procedure Save1Click(Sender: TObject);
    procedure File1Click(Sender: TObject);
    procedure Open1Click(Sender: TObject);
    procedure CutButtonClick(Sender: TObject);
    procedure New1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Object1Click(Sender: TObject);
    procedure Cut1Click(Sender: TObject);
    procedure PasteSpecial1Click(Sender: TObject);
    procedure Edit1Click(Sender: TObject);
    procedure SpeedButton4Click(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
  private
    ObjectFileName: TFileName;
    InsertCanceled: Boolean;
    procedure ShowHint(Sender: TObject);
  end;

var
  MainForm: TMainForm;

implementation

uses about;

{$R *.DFM}

procedure TMainForm.ShowHint(Sender: TObject);
begin
  Statusbar.Panels[0].Text := Application.Hint;
end;

procedure TMainForm.Exit1Click(Sender: TObject);
begin
  Close;
end;

procedure TMainForm.Copy1Click(Sender: TObject);
begin
  OleContainer1.Copy;
  PasteButton.Enabled := True;
end;

procedure TMainForm.Paste1Click(Sender: TObject);
begin
  if (OleContainer1.State = osEmpty) or
    (MessageDlg('Replace existing object?', mtConfirmation, mbOkCancel, 0) = mrOk) then
  begin
    OleContainer1.Paste;
    CopyButton.Enabled := True;
    CutButton.Enabled := True;
  end;
end;

procedure TMainForm.Object2Click(Sender: TObject);
begin
  if OleContainer1.State <> osEmpty then
    OleContainer1.ObjectPropertiesDialog;
end;

procedure TMainForm.LinkButtonClick(Sender: TObject);
begin
  if (OleContainer1.State = osEmpty) or
    (MessageDlg('Replace existing object?', mtConfirmation, mbOkCancel, 0) = mrOk) then
    with OpenDialog1 do
      if OpenDialog1.Execute then
      begin
        OleContainer1.CreateLinkToFile(FileName, False);
        ObjectFileName := FileName;
        CutButton.Enabled := True;
        CopyButton.Enabled := True;
        PasteButton.Enabled := OleContainer1.CanPaste;
      end;
end;

procedure TMainForm.About1Click(Sender: TObject);
begin
  AboutBox := TAboutBox.Create(Self);
  try
    AboutBox.ShowModal;
  finally
    AboutBox.Free;
  end;
end;

procedure TMainForm.Save1Click(Sender: TObject);
begin
  with SaveDialog1 do
  begin
    SaveDialog1.FileName := ObjectFileName;
    if (Length(FileName) = 0) or (Sender = SaveAs1) then
    begin
      if Execute then
      begin
        OleContainer1.SaveToFile(FileName);
        ObjectFileName := FileName;
      end
    end
    else
      OleContainer1.SaveToFile(FileName);
  end;
end;

procedure TMainForm.File1Click(Sender: TObject);
begin
  with OleContainer1 do
  begin
    Save1.Enabled := Modified;
    SaveAs1.Enabled := Modified;
  end;
end;

procedure TMainForm.Open1Click(Sender: TObject);
begin
  with OpenDialog1 do
    if Execute then
    begin
      OleContainer1.CreateObjectFromFile(FileName, False);
      ObjectFileName := FileName;
      CutButton.Enabled := True;
      CopyButton.Enabled := True;
      PasteButton.Enabled := True;
    end;
end;

procedure TMainForm.CutButtonClick(Sender: TObject);
begin
  if OleContainer1.State <> osEmpty then
    with OleContainer1 do
    begin
      Copy;
      DestroyObject;
      CopyButton.Enabled := False;
      PasteButton.Enabled := OleContainer1.CanPaste;
      ObjectFilename := '';
    end;
end;

procedure TMainForm.New1Click(Sender: TObject);
begin
  if (OleContainer1.State = osEmpty) or
    (MessageDlg('Delete existing object?', mtConfirmation, mbOkCancel, 0) = mrOk) then
    begin
      InsertCanceled := false;
      with OleContainer1 do
      begin
        DestroyObject;
        Object1Click(Sender);
        if not InsertCanceled then
        begin
        DoVerb(PrimaryVerb);
        ObjectFileName := '';
        end;
      end
    end;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  ObjectFileName := '';
  Application.OnHint := ShowHint;
end;

procedure TMainForm.Object1Click(Sender: TObject);
begin
  if (OleContainer1.State = osEmpty) or
    (MessageDlg('Delete current OLE object?', mtConfirmation, mbOkCancel, 0) = mrOk) then
    if OleContainer1.InsertObjectDialog then
    begin
      CutButton.Enabled := True;
      CopyButton.Enabled := True;
      PasteButton.Enabled := OleContainer1.CanPaste;
      with OleContainer1 do
        DoVerb(PrimaryVerb);
    end
    else
     InsertCanceled := true;
     
end;

procedure TMainForm.Cut1Click(Sender: TObject);
begin
  OleContainer1.Copy;
  OleContainer1.DestroyObject;
  CutButton.Enabled := False;
  CopyButton.Enabled := False;  
  PasteButton.Enabled := OleContainer1.CanPaste;  
end;

procedure TMainForm.PasteSpecial1Click(Sender: TObject);
begin
  if (OleContainer1.State = osEmpty) or
    (MessageDlg('Delete current OLE object?', mtConfirmation, mbOkCancel, 0) = mrOk) then
  begin
    if OleContainer1.PasteSpecialDialog then
    begin
      CutButton.Enabled := True;
      CopyButton.Enabled := True;
      PasteButton.Enabled := OleContainer1.CanPaste;
    end;
  end;
end;

procedure TMainForm.Edit1Click(Sender: TObject);
begin
  with OleContainer1 do
  begin
    Cut1.Enabled := State <> osEmpty;
    Copy1.Enabled := State <> osEmpty;
    Paste1.Enabled := CanPaste;
    PasteSpecial1.Enabled := CanPaste;
  end;
end;

procedure TMainForm.SpeedButton4Click(Sender: TObject);
begin
  with SaveDialog1 do
  begin
    SaveDialog1.FileName := ObjectFileName;
    if (Length(FileName) = 0) or (Sender = SaveAs1) then
    begin
      if Execute then
      begin
        OleContainer2.SaveToFile(FileName);
        ObjectFileName := FileName;
      end
    end
    else
      OleContainer2.SaveToFile(FileName);
  end;
end;

procedure TMainForm.SpeedButton2Click(Sender: TObject);
begin
  with OpenDialog1 do
    if Execute then
    begin
      OleContainer2.CreateObjectFromFile(FileName, False);
      ObjectFileName := FileName;
      CutButton.Enabled := True;
      CopyButton.Enabled := True;
      PasteButton.Enabled := True;
    end;
end;

end.
0
 
LVL 1

Author Comment

by:isis071598
ID: 6306823
Thanks gemarti!
This is cool but it doesn't give me enough control of the word object. I was thinking about using the server object. I came across a compare function in the wordoject class but I have no idea how to use it and get data back to my RTF control :O(

The thing I really want to do is to be able to run a compare on two documents and then summerise the changes under one of the text files.

ps This is worth a 1000+ poins to anyone who can help me out!

0
 
LVL 4

Expert Comment

by:jsweby
ID: 6307478
If you have Word 97 or above, turn the Macro Recorder on and do the function you want to do within Word. Turn the Macro recorder off when you have finished and look at the Visual Basic editor (all of these can be found under the Tools menu). This will give you the objects, properties and methods that you need to use, as well as any parameters, for the compare function. You can then use these with the Word server object.

J.
0
 
LVL 21

Expert Comment

by:gemarti
ID: 6309118
Okay isis I think I understand your request now. Lets try this.

Basically you want to use the WordDocument.Compare function and you want the modified document that was compared to be pasted into a rich edit component.

This is one way of getting you to that goal.

1.Create a new application.
2.Insert a page control.
3.On the Page control create three tabsheets
4.On Tabsheet one Name it Original Text and add a RichEdit Component
5.On Tabsheet two Name it Text to Compare and add a RichEdit Component
6.On TabSheet three Name it Controls and add a RichEdit Component. Also Add a Button
7. Add a WordApplication Component and two WordDocument Components.

Paste this code (from D5) into the unit.
////////////////////////////////////////////////////////
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Word97, OleServer, ComCtrls, OleCtnrs;

type
  TForm1 = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    RichEdit1: TRichEdit;
    RichEdit2: TRichEdit;
    WordApplication1: TWordApplication;
    WordDocument1: TWordDocument;
    Button1: TButton;
    WordDocument2: TWordDocument;
    RichEdit3: TRichEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  FileName,Template, NewTemplate,DocumentType,Visible : OleVariant;
  StrText : String;
begin
  try
    WordApplication1.Connect;
  except
    MessageDlg('Word may not be installed', mtInformation, [mbOK], 0);
    Abort;
  end;

  WordApplication1.Visible := true;
  WordApplication1.Caption := 'Delphi Comparison';
  //Turn Spell Checking  and Grammer Checking off
  WordApplication1.Options.CheckSpellingAsYouType := False;
  WordApplication1.Options.CheckGrammarAsYouType := false;
  WordApplication1.Options.Get_RevisedLinesMark;
  WordDocument1.Range.InsertBefore(RichEdit1.Lines.Text);
  WordDocument2.Range.InsertBefore(RichEdit2.Lines.Text);
  FileName := 'c:\My Documents\Doc2.Doc';
  WordDocument2.SaveAs(FileName);
  WordDocument1.Select;
  WordDocument1.TrackRevisions := true;
  WordDocument1.Compare(WordDocument2.Name);
  WordDocument1.ShowRevisions := true;
  StrText :=  WordDocument1.Paragraphs.First.Range.Duplicate.FormattedText.Text;
  RichEdit3.Lines.Add(StrText);
end;

end.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 21

Expert Comment

by:gemarti
ID: 6309138
I meant you want the the differences between document1 and document2 to be summarized in a rich edit field, not that "you want the modified document that
was compared to be pasted into a rich edit component."

Also I forgot to mention that what I did was paste your question into Richedit1 and RichEdit2 for this example. I changed a few words in RichEdit2 to do the comparison.

Good Luck.
 
0
 
LVL 21

Expert Comment

by:gemarti
ID: 6309330
Here is how you can post everything you select in the word document.

var
  TxtStr : String;
begin
  TxtStr := WordDocument1.Range.TextRetrievalMode.Duplicate.Application.Selection.Text;
  RichEdit3.Lines.Add(txtStr);

end;
0
 
LVL 1

Author Comment

by:isis071598
ID: 6311328
Hi,
This looks good but I couldn't get it to work. It just kept saying that the filename couldn't be found even after I added the correct path :O(

Did your version also open Word? I want this as transparent as possible.

Thanks
0
 
LVL 21

Accepted Solution

by:
gemarti earned 300 total points
ID: 6311913
If it couldn't open FILENAME it is probably because the file doc2.doc (in my posted code) doesn't exist on your PC.
Make sure you create doc2.doc.

Example:
var FileName# : OLEVariant;
begin
  FileName# := 'c:\[directory folder]\doc#.doc';
end;

Also you can hide word with:

WordApplication1.Visible := false; If you do this you'll
have to either count the sentences or paragraphs in the documents and stick with this code:

StrText :=  WordDocument1.Paragraphs.First.Range.Duplicate.FormattedText.Text;
 RichEdit3.Lines.Add(StrText);



Tell me at what point it is giving you the error message about not finding FILENAME.

Do do this open the unit. Place a stop mark at the begiing of the event and then step through the code it will eventually create the error. The last line of code that executes is the problem Let me know where that is.
0
 
LVL 1

Author Comment

by:isis071598
ID: 6319867
Thanks for all your hard work :O)
I have spent the past couple of days creating my own compare routine that will let me do what I want without using word. I thought it was an easy way to go but proved too inflexible in the long run.

Thanks again for all the input gemarti. Your help is appreciated.
0
 
LVL 21

Expert Comment

by:gemarti
ID: 6320289
Any time. This was a learning experience for me. Good luck isis.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now