home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / c / cnrbas.zip / CREATE.C < prev    next >
Text File  |  1992-10-11  |  20KB  |  450 lines

  1. /*********************************************************************
  2.  *                                                                   *
  3.  * MODULE NAME :  create.c               AUTHOR:  Rick Fishman       *
  4.  * DATE WRITTEN:  10-09-92                                           *
  5.  *                                                                   *
  6.  * DESCRIPTION:                                                      *
  7.  *                                                                   *
  8.  *  This module is part of CNRBASE.EXE. It performs the function of  *
  9.  *  creating the container window and starting a thread that will    *
  10.  *  populate the window with file icons.                             *
  11.  *                                                                   *
  12.  *  The primary purpose of this module is to create the container    *
  13.  *  and set it up to be able to switch views easily. This is         *
  14.  *  accomplished by creating the column definitions for the Details  *
  15.  *  view. The Details view is really the only view that requires     *
  16.  *  any substantial setup.                                           *
  17.  *                                                                   *
  18.  *  We also set the base directory here. This directory will be      *
  19.  *  traversed in the PopulateContainer thread as will all its        *
  20.  *  subdirectories. If the user entered a directory name on the      *
  21.  *  command line we don't need to do anything. If not, we get the    *
  22.  *  current drive and directory and use it as the base.              *
  23.  *                                                                   *
  24.  * CALLABLE FUNCTIONS:                                               *
  25.  *                                                                   *
  26.  *   HWND CreateDirectoryWin( PSZ szDirectory );                     *
  27.  *   HWND CreateContainer( HWND hwndClient, PSZ szDirectory );       *
  28.  *                                                                   *
  29.  * HISTORY:                                                          *
  30.  *                                                                   *
  31.  *  10-09-92 - Program coded                                         *
  32.  *                                                                   *
  33.  *  Rick Fishman                                                     *
  34.  *  Code Blazers, Inc.                                               *
  35.  *  4113 Apricot                                                     *
  36.  *  Irvine, CA. 92720                                                *
  37.  *  CIS ID: 72251,750                                                *
  38.  *                                                                   *
  39.  *********************************************************************/
  40.  
  41. #pragma strings(readonly)   // used for debug version of memory mgmt routines
  42.  
  43. /*********************************************************************/
  44. /*------- Include relevant sections of the OS/2 header files --------*/
  45. /*********************************************************************/
  46.  
  47. #define  INCL_WINERRORS
  48. #define  INCL_WINFRAMEMGR
  49. #define  INCL_WINSTDCNR
  50. #define  INCL_WINWINDOWMGR
  51.  
  52. /**********************************************************************/
  53. /*----------------------------- INCLUDES -----------------------------*/
  54. /**********************************************************************/
  55.  
  56. #include <os2.h>
  57. #include <process.h>
  58. #include <stdarg.h>
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62. #include "cnrbase.h"
  63.  
  64. /*********************************************************************/
  65. /*------------------- APPLICATION DEFINITIONS -----------------------*/
  66. /*********************************************************************/
  67.  
  68. #define FRAME_FLAGS         (FCF_TASKLIST | FCF_TITLEBAR   | FCF_SYSMENU | \
  69.                              FCF_MINMAX   | FCF_SIZEBORDER | FCF_MENU    | \
  70.                              FCF_SHELLPOSITION)
  71.  
  72. #define FILES_TO_GET        100         // Nbr of files to search for at a time
  73. #define FF_BUFFSIZE         (sizeof( FILEFINDBUF3 ) * FILES_TO_GET)
  74.  
  75. #define CONTAINER_COLUMNS   5           // Number of columns in details view
  76.  
  77. #define SPLITBAR_OFFSET     150         // Pixel offset of details splitbar
  78.  
  79. #define THREAD_STACKSIZE    65536       // Stacksize for secondary thread
  80.  
  81. /**********************************************************************/
  82. /*---------------------------- STRUCTURES ----------------------------*/
  83. /**********************************************************************/
  84.  
  85. /**********************************************************************/
  86. /*----------------------- FUNCTION PROTOTYPES ------------------------*/
  87. /**********************************************************************/
  88.  
  89. static BOOL SetContainerColumns( HWND hwndCnr );
  90. static VOID GetCurrentDirectory( PSZ pszDirectory );
  91. static VOID UseCmdLineDirectory( PSZ pszDirectoryOut, PSZ szDirectoryIn );
  92.  
  93. /**********************************************************************/
  94. /*------------------------ GLOBAL VARIABLES --------------------------*/
  95. /**********************************************************************/
  96.  
  97. /**********************************************************************/
  98. /*----------------------- CreateDirectoryWin -------------------------*/
  99. /*                                                                    */
  100. /*  CREATE A DIRECTORY WINDOW MADE UP OF FRAME/CLIENT/CONTAINER.      */
  101. /*                                                                    */
  102. /*  INPUT: directory to represent in the window                       */
  103. /*                                                                    */
  104. /*  1.                                                                */
  105. /*                                                                    */
  106. /*  OUTPUT: window handle of created frame or NULLHANDLE if error     */
  107. /*                                                                    */
  108. /*--------------------------------------------------------------------*/
  109. /**********************************************************************/
  110. HWND CreateDirectoryWin( PSZ szDirectory )
  111. {
  112.     FRAMECDATA  fcdata;
  113.     HWND        hwndFrame, hwndClient = NULLHANDLE;
  114.  
  115.     (void) memset( &fcdata, 0, sizeof( FRAMECDATA ) );
  116.  
  117.     fcdata.cb               = sizeof( FRAMECDATA );
  118.     fcdata.flCreateFlags    = FRAME_FLAGS;
  119.     fcdata.idResources      = ID_RESOURCES;
  120.  
  121.     // Create the frame window. If we were creating multiple instances of
  122.     // this window, iWinCount would become useful.
  123.  
  124.     hwndFrame = WinCreateWindow( HWND_DESKTOP, WC_FRAME, NULL, 0, 0, 0, 0, 0,
  125.                                  NULLHANDLE, HWND_TOP,
  126.                                  ID_FIRST_DIRWINDOW + iWinCount, &fcdata,
  127.                                  NULL );
  128.  
  129.     // Create the client window which will create the container in its
  130.     // WM_CREATE processing. If that fails, hwndClient will be NULLHANDLE.
  131.     // We pass the directory name in the CTLDATA parameter which will be
  132.     // received by the client in mp1 on WM_CREATE.
  133.  
  134.     if( hwndFrame )
  135.         hwndClient = WinCreateWindow( hwndFrame, DIRECTORY_WINCLASS, NULL, 0,
  136.                                       0, 0, 0, 0, NULLHANDLE, HWND_TOP,
  137.                                       FID_CLIENT, szDirectory, NULL );
  138.  
  139.     if( hwndClient )
  140.     {
  141.         // Show the frame window (it was created invisible)
  142.  
  143.         if( !WinShowWindow( hwndFrame, TRUE ) )
  144.         {
  145.             hwndFrame = NULLHANDLE;
  146.  
  147.             Msg( "hwndFrame WinShowWindow RC(%X)", HWNDERR( hwndClient ) );
  148.         }
  149.     }
  150.     else
  151.         hwndFrame = NULLHANDLE;
  152.  
  153.     return hwndFrame;
  154. }
  155.  
  156. /**********************************************************************/
  157. /*------------------------- CreateContainer --------------------------*/
  158. /*                                                                    */
  159. /*  CREATE THE CONTAINER AND CUSTOMIZE IT.                            */
  160. /*                                                                    */
  161. /*  INPUT: client window handle,                                      */
  162. /*         directory to display in the container                      */
  163. /*                                                                    */
  164. /*  1.                                                                */
  165. /*                                                                    */
  166. /*  OUTPUT: Container window handle                                   */
  167. /*                                                                    */
  168. /*--------------------------------------------------------------------*/
  169. /**********************************************************************/
  170. HWND CreateContainer( HWND hwndClient, PSZ szDirectory )
  171. {
  172.     PINSTANCE pi = INSTDATA( hwndClient );
  173.     HWND      hwndCnr = NULLHANDLE;
  174.  
  175.     if( !pi )
  176.     {
  177.         Msg( "CreateContainer cant get Inst data. RC(%X)", HWNDERR(hwndClient));
  178.  
  179.         return NULLHANDLE;
  180.     }
  181.  
  182.     // Create the container control. Indicate that we want to use
  183.     // MINIRECORDCORE structures rather than RECORDCORE structures. This
  184.     // saves memory.
  185.  
  186.     hwndCnr = WinCreateWindow( hwndClient, WC_CONTAINER, NULL,
  187.                                CCS_MINIRECORDCORE | WS_VISIBLE, 0, 0, 0, 0,
  188.                                hwndClient, HWND_TOP, CNR_DIRECTORY, NULL, NULL);
  189.  
  190.     if( hwndCnr )
  191.     {
  192.         if( SetContainerColumns( hwndCnr ) )
  193.         {
  194.             PTHREADPARMS ptp = malloc( sizeof( THREADPARMS ) );
  195.  
  196.             if( ptp )
  197.             {
  198.                 TID tid;
  199.  
  200.                 (void) memset( ptp, 0, sizeof( THREADPARMS ) );
  201.  
  202.                 // If no directory was passed to us, assume that the current
  203.                 // directory is to be displayed.
  204.  
  205.                 if( !szDirectory )
  206.                     GetCurrentDirectory( pi->szDirectory );
  207.                 else
  208.                     UseCmdLineDirectory( pi->szDirectory, szDirectory );
  209.  
  210.                 ptp->hwndClient = hwndClient;
  211.  
  212.                 // Start the thread that will populate the container with
  213.                 // file icons. This is a separate thread because it could take
  214.                 // a while if there are many subdirectories.
  215.  
  216.                 tid = _beginthread( PopulateContainer, NULL, THREAD_STACKSIZE,
  217.                                     (PVOID) ptp );
  218.  
  219.                 if( (INT) tid == -1 )
  220.                     Msg( "Cant start PopulateContainer thread!" );
  221.             }
  222.             else
  223.             {
  224.                 hwndCnr = NULLHANDLE;
  225.  
  226.                 Msg( "Out of Memory in CreateContainer!" );
  227.             }
  228.         }
  229.         else
  230.             hwndCnr = NULLHANDLE;
  231.     }
  232.     else
  233.         Msg( "Couldnt create container. RC(%X)", HWNDERR( hwndClient ) );
  234.  
  235.     return hwndCnr;
  236. }
  237.  
  238. /**********************************************************************/
  239. /*----------------------- SetContainerColumns ------------------------*/
  240. /*                                                                    */
  241. /*  SET THE COLUMNS OF THE CONTAINER FOR DETAIL VIEW                  */
  242. /*                                                                    */
  243. /*  INPUT: container window handle                                    */
  244. /*                                                                    */
  245. /*  1.                                                                */
  246. /*                                                                    */
  247. /*  OUTPUT: TRUE or FALSE if successful or not                        */
  248. /*                                                                    */
  249. /*--------------------------------------------------------------------*/
  250. /**********************************************************************/
  251. static BOOL SetContainerColumns( HWND hwndCnr )
  252. {
  253.     BOOL        fSuccess = TRUE;
  254.     PFIELDINFO  pfi, pfiLastLeftCol;
  255.  
  256.     // Allocate storage for container column data
  257.  
  258.     pfi = WinSendMsg( hwndCnr, CM_ALLOCDETAILFIELDINFO,
  259.                       MPFROMLONG( CONTAINER_COLUMNS ), NULL );
  260.  
  261.     if( pfi )
  262.     {
  263.         PFIELDINFO      pfiFirst;
  264.         FIELDINFOINSERT fii;
  265.  
  266.         // Store original value of pfi so we won't lose it when it changes.
  267.         // This will be needed on the CM_INSERTDETAILFIELDINFO message.
  268.  
  269.         pfiFirst = pfi;
  270.  
  271.         // Fill in column information for the icon column
  272.  
  273.         pfi->flData     = CFA_BITMAPORICON | CFA_HORZSEPARATOR | CFA_CENTER |
  274.                           CFA_SEPARATOR;
  275.         pfi->flTitle    = CFA_CENTER | CFA_FITITLEREADONLY;
  276.         pfi->pTitleData = "Icon";
  277.         pfi->offStruct  = FIELDOFFSET( CNRITEM, hptrIcon );
  278.  
  279.         // Fill in column information for the file name. Note that we are
  280.         // using the pszFileName variable rather than szFileName. We do this
  281.         // because the container needs a pointer to the file name. If we used
  282.         // szFileName (a character array, not a pointer), the container would
  283.         // take the first 4 bytes of szFileName and think it was a pointer,
  284.         // which of course it is not. Later in the FillInRecord function we set
  285.         // pszFileName to point to szFileName.
  286.  
  287.         pfi             = pfi->pNextFieldInfo;
  288.         pfi->flData     = CFA_STRING | CFA_LEFT | CFA_HORZSEPARATOR;
  289.         pfi->flTitle    = CFA_CENTER | CFA_FITITLEREADONLY;
  290.         pfi->pTitleData = "File Name";
  291.         pfi->offStruct  = FIELDOFFSET( CNRITEM, pszFileName );
  292.  
  293.         // Store the current pfi value as that will be used to indicate the
  294.         // last column in the lefthand container window (we have a splitbar)
  295.  
  296.         pfiLastLeftCol = pfi;
  297.  
  298.         // Fill in column information for the file size
  299.  
  300.         pfi             = pfi->pNextFieldInfo;
  301.         pfi->flData     = CFA_ULONG | CFA_RIGHT | CFA_HORZSEPARATOR |
  302.                           CFA_SEPARATOR;
  303.         pfi->flTitle    = CFA_CENTER | CFA_FITITLEREADONLY;
  304.         pfi->pTitleData = "File Size";
  305.         pfi->offStruct  = FIELDOFFSET( CNRITEM, cbFile );
  306.  
  307.         // Fill in column information for file date
  308.  
  309.         pfi             = pfi->pNextFieldInfo;
  310.         pfi->flData     = CFA_DATE | CFA_RIGHT | CFA_HORZSEPARATOR |
  311.                           CFA_SEPARATOR;
  312.         pfi->flTitle    = CFA_CENTER | CFA_FITITLEREADONLY;
  313.         pfi->pTitleData =  "Date";
  314.         pfi->offStruct  = FIELDOFFSET( CNRITEM, date );
  315.  
  316.         // Fill in column information for the file time
  317.  
  318.         pfi             = pfi->pNextFieldInfo;
  319.         pfi->flData     = CFA_TIME | CFA_RIGHT | CFA_HORZSEPARATOR;
  320.         pfi->flTitle    = CFA_CENTER | CFA_FITITLEREADONLY;
  321.         pfi->pTitleData = "Time";
  322.         pfi->offStruct  = FIELDOFFSET( CNRITEM, time );
  323.  
  324.         // Use the CM_INSERTDETAILFIELDINFO message to tell the container
  325.         // all the column information it needs to function properly. Place
  326.         // this column info first in the column list and update the display
  327.         // after they are inserted (fInvalidateFieldInfo = TRUE)
  328.  
  329.         (void) memset( &fii, 0, sizeof( FIELDINFOINSERT ) );
  330.  
  331.         fii.cb                   = sizeof( FIELDINFOINSERT );
  332.         fii.pFieldInfoOrder      = (PFIELDINFO) CMA_FIRST;
  333.         fii.cFieldInfoInsert     = (SHORT) CONTAINER_COLUMNS;
  334.         fii.fInvalidateFieldInfo = TRUE;
  335.  
  336.         if( !WinSendMsg( hwndCnr, CM_INSERTDETAILFIELDINFO, MPFROMP( pfiFirst ),
  337.                          MPFROMP( &fii ) ) )
  338.         {
  339.             fSuccess = FALSE;
  340.  
  341.             Msg( "CM_INSERTDETAILFIELDINFO RC(%X)", HWNDERR( hwndCnr ) );
  342.         }
  343.     }
  344.     else
  345.     {
  346.         fSuccess = FALSE;
  347.  
  348.         Msg( "CM_ALLOCDETAILFIELDINFO failed. RC(%X)", HWNDERR( hwndCnr ) );
  349.     }
  350.  
  351.     if( fSuccess )
  352.     {
  353.         CNRINFO cnri;
  354.  
  355.         // Tell the container about the splitbar and where it goes
  356.  
  357.         cnri.cb             = sizeof( CNRINFO );
  358.         cnri.pFieldInfoLast = pfiLastLeftCol;
  359.         cnri.xVertSplitbar  = SPLITBAR_OFFSET;
  360.  
  361.         if( !WinSendMsg( hwndCnr, CM_SETCNRINFO, MPFROMP( &cnri ),
  362.                         MPFROMLONG( CMA_PFIELDINFOLAST | CMA_XVERTSPLITBAR ) ) )
  363.         {
  364.             fSuccess = FALSE;
  365.  
  366.             Msg( "SetContainerColumns CM_SETCNRINFO RC(%X)", HWNDERR(hwndCnr) );
  367.         }
  368.     }
  369.  
  370.     return fSuccess;
  371. }
  372.  
  373. /**********************************************************************/
  374. /*----------------------- GetCurrentDirectory ------------------------*/
  375. /*                                                                    */
  376. /*  GET THE CURRENT DIRECTORY AND STORE IT.                           */
  377. /*                                                                    */
  378. /*  INPUT: pointer to buffer in which to place path info              */
  379. /*                                                                    */
  380. /*  1.                                                                */
  381. /*                                                                    */
  382. /*  OUTPUT: nothing                                                   */
  383. /*                                                                    */
  384. /*--------------------------------------------------------------------*/
  385. /**********************************************************************/
  386. static VOID GetCurrentDirectory( PSZ pszDirectory )
  387. {
  388.     ULONG  cbDirPath = CCHMAXPATH;
  389.     APIRET rc;
  390.     ULONG  ulCurrDrive, ulDrvMap;
  391.  
  392.     // Set up the "d:\" string to which we will add the current directory.
  393.     // If we can get the current drive number, use it. Otherwise default to
  394.     // C:
  395.  
  396.     rc = DosQueryCurrentDisk( &ulCurrDrive, &ulDrvMap );
  397.  
  398.     if( !rc )
  399.     {
  400.         pszDirectory[ 0 ] = ulCurrDrive + ('A' - 1);
  401.  
  402.         (void) strcpy( pszDirectory + 1, ":\\" );
  403.     }
  404.     else
  405.         (void) strcpy( pszDirectory, "C:\\" );
  406.  
  407.     rc = DosQueryCurrentDir( 0, pszDirectory + 3, &cbDirPath );
  408.  
  409.     // If good retcode, DosQueryCurrentDir just returns the current
  410.     // directory without a trailing backslash. Of course there are always
  411.     // complications. The complication here is that if the current directory is
  412.     // the root, the string *will* end with a backslash. So if the trailing
  413.     // character is a backslash, remove it so we have a pure directory name.
  414.  
  415.     if( pszDirectory[ strlen( pszDirectory ) - 1 ] == '\\' )
  416.         pszDirectory[ strlen( pszDirectory ) - 1 ] = 0;
  417.  
  418.     if( rc )
  419.         Msg( "DosQueryCurrentDir RC(%X). Using Root Directory.", rc );
  420. }
  421.  
  422. /**********************************************************************/
  423. /*----------------------- UseCmdLineDirectory ------------------------*/
  424. /*                                                                    */
  425. /*  TAKE THE DIRECTORY FROM THE COMMANDLINE AND VALIDATE IT.          */
  426. /*                                                                    */
  427. /*  INPUT: pointer to buffer in which to place correct path,          */
  428. /*         directory input at the commandline                         */
  429. /*                                                                    */
  430. /*  1.                                                                */
  431. /*                                                                    */
  432. /*  OUTPUT: nothing                                                   */
  433. /*                                                                    */
  434. /*--------------------------------------------------------------------*/
  435. /**********************************************************************/
  436. static VOID UseCmdLineDirectory( PSZ pszDirectoryOut, PSZ szDirectoryIn )
  437. {
  438.     (void) strcpy( pszDirectoryOut, szDirectoryIn );
  439.  
  440.     // If the user ended their directory name with a backslash, take it off
  441.     // because this program needs to have just the base directory name here.
  442.  
  443.     if( pszDirectoryOut[ strlen( pszDirectoryOut ) - 1 ] == '\\' )
  444.         pszDirectoryOut[ strlen( pszDirectoryOut ) - 1 ] = 0;
  445. }
  446.  
  447. /*************************************************************************
  448.  *                     E N D     O F     S O U R C E                     *
  449.  *************************************************************************/
  450.