home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / CNRMNU.ZIP / EDIT.C < prev    next >
Text File  |  1993-01-01  |  17KB  |  382 lines

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