Display a Complex Data Structure in the VC6 Debugger

Environment: VC6

Introduction

When we evaluate an expression in VC6 Quick Watch Windows, we are allowed to run a function. In additional, we can give the function a parameter. As a result, if we need to display a very complex data structure, such as a Link, which is difficult to display all the data in Quick Watch, we can use this functionality to display the data.

Methodology

  1. To display a data structure such as a link, we need to pop up a dialog box (and ListBox) to display the data, and then we can go through all the data. However, this will introduce a problem because the VC debugger doesn't know whether the mouse and keyboard are clicked (pressed) for the application we're debugging or for the dialog box we used to debug. (I guess this is the case because my VC++ will not respond after several mouse clicks.)
  2. To solve the problem in Step 1, I can only create another application to display the data in the link.
  3. Because I should use another application to display data, we have a different memory address. To make it easy, I just write all the data in the link to the hard disk, and the application to display the link will read the data from disk and then display it.

Simplified Source Code

Place this in MyApplication.cpp:

// MyApplication.cpp initialization
BOOL MyApplication::InitInstance()
{
  // Initialize OLE libraries        // Standard Initialize
  MyLinkClass myLinkClass;           // my link class, which we
                                     // need to display
  myLinkClass.InitWithSomeData();    // give the link some data
  myLinkClass.DoOthers();            // make a break point in
                                     // here, and bring up
                                     // Quick Watch using the menu
                                     // or Shift+F9
  // in Quick Watch, type in Display(myLinkClass), and click
  // ReCalculate.
  return TRUE;

}
// we will call this function in Quick Watch
char* MyApplication(MyLinkClass & data)
    // it's good to be a global, not be a class member, function
{

  CString filename = "Display.xxx";    // give a random filename
  BOOL bStatus ; /
  if ( ! data) return "Not a valid Link!";
  bStatus = data.WriteToFile(filename);
  if ( bStatus != TRUE) return "Failed to write to disk!";
  CHAR command_line[300];
  strcpy(command_line, "Display.EXE ");
    // we need to create another application, Display.exe,
    // to display the data
  strncpy(command_line + strlen(command_line), filename, 200);
  bStatus = command_execution( command_line);
  // execute a command_line, such as using CreateProcess
  if ( bStatus )
    return "Success to Display!";
  else return "Fail to Display";

}

Note: We need to create another application called something like Display.exe, and put it in PATH. We should make sure it can be launched in our application. In Display.exe, we would read data from the file, and display it.