#include "stdafx.h"
#include "MUSHclient.h"
#include "mainfrm.h"


#ifdef _DEBUG
//#define new DEBUG_NEW
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

#ifdef _DEBUG

// dialog handling code on this page from: http://www.microsoft.com/msj/0198/hood0198.aspx

CStdioFile * pf = NULL;

// my printf function for the dialog code

void nickprintf (LPCTSTR lpszFormat, ...)
{
	va_list argList;
	va_start(argList, lpszFormat);
	CString str = CFormat (lpszFormat, argList);
	va_end(argList);

//  pf->WriteString (str);

}

//  This stuff here is for my MUSHclient documentation right now

#define NL "\r\n"
CString KeyCodeToString (const BYTE fVirt, const WORD key);
void StringToKeyCode (const CString strKey,
                      BYTE & fVirt,
                      WORD & key);

extern tCommandIDMapping CommandIDs [];

static void ProcessMenu (const CString strOwner, 
                         HMENU hMenu, 
                         CStdioFile & f, 
                         const int iType)
  {
  if (!hMenu)
    return;

  int iCount = GetMenuItemCount (hMenu);

 	HINSTANCE hInst = AfxGetResourceHandle();

  for (int nPos = 0; nPos < iCount; nPos++)
    {
    UINT ID = GetMenuItemID (hMenu, nPos);
    
    MENUITEMINFO mInfo;

    char sMenuName [200];

    mInfo.cbSize = sizeof mInfo;
    mInfo.fMask = MIIM_DATA | MIIM_ID | MIIM_SUBMENU | MIIM_TYPE;
    mInfo.dwTypeData  = sMenuName;
    mInfo.cch = sizeof sMenuName;

    // get menu info
    if (!GetMenuItemInfo (hMenu, nPos, TRUE, &mInfo))
      continue;

    // ignore separators, bitmaps
//    if ((mInfo.fType & MFT_STRING) == 0 && mInfo.hSubMenu == 0)
//      continue;

    CString strCommand = CommandIDToString (mInfo.wID);
    CString strName = sMenuName;

    // strip off alleged accelerator
    int i = strName.Find ('\t');
    if (i != -1)
      strName = strName.Left (i);
    // strip off underline stuff
    strName.Replace ("&", "");

    // if we have an internal command associated with it, list it
    if (strCommand.IsEmpty ())
      {
      if (mInfo.wID && !strOwner.IsEmpty ())     // warn if could not find non-zero ID
        TRACE (CFormat ("Could not find menu item %s, ID %i\n",
                (LPCTSTR) strName, mInfo.wID));
      }
    else
      {

      CString SQL;

      SQL = CFormat ("UPDATE commands SET menu = \"%s\" "
                     " WHERE command_name = \"%s\" AND when_active = %i; \n",
                     (LPCTSTR) (strOwner + strName),
                     (LPCTSTR) strCommand,
                     iType);
      f.WriteString (SQL);

      // get rid of the ellipses

      strName.Replace ("...", "");

      // we will default short_description to the menu name if nothing else there
      SQL = CFormat ("UPDATE commands SET short_description = \"%s\" "
                     " WHERE command_name = \"%s\" "
                     " AND when_active = %i "
                     " AND short_description IS NULL; \n",
                     (LPCTSTR) strName,
                     (LPCTSTR) strCommand,
                     iType);

      f.WriteString (SQL);

      char buff [300];

      if (LoadString (hInst, ID, buff, sizeof buff))
        {

        CString strText = buff;

        // after newline is hover prompt - get rid of it
        int i = strText.Find ('\n');
        if (i != -1)
          strText = strText.Left (i);

        strText.Replace ("\\", "\\\\"); // escape backslashes 
        strText.Replace ("\"", "\\\""); // escape quotes

        SQL = CFormat ("UPDATE commands SET short_description = \"%s\" "
                       " WHERE command_name = \"%s\" AND when_active = %i; \n",
                       (LPCTSTR) strText,
                       (LPCTSTR) strCommand,
                       iType);

        f.WriteString (SQL);

        }  // end of description existing
      
      }   // end of command idn our table

    ProcessMenu (strName + " -> ", mInfo.hSubMenu, f, iType);    // now do sub-menus

    } // end of getting menu items


  } // end of ProcessMenu
 
void ListAccelerators (CDocument * pDoc, const int iType)
  {
	POSITION pos = NULL;
  
  if (pDoc)
    {
    pos = pDoc->GetFirstViewPosition();
	  if (!pos)
		  return;
    }

  CStdioFile f ("c:\\commands.sql",
                  CFile::modeCreate | CFile::modeReadWrite|CFile::typeText);

  // create table entries for all commands
	for (int iCount = 0; CommandIDs [iCount].iCommandID; iCount++)
    {
    CString SQL;

    SQL = CFormat ("INSERT INTO commands (command_name, command_id, when_active, productid) "
                   "VALUES (\"%s\", %i, %i, 0);\n",
                  (LPCTSTR) CommandIDs [iCount].sCommandName,
                  CommandIDs [iCount].iCommandID,
                  iType);   // type of window

    f.WriteString (SQL);
    }

 	HINSTANCE hInst = AfxGetResourceHandle();

  CMDIChildWnd * pMDIframe = NULL;

  if (pos && pDoc)
    {
	  // work out what our MDI frame is - that will have the accelerators in it

	  CView* pView = pDoc->GetNextView(pos);
	  CWnd * pFrame =  pView->GetParentFrame ();
	  pMDIframe = (CMDIChildWnd *) pFrame;
	  }


ACCEL * pAccel = NULL;

try
  {

	HACCEL hAccel;
  
  if (pDoc)
    {
    hAccel = pDoc->GetDefaultAccelerator ();

    // none for the document? Try the MDI frame
    if (hAccel == 0 && pMDIframe)
      hAccel =  pMDIframe->GetDefaultAccelerator ();
    }
  else
    hAccel = Frame.GetDefaultAccelerator ();

	// find number of them
	int iCount = CopyAcceleratorTable (hAccel, NULL, 10000);

	pAccel = new ACCEL [iCount];

	CopyAcceleratorTable (hAccel, pAccel, iCount);

	for (int iAccel = 0; iAccel < iCount; iAccel++)
		{

    
    CString SQL;
    CString strCommand = CommandIDToString (pAccel [iAccel].cmd);

    SQL = CFormat ("UPDATE commands SET accelerator = \"%s\" "
                   " WHERE command_name = \"%s\" AND when_active = %i; \n",
                   (LPCTSTR) KeyCodeToString (pAccel [iAccel].fVirt, pAccel [iAccel].key),
                   (LPCTSTR) strCommand,
                   iType);

    f.WriteString (SQL);

    char buff [300];

    if (LoadString (hInst, pAccel [iAccel].cmd, buff, sizeof buff))
      {

      CString strText = buff;

      // after newline is hover prompt - get rid of it
      int i = strText.Find ('\n');
      if (i != -1)
        strText = strText.Left (i);

      strText.Replace ("\\", "\\\\"); // escape backslashes 
      strText.Replace ("\"", "\\\""); // escape quotes

      SQL = CFormat ("UPDATE commands SET short_description = \"%s\" "
                     " WHERE command_name = \"%s\" AND when_active = %i; \n",
                     (LPCTSTR) strText,
                     (LPCTSTR) strCommand,
                     iType);

      f.WriteString (SQL);

      }  // end of description existing

		}   // end of keymaps loop

    }
  catch (CException*)
    {
		delete [] pAccel;
		throw;
    } // end of catch

	delete [] pAccel;


  ProcessMenu ("", ::GetMenu (Frame.m_hWnd), f, iType);

  }   // end of ListAccelerators


 //==========================================
 // Matt Pietrek
 // Microsoft Systems Journal, January 1998
 // Program: DlgDump.EXE
 // FILE: DlgDumpHelper.CPP
 //==========================================
 #include <windows.h>
 #include <stdio.h>
 // Data and macro definitions to make bitfield/flag decoding easier
 
 typedef struct
 {
     DWORD   flag;
     PSTR    name;
 } DWORD_FLAG_DESCRIPTIONS;
 
 #define FLAG_AS_STRING( f ) { f, #f },
 
 #define WS_STYLE_FLAGS              \
 FLAG_AS_STRING( WS_POPUP )          \
 FLAG_AS_STRING( WS_CHILD )          \
 FLAG_AS_STRING( WS_MINIMIZE )       \
 FLAG_AS_STRING( WS_VISIBLE )        \
 FLAG_AS_STRING( WS_DISABLED )       \
 FLAG_AS_STRING( WS_CLIPSIBLINGS )   \
 FLAG_AS_STRING( WS_CLIPCHILDREN )   \
 FLAG_AS_STRING( WS_MAXIMIZE )       \
 FLAG_AS_STRING( WS_BORDER )         \
 FLAG_AS_STRING( WS_DLGFRAME )       \
 FLAG_AS_STRING( WS_VSCROLL )        \
 FLAG_AS_STRING( WS_HSCROLL )        \
 FLAG_AS_STRING( WS_SYSMENU )        \
 FLAG_AS_STRING( WS_THICKFRAME )     \
 FLAG_AS_STRING( WS_GROUP )          \
 FLAG_AS_STRING( WS_TABSTOP )        \
 
 DWORD_FLAG_DESCRIPTIONS WndStyleFlags[] =   // Style flags common to all wnds
 {
 WS_STYLE_FLAGS
 };
 
 #define NUMBER_WND_STYLE_FLAGS \
     (sizeof(WndStyleFlags) / sizeof(WndStyleFlags[0]))
 
 DWORD_FLAG_DESCRIPTIONS DlgStyleFlags[] = // All style flags used by dialogs
 {
 WS_STYLE_FLAGS
 FLAG_AS_STRING( DS_ABSALIGN )
 FLAG_AS_STRING( DS_SYSMODAL )
 FLAG_AS_STRING( DS_LOCALEDIT )
 FLAG_AS_STRING( DS_SETFONT )
 FLAG_AS_STRING( DS_MODALFRAME )
 FLAG_AS_STRING( DS_NOIDLEMSG )
 FLAG_AS_STRING( DS_SETFOREGROUND )
 FLAG_AS_STRING( DS_3DLOOK )
 FLAG_AS_STRING( DS_FIXEDSYS )
 FLAG_AS_STRING( DS_NOFAILCREATE )
 FLAG_AS_STRING( DS_CONTROL )
 FLAG_AS_STRING( DS_CENTER )
 FLAG_AS_STRING( DS_CENTERMOUSE )
 FLAG_AS_STRING( DS_CONTEXTHELP )
 };
 
 #define NUMBER_DLG_STYLE_FLAGS \
     (sizeof(DlgStyleFlags) / sizeof(DlgStyleFlags[0]))
 
 // Helper function that takes a set of flags, and constructs a string that
 // contains the names of all the flags that are set
 void GetBitfieldsAsString(  DWORD dwStyle, DWORD_FLAG_DESCRIPTIONS *, 
                             unsigned maxFlags, PSTR pszBuffer, unsigned cbLen )
 {
     if ( !cbLen || !pszBuffer )
         return;
     pszBuffer[0] = 0;   // Start it out null terminated
     BOOL fAtLeastOneFlag = FALSE;
     for ( unsigned i = 0; i < maxFlags; i++ )
     {
         if ( dwStyle & DlgStyleFlags[i].flag )
         {
             if ( fAtLeastOneFlag )
                 pszBuffer += sprintf(pszBuffer, " | %s",DlgStyleFlags[i].name);
             else
             {
                 fAtLeastOneFlag = TRUE;
                 pszBuffer += sprintf( pszBuffer, "%s", DlgStyleFlags[i].name );
             }
         }       
     }
 }
 // Helper function that reads a Unicode string out of a dialog template,
 // and stores the results in an ANSI (8-bit) buffer.  Returns a pointer to
 // the byte immediately following the string.
 PWORD GetDlgEmbeddedString( PWORD pwsz, PSTR pszBuffer, unsigned cbLen )
 {
     if ( !cbLen || !pszBuffer )
         return FALSE;
         
     *pszBuffer = 0;
         
     while ( *pwsz )     // Loop through all chars in the unicode string
     {
         if ( cbLen )    // While there's room, copy to the output buffer
             *pszBuffer++ = (BYTE)*pwsz;         
         pwsz++;
     }
     
     // Null terminate the output string
     if ( cbLen )                
         *pszBuffer = 0;         // Space was left over
     else
         *(pszBuffer-1) = 0;     // Wrote to the entire buffer.  Back up and
                                 // null out the last character
         
     return pwsz+1;  // return next WORD past the null terminator
 }
 
 PSTR GetDlgItemClassIdAsString( WORD classId )
 {
     switch ( classId )
     {
         case 0x0080: return "Button";
         case 0x0081: return "Edit";
         case 0x0082: return "Static";
         case 0x0083: return "List box";
         case 0x0084: return "Scroll bar";
         case 0x0085: return "Combo box";
         default: return "unknown";
     }
 }
 // Input: a ptr.  Output: the ptr aligned to a DWORD.
 #define ALIGN_DWORD( type, p ) ( (type)(((DWORD)p+3) & ~3 ))

 // Displays all the fields of a dialog control.  Returns the next address
 // following the control's data.
 LPDLGITEMTEMPLATE DumpDialogItem( LPDLGITEMTEMPLATE pDlgItemTemplate )
 {
     char szDlgItemStyles[512];
 
     // Emits "warning" if the WS_VISIBLE flag isn't set 
     if ( 0 == (pDlgItemTemplate->style & WS_VISIBLE) )
         nickprintf( "  *** Dialog item not visible ***\n" );
     // Start out by printing all the fixed fields in the DLGITEMTEMPLATE
     GetBitfieldsAsString(   pDlgItemTemplate->style,
                             WndStyleFlags, NUMBER_WND_STYLE_FLAGS,
                             szDlgItemStyles, sizeof(szDlgItemStyles) );
 
     nickprintf( "  style: %X (%s)\n", pDlgItemTemplate->style, szDlgItemStyles ); 
     nickprintf( "  dwExtendedStyle: %X\n", pDlgItemTemplate->dwExtendedStyle); 
 
     nickprintf( "  Coords: (%d,%d) - (%d,%d)\n",
                 pDlgItemTemplate->x, pDlgItemTemplate->y,
                 pDlgItemTemplate->x + pDlgItemTemplate->cx,
                 pDlgItemTemplate->y + pDlgItemTemplate->cy );
     nickprintf( "  id: %d\n", (signed short)pDlgItemTemplate->id);
     
     PWORD pClass, pTitle, pCreationData;
     char szAnsiString[256];
     // Following the fixed DLGITEMTEMPLATE, first up is the window class
     pClass = (PWORD)(pDlgItemTemplate+1);   // ptr math!
     if ( *pClass )
     {
         if ( 0xFFFF == *pClass )
         {
             pClass++;
             nickprintf( "  Class: %s\n", GetDlgItemClassIdAsString(*pClass++) );
         }
         else
         {
             pClass = GetDlgEmbeddedString(  pClass, szAnsiString,
                                             sizeof(szAnsiString) );
             nickprintf( "  Class: %s\n", szAnsiString );
         }
     }
     else
         pClass++;
     // Following the window class array is the title array
     pTitle = pClass;
     if ( *pTitle )
     {
         if ( 0xFFFF == *pTitle )
         {
             pTitle++;
             nickprintf( "  Title resource ID: %u\n", *pTitle++ );
         }
         else
         {
             pTitle = GetDlgEmbeddedString(  pTitle, szAnsiString,
                                             sizeof(szAnsiString) );
                                             
             nickprintf( "  Title: %s\n", szAnsiString );
         }
     }
     else
         pTitle++;
 
     pCreationData = pTitle;
     // Following the title array is the (optional) creation data.  We won't
     // show it here, because it's usually not meaningful as ASCII text
     if ( *pCreationData )
     {
         // Adjust for the creation data.  *pCreationData is in bytes, rather
         // than WORDs, so we divide by sizeof(DWORD) to make the ptr addition
         // come out correctly
         pCreationData = (PWORD)( (PBYTE)pCreationData + *pCreationData );
     }
     else
         pCreationData++;
     // Return value is next byte after the DLGITEMTEMPLATE and its
     // variable len  fields     
     return (LPDLGITEMTEMPLATE)pCreationData;
 }

 // Displays all the fields of a dialog template, and then calls DumpDialogItem
 // to display all the controls.
 BOOL DumpDialog( PVOID pDlg )
 {
     LPDLGTEMPLATE pDlgTemplate = (LPDLGTEMPLATE)pDlg;
     
     char szDlgStyles[512];
     PWORD pMenu, pClass, pTitle, pPointSize, pTypeface;
     char szAnsiString[256];
     RECT rectDlg;
     unsigned i;
             
     if ( HIWORD(pDlgTemplate->style) != 0xFFFF )// Is it a regular DLGTEMPLATE?
     {
         // Start out by printing all the fixed fields in the DLGTEMPLATE
         GetBitfieldsAsString(   pDlgTemplate->style,
                                 DlgStyleFlags, NUMBER_DLG_STYLE_FLAGS,
                                 szDlgStyles, sizeof(szDlgStyles) );
         nickprintf( "style: %08X (%s)\n", pDlgTemplate->style, szDlgStyles );
 
         nickprintf( "extended style: %08X\n", pDlgTemplate->dwExtendedStyle );          
 
         nickprintf( "controls: %u\n", pDlgTemplate->cdit );
         nickprintf( "Coords: (%d,%d) - (%d,%d)\n",
                 pDlgTemplate->x, pDlgTemplate->y,
                 pDlgTemplate->x + pDlgTemplate->cx,
                 pDlgTemplate->y + pDlgTemplate->cy );
         rectDlg.left = rectDlg.top = 0;
         rectDlg.right = pDlgTemplate->cx;
         rectDlg.bottom = pDlgTemplate->cy;
         // Following the fixed DLGTEMPLATE, first up is the menu
         pMenu = (PWORD)(pDlgTemplate + 1);  // ptr math!
         if ( *pMenu )
         {
             if ( 0xFFFF == *pMenu )
             {
                 pMenu++;
                 nickprintf( "Menu ID: %u\n", *pMenu++ );
             }
             else
             {
                 pMenu = GetDlgEmbeddedString(   pMenu, szAnsiString,
                                                 sizeof(szAnsiString) );
                 nickprintf( "Menu Name: %s\n", szAnsiString );
             }
         }
         else
             pMenu++;
         
         // Following the menu array is the "window class" array
         pClass = pMenu;
         if ( *pClass )
         {
             if ( 0xFFFF == *pClass )
                 nickprintf( "Class ID: %d\n", (signed short)*pClass++ );
             else
             {
                 pClass = GetDlgEmbeddedString(  pClass, szAnsiString,
                                                 sizeof(szAnsiString) );
                                                 
                 nickprintf( "Class Name: %s\n", szAnsiString );
             }
         }
         else
             pClass++;
         // Following the window class array is the title array
         pTitle = pClass;
         if ( *pTitle )
         {
             pTitle = GetDlgEmbeddedString(  pTitle, szAnsiString,
                                             sizeof(szAnsiString) );
             nickprintf( "Title: %s\n", szAnsiString );
         }
         else
             pTitle++;
         // Following the title array is the point size and font (if DS_SETFONT
         // is set in pDlgTemplate->Style
         if ( pDlgTemplate->style & DS_SETFONT )
         {       
             pPointSize = pTitle;
             pTypeface = pPointSize+1;
             pTypeface = GetDlgEmbeddedString( pTypeface, szAnsiString,
                                               sizeof(szAnsiString) );
             nickprintf( "Font: %u point %s\n", *pPointSize, szAnsiString );
         }
         else
             pTypeface = pTitle; 
 
         LPDLGITEMTEMPLATE pDlgItemTemplate = (LPDLGITEMTEMPLATE)pTypeface;
         
         // Now iterate through each of the controls, calling DumpDialogItem
         for ( i=0; i < pDlgTemplate->cdit; i++ )
         {
             pDlgItemTemplate = ALIGN_DWORD(LPDLGITEMTEMPLATE, pDlgItemTemplate);
 
             nickprintf( "  ----\n" );   // Print separator for next item
 
             // Check that the dialog item is within the bounds of the dialog.
             // If not, emit a warning message
             POINT ctlPt = { pDlgItemTemplate->x, pDlgItemTemplate->y };
             if ( !PtInRect( &rectDlg, ctlPt ) )
                 nickprintf( "  *** Item not within dialog ***\n" );
                 
             pDlgItemTemplate = DumpDialogItem( pDlgItemTemplate );
         }
     }
     else    // Left as an exercise for the reader... :-)
         nickprintf( "DLGTEMPLATEEX type not yet handled\n" );
             
     return TRUE;
 }

 // Displays all the fields of a dialog control.  Returns the next address
 // following the control's data.
 LPDLGITEMTEMPLATE WriteDialogItem( LPDLGITEMTEMPLATE pDlgItemTemplate, 
                  CStdioFile & f, 
                  LPCTSTR sName,
                  CString & strDescription)
 {

 CString strClass;
 CString strTitle;

     char szDlgItemStyles[512];
 
     // Emits "warning" if the WS_VISIBLE flag isn't set 
     if ( 0 == (pDlgItemTemplate->style & WS_VISIBLE) )
         nickprintf( "  *** Dialog item not visible ***\n" );
     // Start out by printing all the fixed fields in the DLGITEMTEMPLATE
     GetBitfieldsAsString(   pDlgItemTemplate->style,
                             WndStyleFlags, NUMBER_WND_STYLE_FLAGS,
                             szDlgItemStyles, sizeof(szDlgItemStyles) );
 
     nickprintf( "  style: %X (%s)\n", pDlgItemTemplate->style, szDlgItemStyles ); 
     nickprintf( "  dwExtendedStyle: %X\n", pDlgItemTemplate->dwExtendedStyle); 
 
     nickprintf( "  Coords: (%d,%d) - (%d,%d)\n",
                 pDlgItemTemplate->x, pDlgItemTemplate->y,
                 pDlgItemTemplate->x + pDlgItemTemplate->cx,
                 pDlgItemTemplate->y + pDlgItemTemplate->cy );
     nickprintf( "  id: %d\n", (signed short)pDlgItemTemplate->id);
     
     PWORD pClass, pTitle, pCreationData;
     char szAnsiString[256];
     // Following the fixed DLGITEMTEMPLATE, first up is the window class
     pClass = (PWORD)(pDlgItemTemplate+1);   // ptr math!
     if ( *pClass )
     {
         if ( 0xFFFF == *pClass )
         {
             pClass++;
             strClass = GetDlgItemClassIdAsString(*pClass++);
             nickprintf( "  Class: %s\n", (LPCTSTR) strClass );
         }
         else
         {
             pClass = GetDlgEmbeddedString(  pClass, szAnsiString,
                                             sizeof(szAnsiString) );
             nickprintf( "  Class: %s\n", szAnsiString );
             strClass = szAnsiString;
         }
     }
     else
         pClass++;
     // Following the window class array is the title array
     pTitle = pClass;
     if ( *pTitle )
     {
         if ( 0xFFFF == *pTitle )
         {
             pTitle++;
             strTitle = CFormat ("Resource ID: %u", *pTitle++);

             nickprintf( "  Title: %s\n", (LPCTSTR) strTitle );
         }
         else
         {
             pTitle = GetDlgEmbeddedString(  pTitle, szAnsiString,
                                             sizeof(szAnsiString) );                                             
             nickprintf( "  Title: %s\n", szAnsiString );
             strTitle = szAnsiString;
         }
     }
     else
         pTitle++;
 
     pCreationData = pTitle;
     // Following the title array is the (optional) creation data.  We won't
     // show it here, because it's usually not meaningful as ASCII text
     if ( *pCreationData )
     {
         // Adjust for the creation data.  *pCreationData is in bytes, rather
         // than WORDs, so we divide by sizeof(DWORD) to make the ptr addition
         // come out correctly
         pCreationData = (PWORD)( (PBYTE)pCreationData + *pCreationData );
     }
     else
         pCreationData++;

     if (strClass == "Button" || strClass == "Static")
       {
        strTitle.Replace ("&", "");
        strTitle.Replace ("\\", "\\\\"); // escape backslashes 
        strTitle.Replace ("\"", "\\\""); // escape quotes

        strDescription += CFormat ("\\r\\n<b>%s</b>\\r\\n\\r\\n",
                      (LPCTSTR) strTitle);

       }

     // Return value is next byte after the DLGITEMTEMPLATE and its
     // variable len  fields     
     return (LPDLGITEMTEMPLATE)pCreationData;
   } // end of WriteDialogItem

 // Displays all the fields of a dialog template, and then calls DumpDialogItem
 // to display all the controls.
 BOOL WriteDialog( PVOID pDlg, CStdioFile & f, LPCTSTR sName)
 {
CString strDescription;

     LPDLGTEMPLATE pDlgTemplate = (LPDLGTEMPLATE)pDlg;
     
     char szDlgStyles[512];
     PWORD pMenu, pClass, pTitle, pPointSize, pTypeface;
     char szAnsiString[256];
     RECT rectDlg;
     unsigned i;
             
     if ( HIWORD(pDlgTemplate->style) != 0xFFFF )// Is it a regular DLGTEMPLATE?
     {
         // Start out by printing all the fixed fields in the DLGTEMPLATE
         GetBitfieldsAsString(   pDlgTemplate->style,
                                 DlgStyleFlags, NUMBER_DLG_STYLE_FLAGS,
                                 szDlgStyles, sizeof(szDlgStyles) );
         // Following the fixed DLGTEMPLATE, first up is the menu
         pMenu = (PWORD)(pDlgTemplate + 1);  // ptr math!
         if ( *pMenu )
         {
             if ( 0xFFFF == *pMenu )
             {
                 pMenu++;
                 nickprintf( "Menu ID: %u\n", *pMenu++ );
             }
             else
             {
                 pMenu = GetDlgEmbeddedString(   pMenu, szAnsiString,
                                                 sizeof(szAnsiString) );
                 nickprintf( "Menu Name: %s\n", szAnsiString );
             }
         }
         else
             pMenu++;
         
         // Following the menu array is the "window class" array
         pClass = pMenu;
         if ( *pClass )
         {
             if ( 0xFFFF == *pClass )
                 nickprintf( "Class ID: %d\n", (signed short)*pClass++ );
             else
             {
                 pClass = GetDlgEmbeddedString(  pClass, szAnsiString,
                                                 sizeof(szAnsiString) );
                                                 
                 nickprintf( "Class Name: %s\n", szAnsiString );
             }
         }
         else
             pClass++;
         // Following the window class array is the title array
         pTitle = pClass;
         if ( *pTitle )
         {
             pTitle = GetDlgEmbeddedString(  pTitle, szAnsiString,
                                             sizeof(szAnsiString) );
             nickprintf( "Title: %s\n", szAnsiString );


             CString SQL;

             SQL = CFormat ("UPDATE dialogs SET title = \"%s\" "
                            " WHERE dialog_name = \"%s\"; \n",
                            (LPCTSTR) (szAnsiString),
                             sName);
             f.WriteString (SQL);

         }
         else
             pTitle++;
         // Following the title array is the point size and font (if DS_SETFONT
         // is set in pDlgTemplate->Style
         if ( pDlgTemplate->style & DS_SETFONT )
         {       
             pPointSize = pTitle;
             pTypeface = pPointSize+1;
             pTypeface = GetDlgEmbeddedString( pTypeface, szAnsiString,
                                               sizeof(szAnsiString) );
             nickprintf( "Font: %u point %s\n", *pPointSize, szAnsiString );
         }
         else
             pTypeface = pTitle; 
 
         LPDLGITEMTEMPLATE pDlgItemTemplate = (LPDLGITEMTEMPLATE)pTypeface;
         
         // Now iterate through each of the controls, calling DumpDialogItem
         for ( i=0; i < pDlgTemplate->cdit; i++ )
         {
             pDlgItemTemplate = ALIGN_DWORD(LPDLGITEMTEMPLATE, pDlgItemTemplate);
 
             nickprintf( "  ----\n" );   // Print separator for next item
 
             // Check that the dialog item is within the bounds of the dialog.
             // If not, emit a warning message
             POINT ctlPt = { pDlgItemTemplate->x, pDlgItemTemplate->y };
             if ( !PtInRect( &rectDlg, ctlPt ) )
                 nickprintf( "  *** Item not within dialog ***\n" );
                 
             pDlgItemTemplate = WriteDialogItem( pDlgItemTemplate, f, sName, strDescription );
         }

     CString SQL;

     SQL = CFormat ("UPDATE dialogs SET description = \"%s\" "
                    " WHERE dialog_name = \"%s\"; \n",
                    (LPCTSTR) (strDescription),
                     sName);
     f.WriteString (SQL);

     }
     else    // Left as an exercise for the reader... :-)
         TRACE( "DLGTEMPLATEEX type not yet handled\n" );
             
     return TRUE;
 }  // end of WriteDialog

BOOL CALLBACK EnumResNameProc(HMODULE hModule,   // module handle
                              LPCTSTR lpszType, // pointer to resource type
                              LPTSTR lpszName,  // pointer to resource name
                              LONG lParam)       // application-defined parameter
  {

  CStdioFile * f = (CStdioFile *) lParam;

  CString strName;
  int id = 0;

  if (HIWORD (lpszName) == 0)
    {
    id = LOWORD (lpszName);
    strName = CFormat ("%i", id);
    }
  else
    strName = lpszName;

  // find this named resource
  HRSRC hResInfo = FindResource (hModule, lpszName, lpszType);
 
  if (!hResInfo)
    return TRUE;

  // load it
  HGLOBAL hResData = LoadResource (hModule, hResInfo);

  if (!hResData)
    return TRUE;

  // lock it - now pDialog points to the resource data
  LPVOID pDialog = LockResource (hResData);

  if (!pDialog)
    return TRUE;

  CString SQL;

  SQL = CFormat ("INSERT INTO dialogs (dialog_name, dialog_id, productid) "
                 "VALUES (\"%s\", %i, 0);\n",
                (LPCTSTR) strName,
                id);

  f->WriteString (SQL);
 
  WriteDialog (pDialog, *f, strName);

  return TRUE;

  } // end of EnumResNameProc
 

void ListDialogs (void)
  {

  CStdioFile f ("c:\\dialogs.sql",
                  CFile::modeCreate | CFile::modeReadWrite|CFile::typeText);

  pf = &f;

 	HINSTANCE hInst = AfxGetResourceHandle();

  EnumResourceNames(hInst, RT_DIALOG, EnumResNameProc, (long) &f);

  } // end of ListDialogs


#endif  // _DEBUG