home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 April / Chip_1997-04_cd.bin / prezent / cb / data.z / APP.CPP < prev    next >
C/C++ Source or Header  |  1997-01-16  |  40KB  |  1,340 lines

  1. /* APP.CPP:  Application Expert Implementation
  2. */
  3.  
  4. //---------------------------------------------------------------------------
  5. #include <vcl\vcl.h>
  6. #pragma hdrstop
  7.  
  8. #include "app.h"
  9. #include "exconst.h"
  10. #include "filters.h"
  11.  
  12. //---------------------------------------------------------------------------
  13. #pragma resource "*.dfm"
  14. TAppExpert *AppExpert;
  15.  
  16. //  page numbers
  17. int pgMenus      = 0;
  18. int pgExtensions = 1;
  19. int pgSpeedbar   = 2;
  20. int pgAppInfo    = 3;
  21.  
  22. int FirstPage    = pgMenus;
  23. int LastPage     = pgAppInfo;
  24.  
  25. TPoint *DefaultButtonSize; //(24, 24);
  26. int    DefaultButtonSpace = 6;
  27. int    MenuItemCount = 18;
  28.  
  29. int  MenuItemCounts[]  = { 7, 4, 3, 4 };
  30. int  MenuItemOffsets[] = { 0, 7, 11, 14 };
  31. char *SampleBitmaps[]  = { "MENUDSGN",
  32.                            "EXTDSGN",
  33.                            "SPEEDDSGN",
  34.                            "INFODSGN" };
  35.  
  36. int     SourceBufferSize = 1024;
  37. char    *cCodeSnipets[csLastObject-1];
  38. THandle *hCodeResource;
  39. char    *cSourceBuffer;
  40. char    *cResourceBuffer;
  41.  
  42. //========================================= TAppExpert ==========
  43. void __fastcall TAppExpert::MenuClicked(TObject *Sender)
  44. {
  45. //  TMainItems MenuIndex;
  46.   bool       MenuOn;
  47.  
  48.   // a menu category has been turned on/off
  49.   for (int MenuIndex = mmFile; MenuIndex < mmHelp; ++MenuIndex)
  50.   {
  51.     switch(MenuIndex)
  52.     {
  53.       case mmFile:
  54.         MenuOn = cbFileMenu->Checked;
  55.         break;
  56.       case mmEdit:
  57.         MenuOn = cbEditMenu->Checked;
  58.         break;
  59.       case mmWindow:
  60.         MenuOn = cbWindowMenu->Checked;
  61.         break;
  62.       case mmHelp:
  63.         MenuOn = cbHelpMenu->Checked;
  64.         break;
  65.     }
  66.     if (!MenuOn)
  67.     {
  68.       RemoveItems(*SpeedList, (TMainItems)MenuIndex);
  69.       FSpeedIndex = 0;
  70.     }
  71.     if (MenuList->ItemIndex == MenuIndex)
  72.       MenuListClick(this);
  73.   }
  74. } // end of TAppExpert::MenuClicked()
  75.  
  76. //========================================== TAppExpert =========
  77. bool __fastcall TAppExpert::ValidateInfo(void)
  78. {
  79.   AnsiString e;
  80.   if (AppName->Text == "")
  81.   {
  82.     e = LoadStr(sAppNameRequired);
  83.     Application->MessageBox(e.c_str(), "ERROR", mbOK);
  84.     return false;
  85.   }
  86.   if (!IsValidIdent(AppName->Text))
  87.   {
  88.     e = LoadStr(sInvalidAppName);
  89.     Application->MessageBox(e.c_str(), "ERROR", mbOK);
  90.     return false;
  91.   }
  92.   if (!DirectoryExists(AppPath->Text))
  93.   {
  94.     e = LoadStr(sInvalidPath);
  95.     Application->MessageBox(e.c_str(), "ERROR", mbOK);
  96.     return false;
  97.   }
  98.   return true;
  99. } // end of TAppExpert::ValidateInfo()
  100.  
  101. //========================================== TAppExpert =========
  102. // calculate which page is next based on current page and settings->
  103. //  -1 = last page
  104. //  -2 = cannot move in requested direction
  105. int __fastcall TAppExpert::NextPage(TMoveDirection Direction)
  106. {
  107.   int CurPage;
  108.   int Result = -2;
  109.  
  110.   CurPage = PageControl->ActivePage->PageIndex;
  111.   switch(Direction)
  112.   {
  113.     case mdNoMove:
  114.       if (CurPage == LastPage)
  115.         Result = -1;
  116.       else
  117.         Result = 0;
  118.       break;
  119.     case mdPrevious:
  120.       switch(CurPage)
  121.       {
  122.         case 0: //pgMenus: // do nothing
  123.           break;
  124.         case 1: //pgExtensions:
  125.           Result = pgMenus;
  126.           break;
  127.         case 2: //pgSpeedbar:
  128.           if (cbFileMenu->Checked)
  129.             Result = pgExtensions;
  130.           else
  131.             Result = pgMenus;
  132.           break;
  133.         case 3: //pgAppInfo:
  134.           if (HasMenus())
  135.             Result = pgSpeedbar;
  136.           else
  137.             Result = pgMenus;
  138.           break;
  139.       }
  140.  
  141.     case mdNext:
  142.       switch(CurPage)
  143.       {
  144.         case 0: //pgMenus:
  145.             if (cbFileMenu->Checked)
  146.               Result = pgExtensions;
  147.             else
  148.               if (HasMenus())
  149.                 Result = pgSpeedbar;
  150.               else
  151.                 Result = pgAppInfo;
  152.           break;
  153.         case 1: //pgExtensions:
  154.           Result = pgSpeedbar;
  155.           break;
  156.         case 2: //pgSpeedbar:
  157.           Result = pgAppInfo;
  158.           break;
  159.         case 3: //pgAppInfo:
  160.           Result = -1;
  161.           break;
  162.       }
  163.   }
  164.   return Result;
  165. } // end of TAppExpert::NextPage()
  166.  
  167. //---------------------------------------------------------------
  168. void __fastcall GenerateMainFormFile(TAppExpert *AppExpert)
  169. {
  170.   int         buttonWidth = 25;
  171.   int         spaceWidth = 4;
  172.   AnsiString      filter;
  173.   int         buttonNumber;
  174.   int         buttonID;
  175.   AnsiString      buttonMethod;
  176.   AnsiString      buttonHint;
  177.   int         buttonX;
  178.   int         i;
  179.  
  180.   TFileName *textName = new TFileName(AppExpert->AppPath->Text);
  181.   if (textName->Length() > 0 && (textName[textName->Length()] != ':' ||
  182.                         textName[textName->Length()] != '\\'))
  183.     textName += '\\';
  184.  
  185.   TFileName *formName = new TFileName(*textName + LoadStr(sMainFormFile));
  186.   *textName += LoadStr(sMainFormText);
  187.  
  188.   TFileStream *textStream = new TFileStream(*textName, fmCreate);
  189.   TFileStream *formStream = new TFileStream(*formName, fmCreate);
  190.   try
  191.   {
  192.     WriteSnipet(textStream, csForm);
  193.     if (AppExpert->cbMDIApp->Checked)
  194.       WriteSnipet(textStream, csFormMDI);
  195.     if (AppExpert->HasMenus())
  196.       WriteSnipet(textStream, csFormMenu);
  197.     if (AppExpert->cbHints->Checked)
  198.     {
  199.       WriteSnipet(textStream, csHints);
  200.       if (AppExpert->cbStatusLine->Checked)
  201.         WriteSnipet(textStream, csCreateMethod);
  202.     }
  203.  
  204.     // write menus
  205.     if (AppExpert->HasMenus())
  206.     {
  207.       WriteSnipet(textStream, csMenuObject);
  208.  
  209.       if (AppExpert->cbFileMenu->Checked)
  210.         WriteSnipet(textStream, csFileMenuObject);
  211.       if (AppExpert->cbEditMenu->Checked)
  212.         WriteSnipet(textStream, csEditMenuObject);
  213.       if (AppExpert->cbWindowMenu->Checked)
  214.         WriteSnipet(textStream, csWindowMenuObject);
  215.       if (AppExpert->cbHelpMenu->Checked)
  216.         WriteSnipet(textStream, csHelpMenuObject);
  217.  
  218.       FmtWrite(textStream, "  end\n", OPENARRAY(TVarRec, (NULL)));
  219.  
  220.       if (AppExpert->cbFileMenu->Checked)
  221.       {
  222.         // create the dialog objects
  223.         filter = "";
  224.         for (i=0; i < AppExpert->ExtListBox->Items->Count; i++)
  225.           filter = AppExpert->ExtListBox->Items->Strings[i] + "|";
  226.                                 //TListBox
  227.         if (filter.SubString(1, filter.Length()) == "|")
  228.           filter.Delete(1, filter.Length());
  229.  
  230.         FmtWrite(textStream, cCodeSnipets[csOpenDialogObject],
  231.                  OPENARRAY(TVarRec, (filter)));
  232.         FmtWrite(textStream, cCodeSnipets[csSaveDialogObject],
  233.                  OPENARRAY(TVarRec, (filter)));
  234.         WriteSnipet(textStream, csPrintDialogObject);
  235.         WriteSnipet(textStream, csPrintSetupDialogObject);
  236.       }
  237.     }
  238.  
  239.     if (AppExpert->cbStatusLine->Checked)
  240.       WriteSnipet(textStream, csStatusLineObject);
  241.  
  242.     // create speedbuttons
  243.     if (AppExpert->SpeedButtonCount > 0)
  244.     {
  245.       WriteSnipet(textStream, csSpeedbarObject);
  246.  
  247.       buttonNumber = 0;
  248.       buttonX = 8;
  249.  
  250.       for (i=0; i < AppExpert->SpeedButtonCount; i++)
  251.       {
  252.         if (AppExpert->SpeedButtonID[i] > -1)
  253.         {
  254.           buttonNumber++;
  255.           buttonID = AppExpert->SpeedButtonID[i]-sMenuItemTextBase;
  256.           buttonMethod = LoadStr(buttonID + sMenuProcNames);
  257.           buttonHint = LoadStr(buttonID + sHintBase);
  258.           FmtWrite(textStream, cCodeSnipets[csSpeedButtonObject],
  259.                    OPENARRAY(TVarRec, (buttonNumber, buttonX,
  260.                                        buttonMethod, buttonHint)));
  261.           WriteGlyphData(textStream, buttonID + 100);
  262.           buttonX += buttonWidth-1;
  263.         }
  264.         else
  265.         {
  266.           buttonX += spaceWidth;
  267.         }
  268.       }
  269.       FmtWrite(textStream, "  end\n", OPENARRAY(TVarRec, (NULL)));
  270.     }
  271.  
  272.     FmtWrite(textStream, "end\n", OPENARRAY(TVarRec, (NULL)));
  273.  
  274.     // reset the text stream for conversion
  275.     textStream->Position = 0;
  276.  
  277.     try
  278.     {
  279.       ObjectTextToResource(textStream, formStream);
  280.     } catch(...)
  281.     {
  282.         delete formStream;
  283.         formStream = NULL;
  284.     }
  285.  
  286.   } catch(...)
  287.   {
  288.       delete textStream;
  289.       textStream = NULL;
  290.   }
  291.  
  292.   if (formStream) delete formStream;
  293.   if (textStream) delete textStream;
  294. } // end of GenerateMainFormFile()
  295.  
  296. //---------------------------------------------------------------
  297. void __fastcall InitCodeGeneration(void)
  298. {
  299.  
  300.   cSourceBuffer = new char[SourceBufferSize];
  301.  
  302.   // Find out how much data is in the code snippets resource and...
  303.   int ResourceSize = SizeofResource((void*)HInstance,
  304.                                     FindResource((void*)HInstance,
  305.                                     "SNIPETS", RT_RCDATA));
  306.  
  307.   // ...get them into global memory.
  308.   hCodeResource = (int*)LoadResource((void*)HInstance,
  309.                                      FindResource((void*)HInstance,
  310.                                                   "SNIPETS",
  311.                                                   RT_RCDATA));
  312.  
  313.   // Keep 'um from moving around,...
  314.   char *cResourcePtr = (char*)LockResource(hCodeResource);
  315.  
  316.   // ...allocate some local memory for them and...
  317.   cResourceBuffer = new char[ResourceSize];
  318.  
  319.   // ...transfer the global data to the local allocation.
  320.   memcpy(cResourceBuffer, cResourcePtr, ResourceSize);
  321.  
  322.   // Make ASCIIZ strings out of the snippets by replacing bars
  323.   // ('|') with zeros.
  324.   char *cText = cResourceBuffer;
  325.   for (int i=0; i < ResourceSize; i++)
  326.   {
  327.     if (*cText == '|')
  328.       *cText = 0;
  329.   }
  330. } // end of InitCodeGeneration()
  331.  
  332. //---------------------------------------------------------------
  333. void __fastcall DoneCodeGeneration(void)
  334. {
  335.   delete cSourceBuffer;
  336.   UnlockResource(hCodeResource);
  337.   FreeResource(hCodeResource);
  338.   delete cResourceBuffer;
  339. } // end of DoneCodeGeneration()
  340.  
  341. //---------------------------------------------------------------
  342. void __fastcall BinToHex(unsigned char *Binary, unsigned char *Text,
  343.                          int Count)
  344. {
  345.   char *HexChars = "0123456789ABCDEF";
  346.   int i;
  347.  
  348.   for (i=0; i < Count; i++)
  349.   {
  350.     *Text = HexChars[(Binary[i] && 0xF0) >> 4];
  351.     Text++;
  352.     *Text = HexChars[Binary[i] && 0x0F];
  353.     Text++;
  354.   }
  355. } // end of BinToHex()
  356.  
  357. //---------------------------------------------------------------
  358. void __fastcall WriteBinaryAsText(TStream *Input, TStream *Output)
  359. {
  360.   const int BytesPerLine = 32;
  361.   char *NewLine = "\r\n";
  362.  
  363.   bool MultiLine;
  364.   int i;
  365.   long Count;
  366.   char Buffer[BytesPerLine];
  367.   char Text[BytesPerLine * 2 - 1];
  368.  
  369.   // Get the size of the input buffer and...
  370.   Count = Input->Size;
  371.  
  372.   // ...if its longer than our max line length (32 bytes)
  373.   // flag it a multiline buffer.
  374.   MultiLine = Count > BytesPerLine;
  375.  
  376.   // Convert buffer size to hex and display.
  377.   BinToHex((unsigned char*)&Count, (unsigned char*)Text, 4);                              //110796EAS
  378.   Output->Write(Text, 4 * 2);
  379.  
  380.   while(Count > 0)
  381.   {
  382.     if (MultiLine)
  383.       Output->Write((void*)NewLine[0], 2);
  384.  
  385.     if (Count >= BytesPerLine)
  386.       i = BytesPerLine;
  387.     else
  388.       i = Count;
  389.  
  390.     Input->Read(Buffer, i);
  391.     BinToHex((unsigned char*)Buffer, (unsigned char*)Text, i);
  392.     Output->Write(Text, i * 2);
  393.     Count -= i;
  394.   }
  395. } // end of WriteBinaryAsText()
  396.  
  397. //---------------------------------------------------------------
  398. void _fastcall FmtWrite(TStream *Stream, char *Fmt,
  399.                         const TVarRec *Args, const int Args_Size)
  400. {
  401.   sprintf(cSourceBuffer, Fmt, Args);
  402.   Stream->Write((void*)cSourceBuffer, strlen(cSourceBuffer));
  403. } // end of FmtWrite()
  404.  
  405. //---------------------------------------------------------------
  406. void __fastcall WriteSnipet(TStream *Stream, TCodeSnipet Snipet)
  407. {
  408.   Stream->Write((void*)cCodeSnipets[Snipet],
  409.                 strlen(cCodeSnipets[Snipet]));
  410. } // end of WriteSnipet()
  411.  
  412. //---------------------------------------------------------------
  413. void __fastcall WriteIdent(TStream *Stream, long ResID,
  414.                            const AnsiString VarType) {
  415.   sprintf(cSourceBuffer, "%s%s *%s;\n", INDENT, VarType.c_str(),
  416.                                         LoadStr(ResID).c_str());
  417.   Stream->Write((void*)cSourceBuffer, strlen(cSourceBuffer));
  418. } // WriteIdent()
  419.  
  420. //---------------------------------------------------------------
  421. void __fastcall WriteMenuItems(TStream *Stream, TMainItems MenuIndex)
  422. {
  423.   int i;
  424.  
  425.   for (i=0; i<MenuItemCounts[MenuIndex]-1; i++)
  426.   {
  427.     WriteIdent(Stream,
  428.                sMenuItemNameBase+MenuItemOffsets[MenuIndex]+i,
  429.                "TMenuItem");
  430.   }
  431. } // end of WriteMenuItems()
  432.  
  433. //---------------------------------------------------------------
  434. void __fastcall WriteMethodDecl(TStream *Stream, long ResID)
  435. {
  436.   sprintf(cSourceBuffer, "%svoid __fastcall %s(TObject *Sender);\n",
  437.           INDENT, LoadStr(ResID).c_str());
  438.   Stream->Write((void*)cSourceBuffer, strlen(cSourceBuffer));
  439. } // end of WriteMethodDecl()
  440.  
  441. //---------------------------------------------------------------
  442. void __fastcall WriteMethodHeader(TStream *Stream, long ResID)
  443. {
  444.   sprintf(cSourceBuffer, "%s%svoid __fastcall T%s::%s(TObject *Sender)",
  445.           SEPARATOR, CRLF, LoadStr(sMainForm).c_str(),
  446.           LoadStr(ResID).c_str());
  447.   Stream->Write((void*)cSourceBuffer, strlen(cSourceBuffer));
  448. } // end of WriteMethodHeader()
  449.  
  450. //---------------------------------------------------------------
  451. void __fastcall WriteMenuMethodDecls(TStream *Stream,
  452.                                      TMainItems MenuIndex)
  453. {
  454.   int i;
  455.  
  456.   for (i=0; i<MenuItemCounts[MenuIndex]; i++)
  457.     WriteMethodDecl(Stream, sMenuProcNames+MenuItemOffsets[MenuIndex]+i);
  458. } // end of WriteMethodDecls()
  459.  
  460. //---------------------------------------------------------------
  461. void __fastcall WriteMenuMethods(TStream *Stream, TMainItems MenuIndex,
  462.                                  TCodeSnipet BaseSnipet)
  463. {
  464.   int         id;
  465.   int         i;
  466.   TCodeSnipet snipet;
  467.  
  468.   id = sMenuProcNames + MenuItemOffsets[MenuIndex];
  469.   for (i=0; i<MenuItemCounts[MenuIndex]; i++)
  470.   {
  471.     WriteMethodHeader(Stream, id+i);
  472.     snipet = TCodeSnipet(i+BaseSnipet);
  473.     WriteSnipet(Stream, snipet);
  474.   }
  475. } // end of WriteMenuMethods()
  476.  
  477. //---------------------------------------------------------------
  478. void __fastcall WriteGlyphData(TStream *Stream, long BitmapID)
  479. {
  480.   Graphics::TBitmap *bitmap = new Graphics::TBitmap;
  481.   TMemoryStream *memory = new TMemoryStream;
  482.  
  483.   try
  484.   {
  485.     bitmap->Handle = LoadBitmap((void*)HInstance, PChar(BitmapID));
  486.  
  487.     // stream the bitmap to a memory stream, and the write that
  488.     // stream as text.
  489.     try
  490.     {
  491.       bitmap->SaveToStream(memory);
  492.       memory->Position = 0;
  493.       WriteBinaryAsText(memory, Stream);   // 1 invokation
  494.     } catch(...)
  495.     {
  496.         delete memory;
  497.         memory = NULL;
  498.     }
  499.   } catch(...)
  500.   {
  501.       delete bitmap;
  502.       bitmap = NULL;
  503.   }
  504.  
  505.   FmtWrite(Stream, "}\nend\n", OPENARRAY(TVarRec, (NULL)));
  506.   if (bitmap) delete bitmap;
  507.   if (memory) delete memory;
  508. } // end of WriteGlyphData()
  509.  
  510. //---------------------------------------------------------------
  511. TFileName* __fastcall GenerateProjectSource(TAppExpert *AppExpert)
  512. {
  513.   // Get the application expert's fully qualified specification
  514.   // and if it is not slash terminated, slash terminate it and...
  515.   TFileName *result = new TFileName;
  516.   *result = AppExpert->AppPath->Text;
  517.   if (result->Length() > 0 && (result[result->Length()] != ':' &&
  518.                                result[result->Length()] != '\\'))
  519.     result += '\\';
  520.  
  521.   // ...add a DPR extension.
  522.   *result += AppExpert->AppName->Text + ".CPP";
  523.  
  524.   TFileStream *projectFile = new TFileStream(*result, fmCreate);
  525.   try
  526.   {
  527.     sprintf(cSourceBuffer, cCodeSnipets[csProgram],
  528.             AppExpert->AppName->Text.c_str());
  529.     projectFile->Write(cSourceBuffer, strlen(cSourceBuffer));
  530.   } catch(...)
  531.   {
  532.       delete projectFile;
  533.       projectFile = NULL;
  534.   }
  535.  
  536.   return result;
  537. } // end of GenerateProjectSource()
  538.  
  539. //---------------------------------------------------------------
  540. void __fastcall GenerateHdrSourceFile(TAppExpert *AppExpert)
  541. {
  542.   AnsiString      buttonName;//[80];
  543.   AnsiString      buttonText;//[30];
  544.   int         buttonID;
  545.   int         i;
  546.  
  547.   TFileName *filename = new TFileName(AppExpert->AppPath->Text);
  548.   if (filename->Length() > 0 && (filename[filename->Length()] != ':' &&
  549.                                  filename[filename->Length()] != '\\'))
  550.     filename += '\\';
  551.  
  552.   *filename += LoadStr(sHdrSourceFile);
  553.  
  554.   TFileStream *stream = new TFileStream(*filename, fmCreate);
  555.   try
  556.   {
  557.     WriteSnipet(stream, csHdr1);
  558. //    sourcePos = cSourceBuffer;
  559.     *cSourceBuffer = 0;
  560.  
  561.     // create the menu declarations
  562.     if (AppExpert->HasMenus())
  563.     {
  564.       WriteIdent(stream, sMainMenu, "TMainMenu");
  565.       if (AppExpert->cbFileMenu->Checked)
  566.         WriteMenuItems(stream, mmFile);
  567.       if (AppExpert->cbEditMenu->Checked)
  568.         WriteMenuItems(stream, mmEdit);
  569.       if (AppExpert->cbWindowMenu->Checked)
  570.         WriteMenuItems(stream, mmWindow);
  571.       if (AppExpert->cbHelpMenu->Checked)
  572.         WriteMenuItems(stream, mmHelp);
  573.     }
  574.  
  575.     // create any variable declarations
  576.     if (AppExpert->cbStatusLine->Checked)
  577.       WriteIdent(stream, sStatusLine, "TStatusBar");
  578.  
  579.     if (AppExpert->cbFileMenu->Checked)
  580.     {
  581.       WriteIdent(stream, sOpenDialog, "TOpenDialog");
  582.       WriteIdent(stream, sSaveDialog, "TSaveDialog");
  583.       WriteIdent(stream, sPrintDialog, "TPrintDialog");
  584.       WriteIdent(stream, sPrintSetupDialog, "TPrinterSetupDialog");
  585.     }
  586.  
  587.     // create speedbuttons
  588.     if (AppExpert->SpeedButtonCount > 0)
  589.     {
  590.       WriteIdent(stream, sSpeedBar, "TPanel");
  591.       buttonName = (AnsiString)INDENT + "TSpeedButton *" + LoadStr(sSpeedButton) +
  592.                    ";  // %s" + CRLF;
  593.  
  594.       buttonID = 1;
  595.       for (i=0; i < AppExpert->SpeedButtonCount; i++)
  596.       {
  597.         if (AppExpert->SpeedButtonID[i] > -1)
  598.         {
  599.           buttonText = LoadStr(AppExpert->SpeedButtonID[i]);
  600.           sprintf(cSourceBuffer, buttonName.c_str(), buttonID,
  601.                   buttonText.c_str());
  602.           stream->Write(cSourceBuffer, strlen(cSourceBuffer));
  603.           buttonID++;
  604.         }
  605.       }
  606.     }
  607.  
  608.     // generate method declarations
  609.     if (AppExpert->cbStatusLine->Checked &&
  610.         AppExpert->cbHints->Checked)
  611.     {
  612.       WriteMethodDecl(stream, sFormCreateProc);
  613.       WriteMethodDecl(stream, sShowHelpProc);
  614.     }
  615.  
  616.     if (AppExpert->cbFileMenu->Checked)
  617.       WriteMenuMethodDecls(stream, mmFile);
  618.     if (AppExpert->cbEditMenu->Checked)
  619.       WriteMenuMethodDecls(stream, mmEdit);
  620.     if (AppExpert->cbWindowMenu->Checked)
  621.       WriteMenuMethodDecls(stream, mmWindow);
  622.     if (AppExpert->cbHelpMenu->Checked)
  623.       WriteMenuMethodDecls(stream, mmHelp);
  624.  
  625.     WriteSnipet(stream, csHdr2);
  626.  
  627.   } catch(...)
  628.   {
  629.       delete stream;
  630.       stream = NULL;
  631.   }
  632.  
  633.   if (stream) delete stream;
  634. } // end of GenerateHdrSourceFile()
  635.  
  636. //---------------------------------------------------------------
  637. void __fastcall GenerateMainSourceFile(TAppExpert *AppExpert) {
  638.   AnsiString      ButtonName;
  639.   AnsiString      ButtonText;
  640.  
  641.   TFileName *filename = new TFileName(AppExpert->AppPath->Text);
  642.   if (filename->Length() > 0 && (filename[filename->Length()] != ':' &&
  643.                                  filename[filename->Length()] != '\\'))
  644.     filename += '\\';
  645.  
  646.   *filename += LoadStr(sMainSourceFile);
  647.  
  648.   TFileStream *stream = new TFileStream(*filename, fmCreate);
  649.   try
  650.   {
  651.     WriteSnipet(stream, csMainImpl);
  652.     *cSourceBuffer = 0;
  653.  
  654.     // write code implementations
  655.     if (AppExpert->cbStatusLine->Checked &&
  656.         AppExpert->cbHints->Checked)
  657.     {
  658.       WriteMethodHeader(stream, sFormCreateProc);
  659.       WriteSnipet(stream, csFormCreateProc);
  660.       WriteMethodHeader(stream, sShowHelpProc);
  661.       WriteSnipet(stream, csShowHelpProc);
  662.     }
  663.  
  664.     // create any variable declarations
  665.     if (AppExpert->cbFileMenu->Checked)
  666.       WriteMenuMethods(stream, mmFile, csFileNewProc);
  667.  
  668.     if (AppExpert->cbEditMenu->Checked)
  669.       WriteMenuMethods(stream, mmEdit, csEditUndoProc);
  670.  
  671.     // create speedbuttons
  672.     if (AppExpert->cbWindowMenu->Checked)
  673.       WriteMenuMethods(stream, mmWindow, csWindowTileProc);
  674.  
  675.     if (AppExpert->cbHelpMenu->Checked)
  676.       WriteMenuMethods(stream, mmHelp, csHelpContentsProc);
  677.  
  678.     AnsiString s = (AnsiString)SEPARATOR + CRLF;
  679.     FmtWrite(stream, s.c_str(), OPENARRAY(TVarRec, (NULL)));
  680.   } catch(...)
  681.   {
  682.       delete stream;
  683.       stream = NULL;
  684.   }
  685.  
  686.   if (stream) delete stream;
  687. } // end of GenerateMainSourceFile()
  688.  
  689. //---------------------------------------------------------------
  690. // interface void
  691. void __fastcall ApplicationExpert(TIToolServices *ToolServices)
  692. {
  693.   AnsiString usesClause;
  694.  
  695.   TAppExpert *d = new TAppExpert(Application);
  696.   TFileName *projectName = new TFileName;
  697.   try
  698.   {
  699.     if (d->ShowModal() == 1 /*mrOK*/)                             //112696EAS
  700.       InitCodeGeneration();
  701.  
  702.       try
  703.       {
  704.         projectName = &ExpandFileName(*GenerateProjectSource(d));
  705.         GenerateHdrSourceFile(d);
  706.         GenerateMainSourceFile(d);
  707.         GenerateMainFormFile(d);
  708.       } catch(...)
  709.       {
  710.         DoneCodeGeneration();
  711.       }
  712.  
  713.       // open the new project
  714.       if (ToolServices != NULL && ToolServices->CloseProject())
  715.         ToolServices->OpenProject(*projectName);
  716.  
  717.   } catch(...)
  718.   {
  719.       delete d;
  720.       d = NULL;
  721.   }
  722.  
  723.   if (d) delete d;
  724. } // end of ApplicationExpert()
  725.  
  726. //---------------------------------------------------------------
  727. bool __fastcall EditFilterInfo(AnsiString &Filter)
  728. {
  729.   TFilterDlg *d;
  730.   bool       result;
  731.  
  732.   d = new TFilterDlg(Application);
  733.   try
  734.   {
  735.     d->Filter = Filter;
  736.     result = d->ShowModal() == 1; // mrOK;                       //112696EAS
  737.     if (result)
  738.       Filter = d->Filter;
  739.  
  740.   } catch(...)
  741.   {
  742.     delete d;
  743.     d = NULL;
  744.   }
  745.  
  746.   if (d) delete d;
  747.   return result;
  748. } // end of EditFilterInfo()
  749.  
  750. //---------------------------------------------------------------
  751. void __fastcall ClearButtonImages(TList *List)
  752. {
  753.   int i;
  754.  
  755.   for (i=0; i < List->Count; i++)
  756.     (TButtonImage*)(List[i]).Free();
  757.  
  758.   List->Clear();
  759. } // end ClearButtonImages()
  760.  
  761. //=========================================[ TButtonImage ]======
  762. // TButtonImage
  763. __fastcall TButtonImage::TButtonImage(void)
  764. {
  765.   bmFBitmap = new Graphics::TBitmap;
  766.   FNumGlyphs = 1;
  767. }
  768.  
  769. //=========================================[ TButtonImage ]======
  770. __fastcall TButtonImage::~TButtonImage(void)
  771. {
  772.   delete bmFBitmap;
  773. }
  774.  
  775. //========================================= TButtonImage ========
  776. void __fastcall TButtonImage::SetBitmapID(long Value)
  777. {
  778.   if (FBitmapID != Value)
  779.   {
  780.     FBitmapID = Value;
  781.     bmFBitmap->Handle = LoadBitmap((void*)HInstance, PChar(FBitmapID));
  782.   }
  783. } // end of TButtonImage::SetBitmapID()
  784.  
  785. //===============================================================
  786. void __fastcall TButtonImage::Draw(TCanvas *Canvas, int X, int Y)
  787. {
  788.   int    BX;
  789.   TRect  Target;
  790.   TRect  Source;
  791.   TColor SavePen;
  792.   TColor SaveBrush;
  793.  
  794.   SavePen = Canvas->Pen->Color;
  795.   SaveBrush = Canvas->Brush->Color;
  796.  
  797.   Target = DrawButtonFace(Canvas, Bounds(X, Y, DefaultButtonSize->x,
  798.                           DefaultButtonSize->y), 1, bsWin31, False,
  799.                           False, False);
  800.  
  801.   // draw bitmap
  802.   BX = bmFBitmap->Width / FNumGlyphs;
  803.   if (BX > 0)
  804.   {
  805.     Target = Bounds(X, Y, BX, bmFBitmap->Height);
  806.     OffsetRect((RECT*)&Target, (DefaultButtonSize->x / 2) - (BX / 2),
  807.                (DefaultButtonSize->y / 2) - (bmFBitmap->Height / 2));
  808.     Source = Bounds(0, 0, BX, bmFBitmap->Height);
  809.     Canvas->BrushCopy(Target, bmFBitmap, Source,
  810.                       bmFBitmap->Canvas->Pixels[0][bmFBitmap->Height - 1]);
  811.   }
  812.  
  813.   Canvas->Pen->Color = SavePen;
  814.   Canvas->Brush->Color = SaveBrush;
  815. } // end of TButtonImage::Draw()
  816.  
  817. //===============================================================
  818. //===============================================================
  819.  
  820. //========================================== TAppExpert =========
  821. void __fastcall TAppExpert::FormCreate(TObject *Sender)
  822. {
  823.   long         ID;
  824.   TButtonImage *ButtonImage;
  825.  
  826.   SpeedList            = new TList;
  827.   ButtonList           = new TList;
  828.   Offscreen            = new Graphics::TBitmap;
  829.   Offscreen->Width     = Speedbar->Width;
  830.   Offscreen->Height    = Speedbar->Height;
  831.   SpeedPointer         = new Graphics::TBitmap;
  832.   SpeedPointer->Handle = LoadBitmap((void*)HInstance, "SPEEDPOINTER");
  833.   SampleBmp            = new Graphics::TBitmap;
  834.  
  835.   // fill the MenuItemList with the speedbuttons
  836.   for (ID=sMenuItemTextBase; ID < sMenuItemTextBase + MenuItemCount; ID++)
  837.   {
  838.     ButtonImage            = new TButtonImage;
  839.     ButtonImage->NumGlyphs = 2;
  840.     ButtonImage->BitmapID  = ID;
  841.     ButtonList->Add(ButtonImage);
  842.   }
  843.  
  844.   // This is required to prevent the Speedbar from erasing its
  845.   // background each time it paints->  This dramatically reduces
  846.   // (eliminates) any flicker when painting-> (try { commenting
  847.   // out this line to see the difference)
  848.   Speedbar->ControlStyle << csOpaque;
  849.  
  850.   PageControl->ActivePage = PageControl->Pages[FirstPage];
  851.   SampleBmp->Handle = LoadBitmap((void*)HInstance,
  852.                                  SampleBitmaps[FirstPage]);
  853.  
  854.   RefreshButtons();
  855. } // end of TAppExpert::FormCreate()
  856.  
  857. //========================================== TAppExpert =========
  858. void __fastcall TAppExpert::FormDestroy(TObject *Sender)
  859. {
  860.   ClearButtonImages(ButtonList);
  861.   delete ButtonList;
  862.   delete SpeedList;
  863.   delete SpeedPointer;
  864.   delete Offscreen;
  865.   delete SampleBmp;
  866. } // end of TAppExpert::FormDestroy()
  867.  
  868. //========================================== TAppExpert =========
  869. bool __fastcall TAppExpert::HasMenus(void)
  870. {
  871.   return (cbFileMenu->Checked || cbEditMenu->Checked ||
  872.           cbWindowMenu->Checked || cbHelpMenu->Checked);
  873. } // end of TAppExpert::HasMenus()
  874.  
  875. //========================================= TAppExpert ==========
  876. void __fastcall TAppExpert::RefreshButtons(void)
  877. {
  878.   switch(NextPage(mdNoMove))
  879.   {
  880.     case -1:
  881.       NextButton->Caption = LoadStr(sFinish);
  882.       break;
  883.     case 0:
  884.       NextButton->Caption = LoadStr(sNext);
  885.       break;
  886.   }
  887.  
  888.   switch(NextPage(mdPrevious))
  889.   {
  890.     case -2:
  891.       PrevButton->Enabled = False;
  892.       break;
  893.     default:
  894.       PrevButton->Enabled = True;
  895.       break;
  896.   }
  897. } // end of TAppExpert::RefreshButtons()
  898.  
  899. //---------------------------------------------------------------
  900. void __fastcall RemoveItems(TList &List, TMainItems MenuIndex)
  901. {
  902.   int          StartID;
  903.   int          EndID;
  904.   int          i;
  905.   TButtonImage *ButtonImage;
  906.  
  907.   StartID = sMenuItemTextBase + MenuItemOffsets[MenuIndex];
  908.   EndID = StartID + MenuItemCounts[MenuIndex];
  909.  
  910.   i = 0;
  911.  
  912.   while(i < List.Count)
  913.   {
  914.     ButtonImage = (TButtonImage*)List.Items[i];
  915.     if (ButtonImage != 0 && ButtonImage->BitmapID < EndID &&
  916.         ButtonImage->BitmapID >= StartID)
  917.       List.Delete(i);
  918.     else
  919.       i++;
  920.   }
  921. } // end of TAppExpert::RemoveItems()
  922.  
  923. //========================================== TAppExpert =========
  924. void __fastcall TAppExpert::NextPrevClick(TObject *Sender)
  925. {
  926.   int NewPage;
  927.  
  928.   if (Sender == PrevButton)
  929.     NewPage = NextPage(mdPrevious);
  930.   else
  931.     NewPage = NextPage(mdNext);
  932.  
  933.   switch(NewPage)
  934.   {
  935.     case -1:
  936.       if (ValidateInfo())
  937.         ModalResult = 1; //mrOK;                                 //112796
  938.       break;
  939.     case -2:
  940.       break; // do nothing
  941.     default:
  942.       if (SampleBitmaps[NewPage] != 0)
  943.       {
  944.         SampleBmp->Handle = LoadBitmap((void*)HInstance,
  945.                                        SampleBitmaps[NewPage]);
  946.         Sample->Invalidate();
  947.       }
  948.       PageControl->ActivePage = PageControl->Pages[NewPage];
  949.   }
  950.   RefreshButtons();
  951. } // end of TAppExpert::NextPrevClick()
  952.  
  953. //=========================================== TAppExpert ========
  954. // draw the file extension list box
  955. void __fastcall TAppExpert::DrawExtension(TWinControl *Control,
  956.                                           int Index,
  957.                                           const TRect &Rect,
  958.                                           TOwnerDrawState State)
  959. {
  960.   int    P;
  961.   TRect  R;
  962.   char   C[255];
  963.   AnsiString S;
  964.  
  965.   // find the separator in the string
  966.   P = ExtListBox->Items->Strings[Index].Pos("|");
  967.  
  968.   // adjust the rectangle so we draw only the left "column"
  969.   R = Rect;
  970.  
  971.   // draw the filter description
  972.   S = ExtListBox->Items->Strings[Index].SubString(1, P - 1);
  973.   R.Right = R.Left + ExtHeader->SectionWidth[0];
  974.   ExtTextOut((void*)ExtListBox->Canvas->Handle, R.Left, R.Top,
  975.              ETO_CLIPPED | ETO_OPAQUE, (RECT*)&R, StrPCopy(C, S),
  976.              S.Length(), NULL);
  977.  
  978.   // move the rectangle to the next column
  979.   R.Left = R.Right;
  980.   R.Right = Rect.Right;
  981.   S = ExtListBox->Items->Strings[Index].SubString(P + 1, 255);
  982.   ExtTextOut((void*)ExtListBox->Canvas->Handle, R.Left, R.Top,
  983.              ETO_CLIPPED | ETO_OPAQUE, (RECT*)&R, StrPCopy(C, S),
  984.              S.Length(), NULL);
  985. } // end of TAppExpert::DrawEstension()
  986.  
  987. //========================================== TAppExpert =========
  988. void __fastcall TAppExpert::HeaderSized(TObject *Sender,
  989.                                         int ASection,
  990.                                         int AWidth)
  991. {
  992.   ExtListBox->Invalidate();
  993. } // end of TAppExpert::HeaderSized()
  994.  
  995. //=========================================== TAppExpert ========
  996. void __fastcall TAppExpert::AddClick(TObject *Sender)
  997. {
  998.   AnsiString Filter;
  999.  
  1000.   Filter = "";
  1001.   if (EditFilterInfo(Filter))
  1002.     ExtListBox->Items->Add(Filter);
  1003. } // end of TAppExpert::AddClick()
  1004.  
  1005. //========================================== TAppExpert =========
  1006. void __fastcall TAppExpert::EditClick(TObject *Sender)
  1007. {
  1008.   AnsiString Filter;
  1009.  
  1010.   if (ExtListBox->ItemIndex > -1)
  1011.   {
  1012.     Filter = ExtListBox->Items->Strings[ExtListBox->ItemIndex];
  1013.     if (EditFilterInfo(Filter))
  1014.       ExtListBox->Items->Strings[ExtListBox->ItemIndex] = Filter;
  1015.   }
  1016. } // end of TAppExpert::EditClick()
  1017.  
  1018. //========================================== TappExpert =========
  1019. void __fastcall TAppExpert::DeleteClick(TObject *Sender)
  1020. {
  1021.   if (ExtListBox->ItemIndex > -1)
  1022.     ExtListBox->Items->Delete(ExtListBox->ItemIndex);
  1023. } // end of TAppExpert::DeleteClick()
  1024.  
  1025. //========================================= TAppExpert ==========
  1026. void __fastcall TAppExpert::MoveClick(TObject *Sender)
  1027. {
  1028.   int Delta;
  1029.   int NewPos;
  1030.  
  1031.   if (ExtListBox->ItemIndex != -1)
  1032.   {
  1033.     if (Sender == UpButton)
  1034.       Delta = -1;
  1035.     else
  1036.       if (Sender == DownButton)
  1037.         Delta = 1;
  1038.       else
  1039.         Delta = 0;
  1040.  
  1041.     if (Delta != 0)
  1042.     {
  1043.       NewPos = ExtListBox->ItemIndex + Delta;
  1044.       if (NewPos >= 0 && NewPos < ExtListBox->Items->Count)
  1045.       {
  1046.         ExtListBox->Items->Move(ExtListBox->ItemIndex, NewPos);
  1047.         ExtListBox->ItemIndex = NewPos;
  1048.       }
  1049.     }
  1050.   }
  1051. } // end of TAppExpert::MoveClick()
  1052.  
  1053. //========================================== TAppExpert =========
  1054. // return the rectangle of the specified speedbutton or space
  1055. TRect __fastcall TAppExpert::SpeedButtonRect(int Index)
  1056. {
  1057.   int i;
  1058.   int x;
  1059.   TRect Result;
  1060.  
  1061.   x = 10;  // first usable position
  1062.  
  1063.   for (i=0; i < Index; i++)
  1064.     if (SpeedList->Items[i] == NULL)
  1065.       x += DefaultButtonSpace;
  1066.     else
  1067.       x += DefaultButtonSize->x-1;
  1068.  
  1069.   Result = Bounds(x, 5, DefaultButtonSize->x, DefaultButtonSize->y);
  1070.  
  1071.   if (Index < SpeedList->Count && SpeedList->Items[Index] == NULL)
  1072.     Result.Right = Result.Left + DefaultButtonSpace;
  1073.  
  1074.   return Result;
  1075. } // end of TAppExpert::SpeedButtonRect()
  1076.  
  1077. //========================================== TAppExpert =========
  1078. // return an index into SpeedList from the TPoint
  1079. int __fastcall TAppExpert::SpeedButtonAtPos(const tagPOINT &Pos)
  1080. {
  1081.   TRect R;
  1082.   int   i;
  1083.  
  1084.   for (i=0; i < SpeedList->Count; i++)
  1085.   {
  1086.     R = SpeedButtonRect(i);
  1087.     if (PtInRect((RECT*)&R, Pos))
  1088.     {
  1089.       return i;
  1090.     }
  1091.   }
  1092.   return -1;
  1093. } // end of TAppExpert::SpeedButtonAtPos()
  1094.  
  1095. //========================================== TAppExpert =========
  1096. int __fastcall TAppExpert::GetSpeedButtonCount(void)
  1097. {
  1098.   return SpeedList->Count;
  1099. } // end of TAppExpert::GetSpeedButtonCount()
  1100.  
  1101. //========================================== TAppExpert =========
  1102. int __fastcall TAppExpert::GetSpeedButtonID(int Value)
  1103. {
  1104.   TButtonImage *ButtonImage;
  1105.   int Result;
  1106.  
  1107.   ButtonImage = (TButtonImage*)SpeedList->Items[Value];
  1108.   if (ButtonImage != NULL)
  1109.     Result = ButtonImage->BitmapID;
  1110.   else
  1111.     Result = -1;
  1112.  
  1113.   return Result;
  1114. } // end of TAppExpert::GetSpeedButtonID()
  1115.  
  1116. //========================================== TAppExpert =========
  1117. void __fastcall TAppExpert::SpeedbarPaint(TObject *Sender)
  1118. {
  1119.   int          i;
  1120.   TButtonImage *ButtonImage;
  1121.   TRect        R;
  1122.  
  1123.   Offscreen->Canvas->Pen->Color   = (TColor)clWindowFrame;
  1124.   Offscreen->Canvas->Brush->Style = bsClear;
  1125.   Offscreen->Canvas->Brush->Color = Speedbar->Color;
  1126.  
  1127.   Offscreen->Canvas->Rectangle(1, 1, Speedbar->Width - 1,
  1128.                                Speedbar->Height - 1);
  1129.   Offscreen->Canvas->Pen->Color = (TColor)clBtnShadow;
  1130.   TPoint p[3];
  1131.   p[0].x = 0; p[0].y = Speedbar->Height-1;
  1132.   p[1].x = 0; p[1].y = 0;
  1133.   p[2].x = Speedbar->Width-1; p[2].y = 0;
  1134.   Offscreen->Canvas->Polyline(p, 3);
  1135.   Offscreen->Canvas->Pen->Color = (TColor)clBtnHighlight;
  1136.   p[0].x = Speedbar->Width-1; p[0].y = 0;
  1137.   p[1].x = Speedbar->Width-1; p[1].y = Speedbar->Height;
  1138.   Offscreen->Canvas->Polyline(p, 2);
  1139.  
  1140.   // Draw the buttons in the list }
  1141.   int x = 10;
  1142.   for (i=0; i < SpeedList->Count; i++)
  1143.   {
  1144.     ButtonImage = (TButtonImage*)SpeedList->Items[i];
  1145.     if (ButtonImage == NULL)
  1146.     {
  1147.       Offscreen->Canvas->Brush->Style = bsSolid;
  1148.       Offscreen->Canvas->Brush->Color = (TColor)clBtnShadow;
  1149.       R = Bounds(x + 2, 5, DefaultButtonSpace - 3,
  1150.                  DefaultButtonSize->y - 2);
  1151.       Offscreen->Canvas->FillRect((TRect&)R);
  1152.       x += DefaultButtonSpace;
  1153.     }
  1154.     else
  1155.     {
  1156.       Offscreen->Canvas->Brush->Style = bsSolid;
  1157.       ButtonImage->Draw(Offscreen->Canvas, x, 4);
  1158.       x += DefaultButtonSize->x-1;
  1159.     }
  1160.  
  1161.     if (x + (DefaultButtonSize->x * 2) > Speedbar->Width)
  1162.       break;
  1163.  
  1164.     // draw the insertion point }
  1165.     R = SpeedButtonRect(FSpeedIndex);
  1166.     OffsetRect((RECT*)&R, -5, 0);
  1167.     R.Top = R.Bottom + 2;
  1168.     R.Bottom = R.Top + SpeedPointer->Height;
  1169.     R.Right = R.Left + SpeedPointer->Width;
  1170.     Offscreen->Canvas->Brush->Color = Speedbar->Color;
  1171.     Offscreen->Canvas->BrushCopy((TRect&)R, SpeedPointer,
  1172.                                  (TRect&)Rect(0, 0, SpeedPointer->Width,
  1173.                                              SpeedPointer->Height),
  1174.                                  clWhite);
  1175.   }
  1176.   Speedbar->Canvas->Draw(0, 0, Offscreen);
  1177. } // end of TAppExpert::SpeedbarPaint()
  1178.  
  1179. //========================================= TAppExpert ==========
  1180. // The list of menus was clicked
  1181. void __fastcall TAppExpert::MenuListClick(TObject *Sender)
  1182. {
  1183.   long ID;
  1184.   int  i;
  1185.   int  ButtonIndex;
  1186.   bool MenuOn;
  1187.  
  1188.   if (MenuList->ItemIndex > -1)
  1189.   {
  1190.     ID = sMenuItemTextBase + MenuItemOffsets[ TMainItems(MenuList->ItemIndex) ];
  1191.     MenuItemList->Items->BeginUpdate();
  1192.     try
  1193.     {
  1194.       MenuItemList->Clear();
  1195.  
  1196.       switch(MenuList->ItemIndex)
  1197.       {
  1198.         case 0:
  1199.           MenuOn = cbFileMenu->Checked;
  1200.           break;
  1201.         case 1:
  1202.           MenuOn = cbEditMenu->Checked;
  1203.           break;
  1204.         case 2:
  1205.           MenuOn = cbWindowMenu->Checked;
  1206.           break;
  1207.         case 3:
  1208.           MenuOn = cbHelpMenu->Checked;
  1209.           break;
  1210.       }
  1211.  
  1212.       if (MenuOn)
  1213.       {
  1214.         // load the list box with the buttons and text }
  1215.         for (i=0; i < MenuItemCounts[TMainItems(MenuList->ItemIndex)]; i++)
  1216.         {
  1217.           ButtonIndex = i + MenuItemOffsets[TMainItems(MenuList->ItemIndex)];
  1218.           MenuItemList->Items->AddObject(LoadStr(ID+i),
  1219.                                          (TObject*)ButtonList->Items[ButtonIndex]);
  1220.         }
  1221.       }
  1222.     }
  1223.     catch(...)
  1224.     {
  1225.     }
  1226.  
  1227.     MenuItemList->Items->EndUpdate();
  1228.   }
  1229. } // end of TAppExpert::MenuListClick()
  1230.  
  1231. //========================================== TAppExpert =========
  1232. void __fastcall TAppExpert::DrawMenuItem(TWinControl *Control,
  1233.                                          int Index,
  1234.                                          const TRect &Rect,
  1235.                                          TOwnerDrawState State)
  1236. {
  1237.   TButtonImage    *ButtonImage;
  1238.   TRect           R;
  1239.   char            C[255];
  1240.  
  1241.   ExtTextOut((void*)MenuItemList->Canvas->Handle, R.Left, R.Top,
  1242.              ETO_OPAQUE, (RECT*)&Rect, NULL, 0, NULL);
  1243.   ButtonImage = (TButtonImage*)MenuItemList->Items->Objects[Index];
  1244.   ButtonImage->Draw(MenuItemList->Canvas, Rect.Left+2, Rect.Top+1);
  1245.  
  1246.   R = Rect;
  1247.   R.Left += DefaultButtonSize->x + 2 + 4;
  1248.   DrawText((void*)MenuItemList->Canvas->Handle,
  1249.            StrPCopy(C, MenuItemList->Items->Strings[Index]), -1,
  1250.            (RECT*)&R, DT_VCENTER || DT_SINGLELINE);
  1251. } // end of TAppExpert::DrawMenuItem()
  1252.  
  1253. //========================================== TAppExpert =========
  1254. // Insert the current button into the Speedbar }
  1255. void __fastcall TAppExpert::InsertClick(TObject *Sender)
  1256. {
  1257.   TButtonImage *ButtonImage;
  1258.  
  1259.   if (MenuItemList->ItemIndex > -1)
  1260.   {
  1261.     ButtonImage = (TButtonImage*)MenuItemList->Items->Objects[MenuItemList->ItemIndex];
  1262.  
  1263.     if (FSpeedIndex < SpeedList->Count)
  1264.       SpeedList->Insert(FSpeedIndex, ButtonImage);
  1265.     else
  1266.       SpeedList->Add(ButtonImage);
  1267.  
  1268.     FSpeedIndex++;
  1269.     Speedbar->Invalidate();
  1270.   }
  1271. } // end of TAppExpert::InsertClick()
  1272.  
  1273. //========================================== TAppExpert =========
  1274. void __fastcall TAppExpert::SpaceClick(TObject *Sender)
  1275. {
  1276.   if (FSpeedIndex < SpeedList->Count)
  1277.     SpeedList->Insert(FSpeedIndex, NULL);
  1278.   else
  1279.     SpeedList->Add(NULL);
  1280.  
  1281.   FSpeedIndex++;
  1282.   Speedbar->Invalidate();
  1283. } // end of TAppExpert::SpaceClick()
  1284.  
  1285. //========================================== TAppExpert =========
  1286. void __fastcall TAppExpert::RemoveClick(TObject *Sender)
  1287. {
  1288.   if (FSpeedIndex < SpeedList->Count) {
  1289.     SpeedList->Delete(FSpeedIndex);
  1290.     if (FSpeedIndex > SpeedList->Count)
  1291.       FSpeedIndex = SpeedList->Count;
  1292.  
  1293.     Speedbar->Invalidate();
  1294.   }
  1295. } // end of TAppExpert::RemoveClick()
  1296.  
  1297. //========================================== TAppExpert =========
  1298. // The mouse was clicked in the Speedbar area
  1299. void __fastcall TAppExpert::SpeedMouseDown(TObject *Sender,
  1300.                                 TMouseButton Button,
  1301.                                 TShiftState Shift,
  1302.                                 int X, int Y)
  1303. {
  1304.   int Index;
  1305.  
  1306.   Index = SpeedButtonAtPos(Point(X, Y));
  1307.   if (Index != -1)
  1308.     FSpeedIndex = Index;
  1309.   else
  1310.     FSpeedIndex = SpeedList->Count;
  1311.  
  1312.   Speedbar->Invalidate();
  1313. } // end of TAppExpert::SpeeMouseDown()
  1314.  
  1315. //========================================== TAppExpert =========
  1316. void __fastcall TAppExpert::BrowseClick(TObject *Sender)
  1317. {
  1318.   AnsiString d;
  1319.  
  1320.   d = AppPath->Text;
  1321.   TSelectDirOpts tso;
  1322.   tso << sdAllowCreate << sdPrompt << sdPerformCreate;
  1323.   if (SelectDirectory(d, tso, NULL))
  1324.     AppPath->Text = d;
  1325. } // end of TAppExpert::BrowseClick()
  1326.  
  1327. //========================================== TAppExpert =========
  1328. void __fastcall TAppExpert::SamplePaint(TObject *Sender)
  1329. {
  1330.   if (SampleBmp != NULL)
  1331.     Sample->Canvas->Draw(0, 0, SampleBmp);
  1332. } // end of TAppExpert::SamplePaint()
  1333.  
  1334. //========================================[ TAppExpert ]=========
  1335. __fastcall TAppExpert::TAppExpert(TComponent* Owner)
  1336.                       :TForm(Owner)
  1337. {
  1338. }
  1339.  
  1340.