home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cnradv.zip / EDIT.C < prev    next >
C/C++ Source or Header  |  1993-07-09  |  17KB  |  376 lines

  1. /*********************************************************************
  2.  *                                                                   *
  3.  * MODULE NAME :  edit.c                 AUTHOR:  Rick Fishman       *
  4.  * DATE WRITTEN:  11-30-92                                           *
  5.  *                                                                   *
  6.  * DESCRIPTION:                                                      *
  7.  *                                                                   *
  8.  *  This module is part of CNRADV.EXE. It contains the functions     *
  9.  *  necessary to implement container direct editing.                 *
  10.  *                                                                   *
  11.  * CALLABLE FUNCTIONS:                                               *
  12.  *                                                                   *
  13.  *  VOID EditBegin( HWND hwndClient, PCNREDITDATA pced );            *
  14.  *  VOID EditEnd( HWND hwndClient, PCNREDITDATA pced );              *
  15.  *                                                                   *
  16.  * HISTORY:                                                          *
  17.  *                                                                   *
  18.  *  11-30-92 - Source copied from CNRMENU.EXE sample.                *
  19.  *                                                                   *
  20.  *  Rick Fishman                                                     *
  21.  *  Code Blazers, Inc.                                               *
  22.  *  4113 Apricot                                                     *
  23.  *  Irvine, CA. 92720                                                *
  24.  *  CIS ID: 72251,750                                                *
  25.  *                                                                   *
  26.  *********************************************************************/
  27.  
  28. #pragma strings(readonly)   // used for debug version of memory mgmt routines
  29.  
  30. /*********************************************************************/
  31. /*------- Include relevant sections of the OS/2 header files --------*/
  32. /*********************************************************************/
  33.  
  34. #define INCL_DOSERRORS
  35. #define INCL_WINDIALOGS
  36. #define INCL_WINERRORS
  37. #define INCL_WINFRAMEMGR
  38. #define INCL_WINMENUS
  39. #define INCL_WINMLE
  40. #define INCL_WINSTDCNR
  41. #define INCL_WINSTDDLGS
  42. #define INCL_WINWINDOWMGR
  43.  
  44. /**********************************************************************/
  45. /*----------------------------- INCLUDES -----------------------------*/
  46. /**********************************************************************/
  47.  
  48. #include <os2.h>
  49. #include <stdarg.h>
  50. #include <stdio.h>
  51. #include <stdlib.h>
  52. #include <string.h>
  53. #include "cnradv.h"
  54.  
  55. /*********************************************************************/
  56. /*------------------- APPLICATION DEFINITIONS -----------------------*/
  57. /*********************************************************************/
  58.  
  59. /**********************************************************************/
  60. /*---------------------------- STRUCTURES ----------------------------*/
  61. /**********************************************************************/
  62.  
  63. /**********************************************************************/
  64. /*----------------------- FUNCTION PROTOTYPES ------------------------*/
  65. /**********************************************************************/
  66.  
  67. static ULONG GetMaxNameSize     ( CHAR chDrive );
  68. static BOOL  RenameFile         ( HWND hwndCnr, PCNRITEM pci, PSZ szNewName );
  69. static VOID RefreshAllContainers( HWND hwndCnr, PCNRITEM pciChanged );
  70.  
  71. /**********************************************************************/
  72. /*------------------------ GLOBAL VARIABLES --------------------------*/
  73. /**********************************************************************/
  74.  
  75. /**********************************************************************/
  76. /*----------------------------- EditBegin ----------------------------*/
  77. /*                                                                    */
  78. /*  PROCESS CN_BEGINEDIT NOTIFY MESSAGE.                              */
  79. /*                                                                    */
  80. /*  INPUT: client window handle,                                      */
  81. /*         pointer to the CNREDITDATA structure                       */
  82. /*                                                                    */
  83. /*  1.                                                                */
  84. /*                                                                    */
  85. /*  OUTPUT: nothing                                                   */
  86. /*                                                                    */
  87. /*--------------------------------------------------------------------*/
  88. /**********************************************************************/
  89. VOID EditBegin( HWND hwndClient, PCNREDITDATA pced )
  90. {
  91.     PFIELDINFO  pfi = pced->pFieldInfo;
  92.     PINSTANCE   pi = INSTDATA( hwndClient );
  93.     HWND        hwndMLE = WinWindowFromID(
  94.                     WinWindowFromID( hwndClient, CNR_DIRECTORY ), CID_MLE );
  95.  
  96.     if( !pi )
  97.     {
  98.         Msg( "EditBegin cant get Inst data. RC(%X)", HWNDERR( hwndClient ) );
  99.  
  100.         return;
  101.     }
  102.  
  103.     // pfi only available if details view. If we are in details view and
  104.     // the column the user is direct-editing is the file name field, set the
  105.     // text limit of the MLE to the Maximum that the filename can be.
  106.     // If MLM_SETTEXTLIMIT returns a non-zero value, it means that the text
  107.     // length in the MLE is greater than what we are trying to set it to.
  108.  
  109.     if( !pfi || pfi->offStruct == FIELDOFFSET( CNRITEM, rc.pszIcon ) )
  110.     {
  111.         // The Service Pack (November, 1992) included a change where the
  112.         // MLE was defined with the MLS_DISABLEUNDO flag. This causes problems
  113.         // with MLM_SETTEXTLIMIT. With this bit enabled, when the user starts
  114.         // typing after the text limit has been reached, the MLE beeps but
  115.         // also displays the characters. I took off this bit flag with the
  116.         // following code but the MLE doesn't re-check this style bit
  117.         // unfortunately so it is still an outstanding bug.
  118.  
  119.         WinSetWindowBits( hwndMLE, QWL_STYLE, 0, MLS_DISABLEUNDO );
  120.  
  121.         if( WinSendMsg( hwndMLE, MLM_SETTEXTLIMIT,
  122.                         MPFROMLONG( GetMaxNameSize( pi->szDirectory[ 0 ] ) ),
  123.                         NULL) )
  124.             Msg( "MLM_SETTEXTLIMIT failed. RC(%X)", HWNDERR( hwndClient ) );
  125.     }
  126. }
  127.  
  128. /**********************************************************************/
  129. /*----------------------------- EditEnd ------------------------------*/
  130. /*                                                                    */
  131. /*  PROCESS CN_ENDEDIT NOTIFY MESSAGE.                                */
  132. /*                                                                    */
  133. /*  INPUT: client window handle,                                      */
  134. /*         pointer to the CNREDITDATA structure                       */
  135. /*                                                                    */
  136. /*  1.                                                                */
  137. /*                                                                    */
  138. /*  OUTPUT: nothing                                                   */
  139. /*                                                                    */
  140. /*--------------------------------------------------------------------*/
  141. /**********************************************************************/
  142. VOID EditEnd( HWND hwndClient, PCNREDITDATA pced )
  143. {
  144.     PINSTANCE   pi = INSTDATA( hwndClient );
  145.     PCNRITEM    pci = (PCNRITEM) pced->pRecord;
  146.     PFIELDINFO  pfi = pced->pFieldInfo;
  147.     HWND        hwndCnr, hwndMLE;
  148.  
  149.     if( !pi )
  150.     {
  151.         Msg( "EditEnd cant get Inst data. RC(%X)", HWNDERR( hwndClient ) );
  152.  
  153.         return;
  154.     }
  155.  
  156.     hwndCnr = WinWindowFromID( hwndClient, CNR_DIRECTORY );
  157.  
  158.     // Get the handle to the MLE that the container uses for direct editing
  159.  
  160.     hwndMLE = WinWindowFromID( hwndCnr, CID_MLE );
  161.  
  162.     // pfi only available if details view
  163.  
  164.     if( pci && (!pfi || pfi->offStruct == FIELDOFFSET( CNRITEM, rc.pszIcon )) )
  165.     {
  166.         CHAR szNewName[ CCHMAXPATH + 1 ];
  167.  
  168.         WinQueryWindowText( hwndMLE, sizeof( szNewName ), szNewName );
  169.  
  170.         if( RenameFile( hwndCnr, pci, szNewName ) )
  171.         {
  172.             (void) strcpy( pci->szFileName, szNewName );
  173.  
  174.             // Since more than one container can share this record, let all
  175.             // of them know that this record has changed.
  176.  
  177.             RefreshAllContainers( hwndCnr, pci );
  178.         }
  179.     }
  180. }
  181.  
  182. /**********************************************************************/
  183. /*-------------------------- GetMaxNameSize --------------------------*/
  184. /*                                                                    */
  185. /*  GET THE MAXIMUM SIZE OF A FILE NAME FOR A DRIVE.                  */
  186. /*                                                                    */
  187. /*  INPUT: drive letter                                               */
  188. /*                                                                    */
  189. /*  1.                                                                */
  190. /*                                                                    */
  191. /*  OUTPUT: max filename size                                         */
  192. /*                                                                    */
  193. /*--------------------------------------------------------------------*/
  194. /**********************************************************************/
  195.  
  196. #define QFSBUFFSIZE 100
  197.  
  198. static ULONG GetMaxNameSize( CHAR chDrive )
  199. {
  200.     APIRET      rc;
  201.     CHAR        szDrive[ 3 ], achBuf[ QFSBUFFSIZE ];
  202.     PFSQBUFFER2 pfsqb = (PFSQBUFFER2) achBuf;
  203.     ULONG       cbFileName = 0, cbBuf = sizeof( achBuf );
  204.     PSZ         szFSDName;
  205.  
  206.     szDrive[ 0 ] = chDrive;
  207.     szDrive[ 1 ] = ':';
  208.     szDrive[ 2 ] = 0;
  209.  
  210.     // Get the file system type for this drive (i.e. HPFS, FAT, etc.)
  211.  
  212.     rc = DosQueryFSAttach( szDrive, 0, FSAIL_QUERYNAME, (PFSQBUFFER2) achBuf,
  213.                            &cbBuf );
  214.  
  215.     // Should probably handle ERROR_BUFFER_OVERFLOW more gracefully, but not
  216.     // in this sample program <g>
  217.  
  218.     if( rc )
  219.         cbFileName = 12;                     // If any errors, assume FAT
  220.     else
  221.     {
  222.         szFSDName = pfsqb->szName + pfsqb->cbName + 1;
  223.  
  224.         if( !stricmp( "FAT", szFSDName ) )
  225.             cbFileName = 12;
  226.         else
  227.             cbFileName = CCHMAXPATH;         // If not FAT, assume maximum path
  228.     }
  229.  
  230.     return cbFileName;
  231. }
  232.  
  233. /**********************************************************************/
  234. /*--------------------------- RenameFile -----------------------------*/
  235. /*                                                                    */
  236. /*  RENAME A FILE.                                                    */
  237. /*                                                                    */
  238. /*  INPUT: container window handle,                                   */
  239. /*         pointer to CNRITEM record of the current file,             */
  240. /*         new file name                                              */
  241. /*                                                                    */
  242. /*  1.                                                                */
  243. /*                                                                    */
  244. /*  OUTPUT: TRUE or FALSE if successful or not                        */
  245. /*                                                                    */
  246. /*--------------------------------------------------------------------*/
  247. /**********************************************************************/
  248. static BOOL RenameFile( HWND hwndCnr, PCNRITEM pci, PSZ szNewName )
  249. {
  250.     BOOL      fSuccess = TRUE;
  251.     CHAR      szCurrentPath[ CCHMAXPATH + 1 ];
  252.     PCH       pch;
  253.     APIRET    rc;
  254.     PINSTANCE pi = INSTDATA( PARENT( hwndCnr ) );
  255.  
  256.     if( !pi )
  257.     {
  258.         Msg( "RenameFile cant get Inst data. RC(%X)", HWNDERR( hwndCnr ) );
  259.  
  260.         return FALSE;
  261.     }
  262.  
  263.     // Recursively go up the container tree to get the fully qualified path
  264.     // name of the file to be renamed.
  265.  
  266.     (void) strcpy( szCurrentPath, pi->szDirectory );
  267.  
  268.     FullyQualify( szCurrentPath, hwndCnr, pci );
  269.  
  270.     (void) strcpy( pi->achWorkBuf, szCurrentPath );
  271.  
  272.     // Use the fully qualified path to build the filename that the current
  273.     // file is to be renamed to. In other words, in order to rename
  274.     // d:\path\file.ext to file.ren, we need to do a
  275.     // DosMove( "d:\path\file.ext", "d:\path\file.ren" );
  276.     // So we add file.ren after the last backslash of the current pathname.
  277.  
  278.     pch = strrchr( pi->achWorkBuf, '\\' );
  279.  
  280.     if( pch )
  281.         *(pch + 1) = 0;
  282.     else
  283.         pi->achWorkBuf[ 0 ] = 0;
  284.  
  285.     (void) strcat( pi->achWorkBuf, szNewName );
  286.  
  287.     // Do the rename. Alert the user if the rename was not successful. It
  288.     // won't be successful if, for instance, the user tries to change the name
  289.     // to a name that is already used in that directory or the file is on a FAT
  290.     // drive and they try to assign a long name.
  291.  
  292.     rc = DosMove( szCurrentPath, pi->achWorkBuf );
  293.  
  294.     if( rc )
  295.     {
  296.         if( rc == ERROR_FILENAME_EXCED_RANGE )
  297.             Msg( "Cannot rename file %s to %s! Name is too long for this"
  298.                  " drive.", szCurrentPath, pi->achWorkBuf, rc );
  299.         else
  300.             Msg( "Cannot rename file %s to %s! RC(%u)", szCurrentPath,
  301.                 pi->achWorkBuf, rc );
  302.  
  303.         fSuccess = FALSE;
  304.     }
  305.  
  306.     return fSuccess;
  307. }
  308.  
  309. /**********************************************************************/
  310. /*----------------------- RefreshAllContainers -----------------------*/
  311. /*                                                                    */
  312. /*  REFRESH ALL CONTAINERS BECAUSE A FILE WAS RENAMED THAT COULD ALSO */
  313. /*  BE IN OTHER CONTAINERS.                                           */
  314. /*                                                                    */
  315. /*  INPUT: container window handle that is being direct-edited,       */
  316. /*         pointer to CNRITEM record of the renamed file              */
  317. /*                                                                    */
  318. /*  1.                                                                */
  319. /*                                                                    */
  320. /*  OUTPUT: nothing                                                   */
  321. /*                                                                    */
  322. /*--------------------------------------------------------------------*/
  323. /**********************************************************************/
  324. static VOID RefreshAllContainers( HWND hwndCnr, PCNRITEM pci )
  325. {
  326.     HWND hwndEnum;
  327.  
  328.     hwndEnum = WinBeginEnumWindows( HWND_DESKTOP );
  329.  
  330.     if( hwndEnum )
  331.     {
  332.         HWND hwndFrame, hwndClient;
  333.         CHAR szClass[ 50 ];
  334.  
  335.         while( fTrue )
  336.         {
  337.             hwndFrame = WinGetNextWindow( hwndEnum );
  338.  
  339.             if( !hwndFrame )
  340.                 break;
  341.  
  342.             // If we found a frame window (child of the desktop), check to see
  343.             // if it has a client window because that's the one that would have
  344.             // the class that we're looking for
  345.  
  346.             hwndClient = WinWindowFromID( hwndFrame, FID_CLIENT );
  347.  
  348.             if( hwndClient )
  349.             {
  350.                 // Make sure we are checking NULL-terminated strings
  351.  
  352.                 (void) memset( szClass, 0, sizeof( szClass ) );
  353.  
  354.                 // Get the class of this client window. If it is one of ours,
  355.                 // send it a CM_INVALIDATERECORD message so it repaints the
  356.                 // renamed record. Since we don't know if this container has
  357.                 // the renamed record, ignore the return code.
  358.  
  359.                 if( WinQueryClassName( hwndClient, sizeof(szClass), szClass ) )
  360.                     if( !strcmp( szClass, DIRECTORY_WINCLASS ) )
  361.                         WinSendDlgItemMsg( hwndClient, CNR_DIRECTORY,
  362.                                     CM_INVALIDATERECORD, MPFROMP( &pci ),
  363.                                     MPFROM2SHORT( 1, CMA_TEXTCHANGED ) );
  364.             }
  365.         }
  366.  
  367.         WinEndEnumWindows( hwndEnum );
  368.     }
  369.     else
  370.         Msg( "RefreshAllContainers EnumWindows RC(%X)", HWNDERR( hwndCnr ) );
  371. }
  372.  
  373. /*************************************************************************
  374.  *                     E N D     O F     S O U R C E                     *
  375.  *************************************************************************/
  376.