Click here to Skip to main content
15,878,814 members
Articles / Desktop Programming / MFC
Article

RGDiff - Visual Diff Tool

Rate me:
Please Sign up or sign in to vote.
4.62/5 (17 votes)
2 Mar 20035 min read 168.6K   3.9K   51   33
Capture results from GNU Diff and display visually.

Sample Image - RGDiff.jpg

Introduction

The RGDiff project parses the output from a standard command line Diff program and presents the results in a graphical manner. It re-uses the GNU Diff program by "shelling out" using the WIN32 CreateProcess() function.

The techniques used could easily be incorporated into other programs requiring Diff functionality.

This article explains how the above is done in more detail.

Running RGDiff

RGDiff needs the GNU WIN32 diff.exe program to be in the same directory as RGDiff.exe. The directory should be writeable as RGDiff needs to create some temporary files.

RGDiff is statically linked with MFC because it is a standalone tool and MFC70.dll is probably not as widely distributed as MFC42.dll. I know this is probably not true among CodeProject members, but just to be on the safe side...

Background

Whenever I have used Microsoft's WinDiff, I could not help but be frustrated by its "Zebra Stripes". I have used other GUI Diff tools, and found that a side by side approach helps me understand the differences between the files much better. I had a look around the WWW and couldn't find anything that was free and did what I wanted, I therefore decided to have a go at writing my own.

My first decision was whether to write my own Diff algorithm or rip off somebody else's. I looked at Diff algorithms, the WinDiff code, and the GNU Diff code, and found them all impenetrable in the time I had available :-(

I therefore decided that the only realistic approach for me was to use an existing command line Diff utility as a spawned process, which is a common design pattern on *nix. The GNU Diff utility seemed like a good start, and with programmers like Richard Stallman behind it, I felt that it might take me a while to improve on their algorithms! (A man's gotta know his limitations).

The GNU WIN32 Project provides a compiled diff.exe (and a lot of other useful stuff), and I have included diff.exe as part of both downloads. The above page provides details of how to get the source code if the reader should require that.

Techniques Used

This project uses standard WIN32/MFC techniques as follows:

  • Spawn a process and capture the results
  • SDI application with multiple windows
  • Splitter windows
  • Owner draw list boxes
  • Specialized list boxes
  • Registry access

Comparing Files

This is where Diff is used to compare 2 files. The command and output will be something like the following:

C:\Code\DIFF>diff f1.cpp f2.cpp
1,2d0
< // program to add 2 numbers
< //
8c6,7
<       return x + y;
---
>       int res(x+y)
>       return res;
15a15,20
>
> //int main(int argc, char** argv)
> //{
> //    cout << "Result: " << Addit(1,2) << endl;
> //    return 1;
> //}

The lines we are interested in are the ones without < or > signs at the start, as these are simply to help a human see which lines come from which file. The other lines tell us what the differences between the files are, or put another way, what we need to do to either file to make it the same as the other. It is these lines that we parse out and use to build the visual display.

The results above are interpreted as follows:

  1. 1,2d0 means delete lines 1-2 of file 1; or, if changing file 2 into file 1, append lines 1-2 of file 1 after line 0 of file 2.
  2. 8c6,7 means change line 8 of file 1 to read as lines 6-7 of file 2; or, if changing file 2 into file 1, change lines 6-7 of file 2 to read as line 8 of file 1.
  3. 15a15,20 means append lines 15-20 of file 2 after line 15 of file 1; or, if changing file 2 into file 1, delete lines 15-20 of file 2.

The GNU Diff documentation fully describes the way the results should be interpreted.

Comparing Directories

Comparing 2 files is good, but being able to recurse sub-directories like WinDiff is better. Luckily diff.exe provides command line options to allow this. The command and output will be something like the following:

C:\Code\DIFF>diff --recursive --report-identical-files --brief dir1 dir2
Files dir1\file1.cpp and dir2\file1.cpp are identical
Files dir1\file2.cpp and dir2\file2.cpp differ
Only in dir1: file3.cpp
Only in dir2: file4.cpp

The command line options are mostly self explanatory, but --brief tells Diff to only summarize each file. If this was omitted, a full Diff report for each file would be produced, taking longer. The above command executes very quickly, although I have only tried it on medium size projects of 200 or so files, with 20 or so sub-directories.

The results are parsed to produce a summary report just like with WinDiff. Double clicking a file then invokes Diff again to compare those 2 files, and a detailed report is displayed the same, as if the user had just chosen to compare those 2 files.

Note that because file names can contain the sequence " and " , some care is required when parsing the results.

The Scrolling Views

I have chosen to implement each view as an owner-draw list box. This allows me to customize the display to a great extent and I think they look OK. One problem is that when 2 files are displayed side by side in detail mode, I want them to keep in step when either one is scrolled. I achieve this by capturing all messages and when a scroll message is received, I first send it to the other list box. This works fine but can look a little odd sometimes as one view moves slightly after the other.

Future Direction

I am fairly pleased that RGDiff provides a useful, yet minimal implementation without too much effort expended. However the following are a few things that I think could improve RGDiff:

  • Birds eye view in the left margin, like WinDiff
  • Merge functionality (one at a time, or en-masse)
  • Better synchronized scrolling between views, in detail view
  • Better remembering of recently used files, like CodeProject front end to WinDiff

History

1.0.0.3 - 3rd March 2003 - Initial Version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United Kingdom United Kingdom
Software developer using C/C++, ASP, .NET and SQL Server/Oracle relational databases.

Comments and Discussions

 
Praisevery neat Pin
Southmountain6-Nov-21 5:04
Southmountain6-Nov-21 5:04 
QuestionFeature Request - Unix diff file import & export? Pin
daluu14-Jul-06 8:21
daluu14-Jul-06 8:21 
GeneralProblem comparing binary files Pin
YaronNir20-Mar-05 22:37
YaronNir20-Mar-05 22:37 
GeneralRe: Problem comparing binary files Pin
Rob Groves21-Mar-05 8:27
Rob Groves21-Mar-05 8:27 
GeneralRe: Problem comparing binary files Pin
YaronNir21-Mar-05 20:40
YaronNir21-Mar-05 20:40 
Generalthis code doesn't work for me :( Pin
YaronNir13-Mar-05 3:56
YaronNir13-Mar-05 3:56 
GeneralRe: this code doesn't work for me :( Pin
Rob Groves13-Mar-05 10:08
Rob Groves13-Mar-05 10:08 
GeneralRe: this code doesn't work for me :( Pin
YaronNir13-Mar-05 11:23
YaronNir13-Mar-05 11:23 
thanks for you reply!

I'm not sure what i did wrong, but i took your function 'RunDiff' as is, and modified it according to my needs and walla, it worked like a charm!

so thanks for all the help, keep up the good work!

cheers

Yaron
GeneralPretty good tool Pin
gal007hm9-Dec-04 7:04
gal007hm9-Dec-04 7:04 
Generalgreat tool Pin
fvcs20-Sep-04 18:01
fvcs20-Sep-04 18:01 
GeneralMade some improvements Pin
tnimble18-Jul-04 1:40
tnimble18-Jul-04 1:40 
GeneralRe: Made some improvements Pin
Rob Groves18-Jul-04 10:23
Rob Groves18-Jul-04 10:23 
GeneralRe: Made some improvements Pin
Gud2114-Mar-05 10:13
Gud2114-Mar-05 10:13 
GeneralRe: Made some improvements Pin
Rob Groves4-Mar-05 21:21
Rob Groves4-Mar-05 21:21 
GeneralRe: Made some improvements Pin
Christian Ebel26-Apr-06 4:36
Christian Ebel26-Apr-06 4:36 
GeneralRe: Made some improvements Pin
Rob Groves26-Apr-06 7:41
Rob Groves26-Apr-06 7:41 
Generalhelp Pin
ttxuefeng25-Mar-04 14:25
ttxuefeng25-Mar-04 14:25 
GeneralRe: help Pin
Rob Groves26-Mar-04 7:31
Rob Groves26-Mar-04 7:31 
GeneralWinMerge Pin
ralfoide13-Dec-03 10:58
ralfoide13-Dec-03 10:58 
GeneralOLEACC.DLL Error Pin
ty078726-Oct-03 18:54
ty078726-Oct-03 18:54 
GeneralRe: OLEACC.DLL Error Pin
Rob Groves27-Oct-03 10:23
Rob Groves27-Oct-03 10:23 
GeneralRe: OLEACC.DLL Error Pin
surreybc9-May-04 16:05
surreybc9-May-04 16:05 
QuestionPosition? Pin
chen26-May-03 2:19
chen26-May-03 2:19 
GeneralVery Practical Question Pin
Chopper4-Mar-03 6:43
Chopper4-Mar-03 6:43 
GeneralRe: Very Practical Question Pin
Jörgen Sigvardsson4-Mar-03 7:59
Jörgen Sigvardsson4-Mar-03 7:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.