home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / INITREE.PAK / INI.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  18.0 KB  |  519 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993-1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   ini.c
  9. //
  10. //  PURPOSE:  Fills a TreeView control with a listing of the INI
  11. //            files. The root items are the INI files, then children
  12. //            off the roots are the sections, and the children off
  13. //            the sections are the entries:
  14. //
  15. //            ROOT WIN.INI
  16. //                   |
  17. //                   --[Fonts]
  18. //                     |
  19. //                     --AlbertusBold
  20. //            ROOT SYSTEM.INI
  21. //
  22. //
  23. //  FUNCTIONS:
  24. //
  25. //    INI_FillTreeView - Entry point function to fill TreeView Control
  26. //    FillIniKeys      - Build a list of sections for each INI file
  27. //    FillKeyItems     - Build a list of entries for each section
  28. //
  29. //  COMMENTS:
  30. //
  31. //    The INI_FillTreView function is called. It adds the INI file
  32. //    names to the treeview. It calls FillIniKeys for each INI file.
  33. //    The FillIniKeys function adds the sections for the passed in
  34. //    INI filename. The FillIniKeys calls FillKeyItems for each section.
  35. //    The FillKeyItems function adds the entries for the passed in
  36. //    section.
  37.  
  38. #include <windows.h>            // required for all Windows applications
  39. #include <windowsx.h>
  40. #include <commctrl.h>           // TreeView declarations live here
  41. #include "globals.h"            // prototypes specific to this application
  42.  
  43. #define MAX_SECTION_SIZE      32764
  44. #define MAX_SECTION_KEY_SIZE  256
  45. #define MAX_ENTRY_SIZE        256
  46. #define MAX_STRING_SIZE       256
  47. #define MAX_INIFILE_SIZE      65536
  48.  
  49. //
  50. //  FUNCTION PROTOTYPES
  51. //
  52.  
  53. void INI_FillTreeView(HWND        hwndTreeView,
  54.                       int         iINIFileImage,
  55.                       int         iSectionKeyImage,
  56.                       int         iSelectedEntryImage,
  57.                       int         iNonSelectedEntryImage);
  58.  
  59. void FillIniKeys(HWND hwndTreeView,
  60.                  HTREEITEM hParent,
  61.                  LPSTR szIniFileName,
  62.                  int         iSectionKeyImage,
  63.                  int         iSelectedEntryImage,
  64.                  int         iNonSelectedEntryImage);
  65.  
  66. void FillKeyItems(HWND        hwndTreeView,
  67.                   HTREEITEM   hParent,
  68.                   LPSTR       szIniFileName,
  69.                   LPSTR       szSection,
  70.                   int         iSelectedEntryImage,
  71.                   int         iNonSelectedEntryImage);
  72.  
  73. //
  74. //  FUNCTION: INI_FillTreeView(HWND        hwndTreeView,
  75. //                             int         iINIFileImage,
  76. //                             int         iSectionKeyImage,
  77. //                             int         iSelectedEntryImage,
  78. //                             int         iNonSelectedEntryImage)
  79. //
  80. //
  81. //  PURPOSE: Fills the TreeView control with the INI files,
  82. //           call helper functions to fill in more detailed
  83. //           information.
  84. //
  85. //  PARAMETERS:
  86. //    hwndTreeView           - Handle fo TreeView Control
  87. //    iINIFileImage          - ImageList ID for "INI" item.
  88. //    iSectionKeyImage       - ImageList ID for "Folder" item.
  89. //    iSelectedEntryImage    - ImageList ID for selected entry.
  90. //    iNonSelectedEntryImage - ImageList ID for non-selected entry.
  91. //
  92. //  RETURN VALUE:
  93. //    none
  94. //
  95. //  COMMENTS:
  96. //
  97. //    This function walks the Windows directory for INI files.
  98. //    For each file found, a root entry is added to the TreeView,
  99. //    and then the FillIniKeys helper function is called to
  100. //    fill in the sections for the INI file.
  101. //
  102.  
  103. void INI_FillTreeView(HWND        hwndTreeView,
  104.                       int         iINIFileImage,
  105.                       int         iSectionKeyImage,
  106.                       int         iSelectedEntryImage,
  107.                       int         iNonSelectedEntryImage)
  108. {
  109.     char             szWindowsDirectory[MAX_PATH]; // Windows Directory.
  110.     WIN32_FIND_DATA  FindFile;                     // For file searches.
  111.     HANDLE           hFindFile;                    // For file searches.
  112.     TV_ITEM          tvi;                          // TreeView Item.
  113.     TV_INSERTSTRUCT  tvins;                        // TreeView Insert Struct.
  114.     HTREEITEM        hPrev = TVI_FIRST;            // Previous Item Added.
  115.  
  116.     // Hourglass on!
  117.  
  118.     SetCapture(GetParent(hwndTreeView));
  119.     SetCursor(LoadCursor(NULL, IDC_WAIT));
  120.  
  121.     // Clear TreeView Control
  122.  
  123.     TreeView_DeleteAllItems(hwndTreeView);
  124.  
  125.     // Find Windows Directory
  126.  
  127.     GetWindowsDirectory(szWindowsDirectory, sizeof(szWindowsDirectory));
  128.  
  129.     // Make a *.INI mask
  130.  
  131.     lstrcat(szWindowsDirectory, "\\*.ini");
  132.  
  133.     // Find the first INI file
  134.  
  135.     hFindFile = FindFirstFile(szWindowsDirectory, &FindFile);
  136.  
  137.     // Loop through each INI file and add to the tree
  138.  
  139.     if (INVALID_HANDLE_VALUE != hFindFile)
  140.     {
  141.         do
  142.         {
  143.             // Add this file to the TreeView
  144.             // Set up the structure for a text label, and use
  145.             // the ImageList ID iINIFileImage.
  146.  
  147.             tvi.mask            = TVIF_TEXT | TVIF_IMAGE;
  148.             tvi.iImage          =
  149.             tvi.iSelectedImage  = iINIFileImage;
  150.  
  151.             tvi.pszText         = FindFile.cFileName;
  152.             tvi.cchTextMax      = MAX_PATH;
  153.  
  154.             // Populate the TreeVeiw Insert Struct
  155.             // The item is the one filled above.
  156.             // Insert it after the last item inserted at this level.
  157.             // And indicate this is a root entry.
  158.  
  159.             tvins.item         = tvi;
  160.             tvins.hInsertAfter = hPrev;
  161.             tvins.hParent      = TVI_ROOT;
  162.  
  163.             // Add the item to the tree
  164.  
  165.             hPrev = TreeView_InsertItem(hwndTreeView, &tvins);
  166.  
  167.             // Add the keys for this ini to the TreeView
  168.  
  169.             FillIniKeys(hwndTreeView,
  170.                         hPrev,
  171.                         FindFile.cFileName,
  172.                         iSectionKeyImage,
  173.                         iSelectedEntryImage,
  174.                         iNonSelectedEntryImage);
  175.         }
  176.         while (FindNextFile(hFindFile, &FindFile));
  177.  
  178.     } /* end if */
  179.  
  180.     // Sort TreeView Control
  181.     //
  182.     // Sort at the root, and recurse down the children levels.
  183.  
  184. //    TreeView_SortChildren(hwndTreeView, TVI_ROOT, TRUE);
  185.  
  186.     // Hourglass off!
  187.  
  188.     ReleaseCapture();
  189.     SetCursor(LoadCursor(NULL, IDC_ARROW));
  190. }
  191.  
  192. //
  193. //  FUNCTION: bThisLineIsSection(LPSTR *pszFile, LPSTR szSectionName)
  194. //
  195. //  PURPOSE: Checks the next line of text in a file memory image
  196. //           and it if is a [section], copies the section into
  197. //           the szSectionName string and returns TRUE.
  198. //
  199. //  PARAMETERS:
  200. //    pszFile      - Points to a LPSTR, which points to the start of
  201. //                   a line of text in the file memory image.
  202. //    szSectionNmae- String to copy section name to on success.
  203. //
  204. //  RETURN VALUE:
  205. //    On success - TRUE
  206. //    On Failure - FALSE
  207. //
  208. //  COMMENTS:
  209. //
  210. //    The pszFile pointer MUST point to the start of a line of
  211. //    text in a file memory image. This function will move the
  212. //    pointer to the start of the next line in the file memory
  213. //    image.
  214. //
  215.  
  216. BOOL bThisLineIsSection(LPSTR *pszFile, LPSTR szSectionName)
  217. {
  218.     int    iFilePtrPos;       // Character position in file mem image
  219.     int    iSectionStringPtr; // Character position in szSectionName
  220.     BOOL   bRetval = FALSE;   // Return value for function
  221.  
  222.     // Initialize position counters
  223.  
  224.     iFilePtrPos = iSectionStringPtr = 0;
  225.  
  226.     // Check to see if line starts with a '[', that would make
  227.     // it a [section].
  228.  
  229.     if ('[' == (*pszFile)[iFilePtrPos])
  230.     {
  231.         // Bump char position in file by one to skip the
  232.         // open square bracket.
  233.  
  234.         iFilePtrPos++;
  235.  
  236.         // Keep copying characters into the szSectionName string
  237.         // until the closing square bracket is found.
  238.  
  239.         while ((*pszFile)[iFilePtrPos] && (']' != (*pszFile)[iFilePtrPos]))
  240.         {
  241.             szSectionName[iSectionStringPtr] = (*pszFile)[iFilePtrPos];
  242.             iSectionStringPtr++;
  243.             iFilePtrPos++;
  244.         }
  245.  
  246.         // Add the null terminator to the end of szSectionName
  247.  
  248.         szSectionName[iSectionStringPtr] = 0;
  249.  
  250.         // Indicate sucess for the return value.
  251.  
  252.         bRetval = TRUE;
  253.     }
  254.  
  255.     // Now, we must skip over the CRLF at the and of each text line
  256.     // so that the next time this function is called, the pointer
  257.     // will be at the end of the line
  258.  
  259.     while (
  260.             ((*pszFile)[iFilePtrPos])          // While not EOF
  261.             &&
  262.             ('\n' != (*pszFile)[iFilePtrPos])  // While not LF char
  263.           )
  264.         iFilePtrPos++;
  265.  
  266.     // After the above while loop, the iFilePtrPos is still sitting
  267.     // on the LF. Bump it to the next character, which will be the
  268.     // first character of the next line.
  269.  
  270.     if ((*pszFile)[iFilePtrPos]) iFilePtrPos++;
  271.  
  272.     // Change the value of the pointer to the file memory image
  273.     // to point to the next line.
  274.  
  275.     *pszFile += iFilePtrPos;
  276.  
  277.     // Return the results.
  278.  
  279.     return bRetval;
  280. }
  281.  
  282. //
  283. //  FUNCTION: FillIniKeys(HWND        hwndTreeView,
  284. //                        HTREEITEM   hParent,
  285. //                        LPSTR       szIniFileName,
  286. //                        int         iSectionKeyImage,
  287. //                        int         iSelectedEntryImage,
  288. //                        int         iNonSelectedEntryImage)
  289. //
  290. //  PURPOSE: Adds all the [section] names of the specified
  291. //           INI file to the TreeView control.
  292. //
  293. //  PARAMETERS:
  294. //    hwndTreeView           - Handle fo TreeView Control.
  295. //    hParent                - Handle to root TreeView Item which
  296. //                             inidcates the name of the INI file.
  297. //    szIniFileName          - Filename of the INI file.
  298. //    iSectionKeyImage       - ImageList ID for "Folder" item.
  299. //    iSelectedEntryImage    - ImageList ID for selected entry.
  300. //    iNonSelectedEntryImage - ImageList ID for non-selected entry.
  301. //
  302. //  RETURN VALUE:
  303. //    none
  304. //
  305. //  COMMENTS:
  306. //
  307. //    This function makes a memory image of the file by loading it
  308. //    into memory. Then, a pointer to this image is repeatedly
  309. //    passed to the bThisLineIsSection function, which then
  310. //    determines if the line is a [section]. If so, the section
  311. //    is added to the TreeView control, and the FillKeyItems
  312. //    function is called to fill in the individual entries.
  313. //
  314.  
  315. void FillIniKeys(HWND        hwndTreeView,
  316.                  HTREEITEM   hParent,
  317.                  LPSTR       szIniFileName,
  318.                  int         iSectionKeyImage,
  319.                  int         iSelectedEntryImage,
  320.                  int         iNonSelectedEntryImage)
  321. {
  322.     static char      szIniFile[MAX_INIFILE_SIZE];  // Memory image of file
  323.  
  324.     char             szRawSection[MAX_SECTION_KEY_SIZE]; // Holds "Section".
  325.     char             szSection[MAX_SECTION_KEY_SIZE+2];  // Holds "[Section]".
  326.     int              iIniFileSize;                       // Size of INI file.
  327.     HFILE            hFile;                              // File handle.
  328.     OFSTRUCT         of;                                 // For OpenFile.
  329.     LPSTR            ptr;                                // Pointer to file
  330.                                                          // image.
  331.     TV_ITEM          tvi;                                // TreeView Item.
  332.     TV_INSERTSTRUCT  tvins;                              // TreeView Insert
  333.                                                          // struct.
  334.     HTREEITEM        hPrev = TVI_FIRST;                  // Previous Item
  335.                                                          // added.
  336.  
  337.     // Load the INI file into the memory image, and count the
  338.     // bytes.
  339.  
  340.     hFile        = OpenFile(szIniFileName, &of, OF_READ);
  341.     iIniFileSize = _lread(hFile, szIniFile, MAX_INIFILE_SIZE-1);
  342.     _lclose(hFile);
  343.  
  344.     // Terminate the EOF with a zero, this lets the bThisLineIsSection
  345.     // function and the loop below know when to stop.
  346.  
  347.     szIniFile[iIniFileSize] = 0;
  348.  
  349.     // Set the pointer to the start of the memory image.
  350.  
  351.     ptr = szIniFile;
  352.  
  353.     // Loop through each line in the memory image
  354.  
  355.     while (*ptr)
  356.     {
  357.         // Check to see if this line is a [section]
  358.  
  359.         if (bThisLineIsSection(&ptr, szRawSection))
  360.         {
  361.             // Format the string to look like a [Section]
  362.  
  363.             wsprintf (szSection, "[%s]", szRawSection );
  364.  
  365.             // Add the string to the TreeView
  366.             // Set up the structure for a text label, and use
  367.             // the ImageList ID iSectionKeyImage for both images
  368.             // and selected images. If we did not use the
  369.             // TVIF_SELECTEDIMAGE mask, then the selected
  370.             // image of the parent of this item would be used
  371.             // for this image, which would look goofy.
  372.  
  373.             tvi.mask            = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  374.             tvi.iImage          =
  375.             tvi.iSelectedImage  = iSectionKeyImage;
  376.  
  377.             tvi.pszText    = szSection;
  378.             tvi.cchTextMax = sizeof(szSection);
  379.  
  380.             // Populate the TreeVeiw Insert Struct
  381.             // The item is the one filled above.
  382.             // Insert it after the last item inserted at this level.
  383.             // And indicate this is a child entry from the hParent
  384.             // item passed into this function.
  385.  
  386.             tvins.item         = tvi;
  387.             tvins.hInsertAfter = hPrev;
  388.             tvins.hParent      = hParent;
  389.  
  390.             // Add the item to the tree
  391.  
  392.             hPrev = TreeView_InsertItem(hwndTreeView, &tvins);
  393.  
  394.             // Add the entries for this section to the TreeView.
  395.  
  396.             FillKeyItems(hwndTreeView,
  397.                          hPrev,
  398.                          szIniFileName,
  399.                          szRawSection,
  400.                          iSelectedEntryImage,
  401.                          iNonSelectedEntryImage);
  402.  
  403.         } /* end if */
  404.  
  405.     } /* end while */
  406.  
  407. }
  408.  
  409.  
  410. //
  411. //  FUNCTION: FillKeyItems(HWND        hwndTreeView,
  412. //                         HTREEITEM   hParent,
  413. //                         LPSTR       szIniFileName,
  414. //                         LPSTR       szSection,
  415. //                         int         iSelectedEntryImage,
  416. //                         int         iNonSelectedEntryImage)
  417. //
  418. //  PURPOSE: Adds all the entries under the specified [section]
  419. //           of the specified INI file to the TreeView control.
  420. //
  421. //  PARAMETERS:
  422. //    hwndTreeView           - Handle fo TreeView Control.
  423. //    hParent                - Handle to root TreeView Item which
  424. //                             inidcates the name of the INI file.
  425. //    szIniFileName          - Filename of the INI file.
  426. //    szSection              - Name of the [section].
  427. //    iSelectedEntryImage    - ImageList ID for selected entry.
  428. //    iNonSelectedEntryImage - ImageList ID for non-selected entry.
  429. //
  430. //  RETURN VALUE:
  431. //    none
  432. //
  433. //  COMMENTS:
  434. //
  435. //    This function uses the GetPrivateProfileSection API to
  436. //    get a list of strings for the specified [section]. Each
  437. //    string is then happily added to the TreeView.
  438. //
  439.  
  440. void FillKeyItems(HWND        hwndTreeView,
  441.                   HTREEITEM   hParent,
  442.                   LPSTR       szIniFileName,
  443.                   LPSTR       szSection,
  444.                   int         iSelectedEntryImage,
  445.                   int         iNonSelectedEntryImage)
  446. {
  447.     static char  szSectionData[MAX_SECTION_SIZE];          // Place to
  448.                                                            // put all the
  449.                                                            // strings.
  450.  
  451.     LPSTR szEntryPtr;                               // Pointer to
  452.                                                     // the current
  453.                                                     // entry.
  454.  
  455.     TV_ITEM         tvi;                            // TreeView Item.
  456.     TV_INSERTSTRUCT tvins;                          // TreeView Insert struct.
  457.     HTREEITEM       hPrev = TVI_FIRST;              // Previous Item added.
  458.  
  459.     // Fill the szSectionData buffer with the entries. The API will
  460.     // fill the buffer like this: "one=1\0two=2" for the following
  461.     // entries:
  462.     //
  463.     // [Section]
  464.     // one=1
  465.     // two=2
  466.     //
  467.  
  468.     GetPrivateProfileSection(szSection,
  469.                              szSectionData,
  470.                              MAX_SECTION_SIZE,
  471.                              szIniFileName);
  472.  
  473.     // Set the entry to point to the first item in the above
  474.     // string.
  475.  
  476.     szEntryPtr = szSectionData;
  477.  
  478.     // Loop through each entry, and add them to the TreeView.
  479.  
  480.     while (*szEntryPtr)
  481.     {
  482.         // Add the string to the TreeView
  483.         // Set up the structure for a text label, and use
  484.         // the ImageList ID iNonSelectedEntryImage for
  485.         // non-selected images, and iSelectedEntryImage for
  486.         // selected images. If we did not use the
  487.         // TVIF_SELECTEDIMAGE mask, then the selected
  488.         // image of the parent of this item would be used
  489.         // for this image, which would look goofy.
  490.  
  491.         tvi.mask            = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  492.         tvi.iImage          = iNonSelectedEntryImage;
  493.         tvi.iSelectedImage  = iSelectedEntryImage;
  494.  
  495.         tvi.pszText    = szEntryPtr;
  496.         tvi.cchTextMax = lstrlen(szEntryPtr);
  497.  
  498.         // Populate the TreeVeiw Insert Struct
  499.         // The item is the one filled above.
  500.         // Insert it after the last item inserted at this level.
  501.         // And indicate this is a child entry from the hParent
  502.         // item passed into this function.
  503.  
  504.         tvins.item         = tvi;
  505.         tvins.hInsertAfter = hPrev;
  506.         tvins.hParent      = hParent;
  507.  
  508.         // Add the item to the tree
  509.  
  510.         hPrev = TreeView_InsertItem(hwndTreeView, &tvins);
  511.  
  512.         // Bump the pointer to the next string.
  513.  
  514.         szEntryPtr += lstrlen(szEntryPtr) + 1;
  515.  
  516.     } /* end while */
  517.  
  518. }
  519.