What I present here is a small GUI app that takes a specific source file, scans it, and recursively scans all included file building a list of inclusions to then display in a nice little tree.
Download source and executable here, [size 143K].
On my PII 266, I can generally scan all of a fairly complex stdafx.h in under 4 seconds.
- Full Drag and Drop server support:
You can drag a file from the list in the tree window into another application, e.g. DevStudio.
- Topmost window support:
The pushpin on the title bar pins the window to the screen so that it is always the topmost window. This makes browsing in combination with DevStudio much more convenient.
- INCLUDE path support:
You can set two include paths, the first is for your system includes, i.e. what DevStudio has in its Options/Directories dialog. The second is for your project specific paths.
- Find support:
You can search through the list for a file or part of file name.
- Source Code:
You get the source; use it, abuse it, credit who wrote it. Seriously, I may have put this together but a huge amount of the code here has been culled from the work of others.
This should be fairly obvious, but regardless, this is what to do.
- Set your INCLUDE path. The default is to simply pull in your INCLUDE environment value if you have one. The first time that you run Includes then you may want to check that this is accurate. You will only need to change the per-file INCLUDE value if you are adding /I... options to the compile line.
- The include depth defaults to 10, the intent here is more to simply fix any recursion loops than anything else, if you find that the number is too low, then simply increase it.
- Open a file. That's it.
- Parsing the source files is a little simplistic. I simply find every #include... entry, get the filename and then open that file and recurse. There is no note taken of any conditional compilation options, this means that the tree can show you headers as being included that simply aren't. As a rule I've not found this to be a problem, but do be aware of it.
- I only show a file once. The first time that a file is encountered it is logged and ignored from that point on. If you are interested in changing this there is a run time flag in the code (CIncludesDoc::m_once) that if set to true will force a full tree to be built. This is much, much slower and is also subject to recursion loops since there are many circular dependencies in both the MFC and standard headers, this is where the inclusion depth limit comes in to bail from ludicrous recursion. I decided that this wasn't of enough general use to even bother adding a GUI for this option, but it should be simple for anyone who's interested.
On to the Code:
First you'll see that there is a fair mix of styles in this code, sorry. I've been looking at more of the new standard C++ library and fiddling around with using std::string rather than CString, this does mean that both are used in this project, I can't say that I'm completely happy with this, but it's very hard to avoid using CString if you use MFC and I wanted to use std::string to see what it was like.
I'm very happy with the standard container classes, std::vector, std::set etc, you'll see that they crop up quite a bit.
The source has been built and tested on both VC 5 and 6.
The major files:
- Includes.cpp & Includes.h
Not too much, the main application object and about box.
The ubiquitous project file.
- IncludesDoc.cpp & IncludesDoc.h
The main scanning and parsing routines, along with the checks to see if the file has been visited once already.
- IncludeView.cpp & IncludeView.h
All of the code for adding the elements to the ListView as well as the grunt work of the drag and drop and find support.
- item.cpp & item.h
Storage object for the include file that we've processed.
- DropHelpers.cpp & DropHelpers.h
Some very neat code written by Jeffrey Richter for his book "Windows 95: A Developer's Guide", This deals with providing server support for WM_DROPFILES.
- HyperLink.cpp & HyperLink.h
Used in the about box to provide a hyperlink control.
- PaintCap.cpp & PaintCap.h
Paul DiLascia's Code to support owner draw caption bar painting, mainly used here as a foundation for my CTopCaption Class.
- Subclass.cpp & Subclass.h
Again from Paul DiLascia, this class supports the arbitrary subclassing of an MFC CWnd object, very cool.
- TopCaption.cpp & TopCaption.h
Derived from CCaptionPainter, this class' purpose is to provide a caption bar with a topmost pushpin.
- MainFrm.cpp & MainFrm.h
Responsible for persistent window positioning, and caption painting. If the OS supports drawing a gradient colour on the caption bar (Win98 and Win2K) then we use the system GradientFill routine to make the caption bar fall in with the rest of the OS, if we are in NT 4 or Win95 then we do our own gradient fill.
- Regexp.cpp & Regexp.h
My regular expression class, see http://www.codeguru.com/string/regexp.shtml
Convert a string with a sequence of delimited segments into a collection of those segments.
- SuperGridCtrl.cpp & SuperGridCtrl.h
Taken from Allan Nielsen's Multi column treelist, this version is slightly modified. I didn't need any of the editing options so this version can be compiled to be read only.
- TreeGridCtrl.cpp & TreeGridCtrl.h
Subclassed from CSuperGridCtrl, this class reflects some of the drag 'n' drop related messages up to the parent as well as providing searching support. Note that the searching uses regular expressions.
block<> is a simple class that provides std library iterator semantics to a block of memory. This can be handy for applying std library algorithms and functions to arbitrary lumps of memory.
Very simply routing to assist in function timings, search for _TIME_IT in the code to see an example.
- DebugStream.cpp &DebugStream.h
std::stream derived class to provide an interface to OutputDebugString.
- RTFStream.cpp & RTFStream.h
std::stream derived class to allow the insertion of formatted text into an RTF control.
Guy Gascoigne - Piggford Last modified: Wed Jan 20 15:24:46 Pacific Standard Time 1999