home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK4 / SAMPLES / PWBEXTEN / DISKMENU.C$ / DISKMENU
Encoding:
Text File  |  1992-02-05  |  22.2 KB  |  884 lines

  1. /* DISKMENU.C - Disk menu: multifile open, touch, delete
  2.  *
  3.  * Copyright <C> 1992, Microsoft Corporation, All rights reserved
  4.  * All rights reserved.
  5.  *
  6.  * Demonstrates the following extension functions:
  7.  *
  8.  * IdAddPwbMenuItem     IdFindPwbMenuItem   DoMessageBox    DoStatusBox
  9.  * fExecute             FileNameToHandle    FindSwitch      ForFile
  10.  * fSetWindowWithFile   GetLine             GetListHandle   GetPfileFromName
  11.  * ScanList             SelectFiles
  12.  *
  13.  * Switches: None
  14.  *
  15.  * Functions:
  16.  *
  17.  *  See each function's header comment for the details on the arguments
  18.  *  accepted by each.
  19.  *
  20.  *  OpenFiles        Open multiple files
  21.  *  TouchFiles       Touch files (set file modification time to current time
  22.  *                   and date)
  23.  *  DeleteFiles      Delete files
  24.  *
  25.  * Macros:
  26.  *
  27.  *  Macro            Menu Command
  28.  *  ---------------  -----------------
  29.  *  DiskOpenFiles    Disk.Open Files
  30.  *  DiskDeleteFiles  Disk.Delete Files
  31.  *  DiskTouchFiles   Disk.Touch Files
  32.  *
  33.  * Special Macros (similar to Mgreplist):
  34.  *
  35.  *  Mopenlist        List of files to open
  36.  *  Mdellist         List of files to delete
  37.  *  Mtouchlist       List of files to touch
  38.  *
  39.  */
  40.  
  41. #pragma warning( disable:4001 )  //Allow single-line comments
  42. #pragma warning( disable:4100 )  //Allow unused arguments
  43.  
  44. #include <dos.h>
  45. #include <string.h>
  46. #include "ext.h"
  47.  
  48. //  Special macros
  49. //
  50. static char *szOpenList  = "Mopenlist";
  51. static char *szTouchList = "Mtouchlist";
  52. static char *szDelList   = "Mdellist";
  53.  
  54. //  fExecute strings to define the Disk menu's macros
  55. //
  56. static char *DefineDiskOpenFiles   = "arg \"DiskOpenFiles:=cancel OpenFiles <\" assign";
  57. static char *DefineDiskTouchFiles  = "arg \"DiskTouchFiles:=cancel TouchFiles <\" assign";
  58. static char *DefineDiskDeleteFiles = "arg \"DiskDeleteFiles:=cancel meta DeleteFiles <\" assign";
  59.  
  60. //  Miscellaneous strings
  61. static char *Banner    = "Multifile Example Extension";
  62. static char *ReadOnly  = "File is read-only";
  63. static char *QContinue = "Continue?";
  64.  
  65.  
  66. void _cdecl EXTERNAL WhenLoaded( void );
  67.  
  68. //
  69. //  Exported functions
  70. //
  71.  
  72. PWBFUNC OpenFiles  ( unsigned argData, ARG far *pArg, flagType fMeta );
  73. PWBFUNC TouchFiles ( unsigned argData, ARG far *pArg, flagType fMeta );
  74. PWBFUNC DeleteFiles( unsigned argData, ARG far *pArg, flagType fMeta );
  75.  
  76. //
  77. //  Local functions
  78. //
  79.  
  80. //  Void-return shells for ForFile
  81. void __pascal EXPORT DoTouchFile ( char far *FileName );
  82. void __pascal EXPORT DoDeleteFile( char far *FileName );
  83. void __pascal EXPORT DoOpenFile  ( char far *FileName );
  84.  
  85. flagType DoOpenFilesBox  ( void );
  86. flagType DoTouchFilesBox ( flagType fConfirm );
  87. flagType DoDeleteFilesBox( flagType fConfirm );
  88.  
  89. flagType TouchFile( char far *FileName );
  90. flagType __pascal DeleteFile( char far *FileName );
  91.  
  92. char far *ParseFileName( LINE y, COL x );
  93.  
  94. //  Low-level DOS file functions
  95. //
  96. //  Some of these simulate _dos_... functions from DOS.H, that cannot be
  97. //  used in an extension
  98. //
  99. unsigned __pascal DOSGetCurDate( void );
  100. unsigned __pascal DOSGetCurTime( void );
  101. unsigned __pascal DOSGetFileAttr( char far *FileName, unsigned * attrib );
  102. unsigned __pascal DOSOpenFile( char far *FileName, BYTE flags, int *iFile );
  103. unsigned __pascal DOSCloseFile( int iFile );
  104. unsigned __pascal DOSSetFileTime( int iFile, unsigned date, unsigned time );
  105.  
  106.  
  107. //--------------------------<  Implementations  >------------------------//
  108.  
  109. //  DOSGetCurDate - Get current DOS date
  110. //
  111. //  Returns the current DOS date in packed format
  112. //
  113. unsigned __pascal DOSGetCurDate( void )
  114. {
  115.     unsigned rv;
  116.     _asm
  117.     {
  118.         mov ah, 2ah
  119.         int 21h
  120.         sub cx, 1980
  121. #ifdef _M_I8086
  122.         shl cx, 1
  123.         shl cx, 1
  124.         shl cx, 1
  125.         shl cx, 1
  126.         shl cx, 1
  127.         shl cx, 1
  128.         shl cx, 1
  129.         shl cx, 1
  130.         shl cx, 1
  131. #else
  132.         shl cx, 9
  133. #endif
  134.         or  cl, dl
  135. #ifdef _M_I8086
  136.         shl dh, 1
  137.         shl dh, 1
  138.         shl dh, 1
  139.         shl dh, 1
  140.         shl dh, 1
  141. #else
  142.         shl dh, 5
  143. #endif
  144.         or  cl, dh
  145.         mov rv, cx
  146.     }
  147.     return rv;
  148. }
  149.  
  150. //  DOSGetCurTime - Get current DOS time
  151. //
  152. //  Returns the current DOS time in packed format
  153. //
  154.  
  155. unsigned __pascal DOSGetCurTime( void )
  156. {
  157.     unsigned rv;
  158.     __asm
  159.     {
  160.         mov ah, 0x2c
  161.         int 21h
  162.         xor ax, ax
  163.         mov al, ch
  164. #ifdef _M_I8086
  165.         mov cl, 11
  166.         shl ax, cl
  167. #else
  168.         shl ax, 11
  169. #endif
  170. #ifdef _M_I8086
  171.         mov cl, 5
  172.         shl dh, cl
  173. #else
  174.         shl dh, 5
  175. #endif
  176.         or  al, dh
  177.         mov rv, ax
  178.     }
  179.     return rv;
  180. }
  181.  
  182. //  DOSGetFileAttr - Get a file's attributes
  183. //
  184. //  simulate _dos_getfileattr
  185. //
  186.  
  187. unsigned __pascal DOSGetFileAttr( char far *FileName, unsigned *attrib )
  188. {
  189.     BYTE cflag = 0;
  190.     unsigned status;
  191.     unsigned offName = _FP_OFF(FileName);
  192.     unsigned segName = _FP_SEG(FileName);
  193.  
  194.     // Int 21, Function 43h: Get file attributes
  195.     __asm
  196.     {
  197.         push ds
  198.         mov ah, 43h
  199.         mov al, 0
  200.         mov dx, offName
  201.         mov ds, segName
  202.         int 21h
  203.         pop ds
  204.         jc  Error
  205.         mov status, cx
  206.         jmp end_block
  207.  
  208.     Error:
  209.         mov status, ax
  210.         mov cflag, 1
  211.  
  212.     end_block:
  213.     }
  214.     if( cflag )
  215.         return status;
  216.     else
  217.     {
  218.         *attrib = status;
  219.         return 0;
  220.     }
  221. }
  222.  
  223. //  DOSOpenFile - Open specified file, return file handle
  224. //
  225. //  simulate _dos_open
  226. //
  227.  
  228. unsigned __pascal DOSOpenFile( char far *FileName, BYTE flags, int *iFile )
  229. {
  230.     unsigned status;
  231.     BYTE cflag = 0;
  232.     unsigned offName = _FP_OFF(FileName);
  233.     unsigned segName = _FP_SEG(FileName);
  234.  
  235.     // Int 21, Function 3dh: Open file handle
  236.     __asm
  237.     {
  238.         push ds
  239.         mov ah, 3dh
  240.         mov al, flags
  241.         mov dx, offName
  242.         mov ds, segName
  243.         int 21h
  244.         pop ds
  245.         mov status, ax
  246.         jnc end_block
  247.         mov cflag, 1
  248.     end_block:
  249.     }
  250.  
  251.     if( cflag )
  252.         return status;
  253.     else
  254.     {
  255.         *iFile = status;
  256.         return 0;
  257.     }
  258.  
  259. }
  260.  
  261. //  DOSCloseFile - Close file specified by handle
  262. //
  263. //  simulate _dos_close
  264. //
  265. unsigned __pascal DOSCloseFile( int iFile )
  266. {
  267.     int status;
  268.     BYTE cflag = 0;
  269.  
  270.     // Int 21, Function 3eh: Close file handle
  271.     __asm
  272.     {
  273.         mov ah, 0x3e
  274.         mov bx, iFile
  275.         int 21h
  276.         jnc end_block
  277.         mov status, ax
  278.         mov cflag, 1
  279.     end_block:
  280.     }
  281.  
  282.     if( cflag )
  283.         return status;
  284.     else
  285.         return 0;
  286. }
  287.  
  288. //  DOSSetFileTime - Set file's timestamp
  289. //
  290. //  simulate _dos_setftime
  291. //
  292.  
  293. unsigned __pascal DOSSetFileTime( int iFile, unsigned date, unsigned time )
  294. {
  295.     unsigned status;
  296.     BYTE cflag = 0;
  297.  
  298.     // Int 21, Function 57h: Set file date/time
  299.     __asm
  300.     {
  301.         mov ah, 57h
  302.         mov al, 01h
  303.         mov bx, iFile
  304.         mov cx, time
  305.         mov dx, date
  306.         int 21h
  307.         jnc end_block
  308.         mov cflag, 1
  309.         mov status, ax
  310.     end_block:
  311.     }
  312.  
  313.     if( cflag )
  314.         return status;
  315.     else
  316.         return 0;
  317.  
  318. }
  319.  
  320. //  Shell for ForFile
  321. void __pascal EXPORT DoTouchFile( char far *FileName )
  322. {
  323.     TouchFile( FileName );
  324. }
  325.  
  326. //  TouchFile - Change modification date of file to the current time
  327. //
  328. //  Returns:
  329. //  TRUE    File touched
  330. //  FALSE   Error
  331. //
  332.  
  333. flagType TouchFile( char far *FileName )
  334. {
  335.     unsigned attrib;
  336.     unsigned date;
  337.     unsigned time;
  338.     int ifile;
  339.  
  340.     if( DOSGetFileAttr( FileName, &attrib) )
  341.         return FALSE;
  342.  
  343.     if( attrib & _A_RDONLY )
  344.     {
  345.         DoMessageBox( "Can't touch", FileName, ReadOnly, MBOX_OK|MBOX_BEEP|MBOX_NOHELP, 0 );
  346.         return FALSE;
  347.     }
  348.  
  349.     if( attrib & (_A_SUBDIR|_A_VOLID|_A_SYSTEM) )
  350.     {
  351.         DoMessageBox( "Can't touch", FileName, "File is a directory or system file", MBOX_OK|MBOX_BEEP|MBOX_NOHELP, 0 );
  352.         return FALSE;
  353.     }
  354.  
  355.     if( DOSOpenFile( FileName, 0x0002, &ifile ) )
  356.     {
  357.         DoMessageBox( "Can't touch", FileName, "Can't open file", MBOX_OK|MBOX_BEEP|MBOX_NOHELP, 0 );
  358.         return FALSE;
  359.     }
  360.  
  361.     date = DOSGetCurDate();
  362.     time = DOSGetCurTime();
  363.     DOSSetFileTime( ifile, date, time );
  364.     DOSCloseFile( ifile );
  365.  
  366.     return TRUE;
  367.  
  368. }
  369.  
  370. //  Shell for ForFile
  371. void __pascal EXPORT DoDeleteFile( char far *FileName )
  372. {
  373.     DeleteFile( FileName );
  374. }
  375.  
  376. //  DeleteFile - Delete the specified file from disk
  377. //
  378. //  Returns:
  379. //  TRUE    File deleted
  380. //  FALSE   File not deleted
  381. //
  382.  
  383. flagType __pascal DeleteFile( char far *FileName )
  384. {
  385.     static char msgErr[] = "Can't delete";
  386.  
  387.     unsigned attrib;
  388.     unsigned status;
  389.     unsigned offName;
  390.     unsigned segName;
  391.     flagType fError = FALSE;
  392.     BYTE Function;
  393.  
  394.     if( DOSGetFileAttr( FileName, &attrib) )
  395.         return FALSE;
  396.     if( attrib & _A_RDONLY )
  397.     {
  398.         DoMessageBox( msgErr, FileName, ReadOnly, MBOX_OK|MBOX_BEEP|MBOX_NOHELP, 0 );
  399.         return FALSE;
  400.     }
  401.     if( attrib & (_A_VOLID|_A_SYSTEM) )
  402.     {
  403.         DoMessageBox( msgErr, FileName, "File is a volume ID or system file", MBOX_OK|MBOX_BEEP|MBOX_NOHELP, 0 );
  404.         return FALSE;
  405.     }
  406.     offName = _FP_OFF(FileName);
  407.     segName = _FP_SEG(FileName);
  408.     if( attrib & _A_SUBDIR )
  409.         Function = 0x3a; //Function 3ah -- remove directory
  410.     else
  411.         Function = 0x41; //Function 41h -- delete file
  412.     __asm
  413.     {
  414.         mov ah, Function
  415.         mov dx, offName
  416.         mov ds, segName
  417.         int 21h
  418.         jnc end_block
  419.         mov fError, 1
  420.         mov status, ax
  421.     end_block:
  422.     }
  423.  
  424.     if( fError )   //error
  425.     {
  426.         switch( status )
  427.         {
  428.         case 0x02:
  429.         case 0x03:
  430.             DoMessageBox( msgErr, FileName, "File not found", MBOX_OK|MBOX_BEEP|MBOX_NOHELP, 0 );
  431.             return FALSE;
  432.  
  433.         case 0x05:
  434.             DoMessageBox( msgErr, FileName, "Access denied", MBOX_OK|MBOX_BEEP|MBOX_NOHELP, 0 );
  435.             return FALSE;
  436.  
  437.         case 0x10:
  438.             if( Function == 0x3a )
  439.             {
  440.                 DoMessageBox( msgErr, FileName, "Directory is the current directory", MBOX_OK|MBOX_BEEP|MBOX_NOHELP, 0 );
  441.                 return FALSE;
  442.             }
  443.             //else fall through
  444.         default:
  445.             DoMessageBox( msgErr, FileName, NULL, MBOX_OK|MBOX_BEEP|MBOX_NOHELP, 0 );
  446.             return FALSE;
  447.         }
  448.     }
  449.  
  450.     return TRUE;
  451. }
  452.  
  453.  
  454. //  ParseFileName - Parse filename or wildcard at cursor
  455. //
  456. //  Return NULL on failure, else pointer to filename
  457. //
  458. char far *ParseFileName( LINE y, COL x )
  459. {
  460.     static buffer temp;
  461.     static char *FileChars =
  462.         ":\\abcdefghijklmnopqrstuvwxyz0123456789.*?`~!@#$%^-_=/',[]{}()";
  463.  
  464.     PFILE pfile;
  465.     char far *FileName;
  466.     char far *FileNameEnd;
  467.  
  468.     if( (pfile = FileNameToHandle( NULL, NULL )) == PNULL )
  469.     {
  470.         //no file
  471.         bell();
  472.         return NULL;
  473.     }
  474.  
  475.     //  Parse filename or wildcard at cursor
  476.     //
  477.     GetLine( y, temp, pfile );
  478.     FileName = temp + x;
  479.  
  480.     //  Trim to the longest span of legal characters
  481.     farstrlwr( FileName );
  482.     FileNameEnd = FileName + _fstrspn( FileName, FileChars );
  483.     if( FileNameEnd )
  484.         *FileNameEnd = '\0';
  485.     return FileName;
  486.  
  487. }
  488.  
  489. //  Shell for ForFile
  490.  
  491. void __pascal EXPORT DoOpenFile( char far *FileName )
  492. {
  493.     fSetWindowWithFile( FileName );
  494. }
  495.  
  496. //  DoOpenFilesBox - Display the Open Files dialog box
  497. //
  498. flagType DoOpenFilesBox( void )
  499. {
  500.     PCMD FileList;
  501.     char far *FileName;
  502.     flagType ret = TRUE;
  503.  
  504.     FileList = GetListHandle( szOpenList, TRUE );
  505.     if( !SelectFiles( FileList, "Open Files", "Selected Files to ~Open",
  506.                       "*.*", FALSE, 0 ) )
  507.         return FALSE;
  508.     FileName = ScanList( FileList, TRUE );
  509.     while( FileName != NULL )
  510.     {
  511.         if( farstrchr( FileName, '*' ) || farstrchr( FileName, '?' ) )
  512.         {
  513.             //wildcard
  514.             if( !ForFile( FileName, FORFILE_ALL, DoOpenFile ) )
  515.                 ret = FALSE;
  516.         }
  517.         else
  518.             fSetWindowWithFile( FileName );
  519.         FileName = ScanList( PNULL, TRUE );
  520.     }
  521.  
  522.     return ret;
  523.  
  524. }
  525.  
  526. //  DoTouchFilesBox - Display the Touch Files dialog box
  527. //
  528.  
  529. flagType DoTouchFilesBox( flagType fConfirm )
  530. {
  531.     PCMD FileList;
  532.     char far *FileName;
  533.     flagType ret = TRUE;
  534.  
  535.     FileList = GetListHandle( szTouchList, TRUE );
  536.     if( !SelectFiles( FileList, "Touch Files", "~Selected Files to Touch",
  537.                  "*.*", FALSE, 0 ) )
  538.         return FALSE;
  539.     FileName = ScanList( FileList, TRUE );
  540.     while( FileName != NULL )
  541.     {
  542.         if( fConfirm )
  543.         {
  544.             switch( DoMessageBox( "About to touch file:", FileName,
  545.                                   "Are you sure you want to touch it?",
  546.                                   MBOX_YESNOCANCEL|MBOX_NOHELP, 0 ) )
  547.             {
  548.             case MBOX_IDYES:    break;
  549.             case MBOX_IDNO:     FileName = ScanList( PNULL, TRUE );
  550.                                 continue;
  551.             case MBOX_IDCANCEL: return FALSE;
  552.             }
  553.         }
  554.         if( farstrchr( FileName, '*' ) || farstrchr( FileName, '?' ) )
  555.         {
  556.             //wildcard
  557.             if( !ForFile( FileName, FORFILE_ALL, DoTouchFile ) )
  558.                 ret = FALSE;
  559.         }
  560.         else
  561.         if( !TouchFile( FileName ) )
  562.         {
  563.             if( DoMessageBox( "Can't touch file:", FileName,
  564.                               "Continue processing list?",
  565.                               MBOX_YESNO|MBOX_BEEP|MBOX_NOHELP, 0 )
  566.                 == MBOX_IDNO )
  567.                 return FALSE;
  568.         }
  569.         FileName = ScanList( PNULL, TRUE );
  570.     }
  571.  
  572.     return ret;
  573.  
  574. }
  575.  
  576. //  DoDeleteFilesBox - Display the Delete Files dialog box
  577. //
  578.  
  579. flagType DoDeleteFilesBox( flagType fConfirm )
  580. {
  581.     PCMD FileList;
  582.     char far *FileName;
  583.     flagType ret = TRUE;
  584.  
  585.     FileList = GetListHandle( szDelList, TRUE );
  586.     if( !SelectFiles( FileList, "Delete Files", "~Selected Files to Delete",
  587.                  "*.*", FALSE, 0 ) )
  588.         return FALSE;
  589.     FileName = ScanList( FileList, TRUE );
  590.     while( FileName != NULL )
  591.     {
  592.         if( fConfirm )
  593.         {
  594.             switch( DoMessageBox( "About to delete:", FileName,
  595.                                   QContinue,
  596.                                   MBOX_YESNOCANCEL|MBOX_NOHELP, 0 ) )
  597.             {
  598.             case MBOX_IDYES:    break;
  599.             case MBOX_IDNO:     FileName = ScanList( PNULL, TRUE );
  600.                                 continue;
  601.             case MBOX_IDCANCEL: return FALSE;
  602.             }
  603.         }
  604.         if( farstrchr( FileName, '*' ) || farstrchr( FileName, '?' ) )
  605.         {
  606.             //wildcard
  607.             if( !ForFile( FileName, FORFILE_ALL, DoDeleteFile ) )
  608.                 ret = FALSE;
  609.         }
  610.         else
  611.         if( !DeleteFile( FileName ) )
  612.         {
  613.             if( DoMessageBox( "Can't delete file:", FileName,
  614.                               "Continue processing list?",
  615.                               MBOX_YESNO|MBOX_BEEP|MBOX_NOHELP, 0 )
  616.                 == MBOX_IDNO )
  617.                 return FALSE;
  618.         }
  619.         FileName = ScanList( PNULL, TRUE );
  620.     }
  621.  
  622.     return ret;
  623.  
  624. }
  625.  
  626. //------------------------<  Exported Functions  >-----------------------//
  627.  
  628. // OpenFiles - Open multiple files
  629. //
  630. // Input:
  631. //  No args              - Display Open Files dialog box
  632. //  Meta                 - Toggle NewWindow switch
  633. //  Arg                  - Parse name at cursor
  634. //  textarg              - Open specified files(s)
  635. //  stream, one-line-box - Open selected file(s)
  636. //
  637. // Output:
  638. //      TRUE : All specified files opened
  639. //      FALSE: At least one file was not opened
  640. //
  641. PWBFUNC OpenFiles( unsigned argData, ARG far *pArg, flagType fMeta )
  642. {
  643.     char far *FileName = NULL;
  644.     flagType ret = TRUE;
  645.     flagType NewWindow;
  646.     PSWI pswi;
  647.     static char *ChangeSwitch1 = "arg \"newwindow:";
  648.     static char *ChangeSwitch2 = "\" assign";
  649.     static char ChangeSwitch[25];
  650.  
  651.     if( fMeta ) //Toggle NewWindow switch
  652.     {
  653.         pswi = FindSwitch( "newwindow" );
  654.         NewWindow = *(pswi->act.fval);
  655.         farstrcpy( ChangeSwitch, ChangeSwitch1 );
  656.         farstrcat( ChangeSwitch, NewWindow ? "0" : "1" );
  657.         farstrcat( ChangeSwitch, ChangeSwitch2 );
  658.         fExecute( ChangeSwitch );
  659.         //  Build string to restore NewWindow
  660.         farstrcpy( ChangeSwitch, ChangeSwitch1 );
  661.         farstrcat( ChangeSwitch, NewWindow ? "1" : "0" );
  662.         farstrcat( ChangeSwitch, ChangeSwitch2 );
  663.     }
  664.  
  665.     switch( pArg->argType )
  666.     {
  667.     case NOARG:
  668.         ret = DoOpenFilesBox();
  669.         //  Restore NewWindow if toggled
  670.         if( fMeta )
  671.             fExecute( ChangeSwitch );
  672.         if( !ret )
  673.             bell();
  674.         return ret;
  675.         break;
  676.  
  677.     case NULLARG:
  678.         FileName = ParseFileName( pArg->arg.nullarg.y, pArg->arg.nullarg.x );
  679.         break;
  680.  
  681.     case TEXTARG:
  682.         FileName = pArg->arg.textarg.pText;
  683.         break;
  684.  
  685.     }
  686.  
  687.     if( farstrchr( FileName, '*' ) || farstrchr( FileName, '?' ) )
  688.     {
  689.         //wildcard
  690.         if( !ForFile( FileName, FORFILE_ALL, DoOpenFile ) )
  691.             ret = FALSE;
  692.     }
  693.     else
  694.         fSetWindowWithFile( FileName );
  695.  
  696.     //  Restore NewWindow if toggled
  697.     if( fMeta )
  698.         fExecute( ChangeSwitch );
  699.     bell();
  700.     return ret;
  701.  
  702. }
  703.  
  704. // TouchFiles - Change modification date of file or wildcard files
  705. //
  706. // Input:
  707. //  No args              - Display Touch Files dialog box
  708. //  Meta                 - Confirm at each file or wildcard
  709. //  Arg                  - Parse name at cursor
  710. //  textarg              - Touch specified file or wildcard
  711. //  stream, one-line-box - Touch selected file or wildcard
  712. //
  713. // Output:
  714. //      TRUE : All specified files opened
  715. //      FALSE: At least one file was not opened
  716. //
  717.  
  718. PWBFUNC TouchFiles( unsigned argData, ARG far *pArg, flagType fMeta )
  719. {
  720.     char far *FileName = NULL;
  721.  
  722.     switch( pArg->argType )
  723.     {
  724.     case NOARG:
  725.         return DoTouchFilesBox( fMeta );
  726.  
  727.     case NULLARG:
  728.         FileName = ParseFileName( pArg->arg.nullarg.y, pArg->arg.nullarg.x );
  729.         break;
  730.  
  731.     case TEXTARG:
  732.         FileName = pArg->arg.textarg.pText;
  733.  
  734.     }
  735.  
  736.     if( fMeta )
  737.     {
  738.         if( DoMessageBox( "About to Touch file:", FileName, QContinue,
  739.                           MBOX_YESNO|MBOX_NOHELP, 0 )
  740.             == MBOX_IDNO )
  741.             return FALSE;
  742.     }
  743.     if( farstrchr( FileName, '*' ) || farstrchr( FileName, '?' ) )
  744.     {
  745.         //wildcard
  746.         if( !ForFile( FileName, FORFILE_ALL, DoTouchFile ) )
  747.             return FALSE;
  748.     }
  749.     else
  750.         return TouchFile( FileName );
  751.  
  752. }
  753.  
  754.  
  755. // DeleteFiles - Delete file, directory, or wildcard
  756. //
  757. // Input:
  758. //  No arg               - Display Delete Files dialog box
  759. //  Meta                 - Confirm at each file or wildcard
  760. //  Arg                  - Parse name at cursor
  761. //  textarg              - Delete specified file or wildcard
  762. //  stream, one-line-box - Delete selected file or wildcard
  763. //
  764. // Output:
  765. //      TRUE : All specified files deleted
  766. //      FALSE: At least one file was not deleted
  767. //
  768.  
  769. PWBFUNC DeleteFiles( unsigned argData, ARG far *pArg, flagType fMeta )
  770. {
  771.     char far *FileName = NULL;
  772.     flagType ret = TRUE;
  773.  
  774.     switch( pArg->argType )
  775.     {
  776.     case NOARG:
  777.         ret = DoDeleteFilesBox( fMeta );
  778.         return ret;
  779.  
  780.     case NULLARG:
  781.         FileName = ParseFileName( pArg->arg.nullarg.y, pArg->arg.nullarg.x );
  782.         break;
  783.  
  784.     case TEXTARG:
  785.         FileName = pArg->arg.textarg.pText;
  786.         break;
  787.     }
  788.     if( fMeta )
  789.     {
  790.         if( DoMessageBox( "About to delete:", FileName, QContinue,
  791.                           MBOX_YESNO|MBOX_NOHELP, 0 )
  792.             == MBOX_IDNO )
  793.             return FALSE;
  794.     }
  795.     if( farstrchr( FileName, '*' ) || farstrchr( FileName, '?' ) )
  796.     {
  797.         //wildcard
  798.         if( !ForFile( FileName, FORFILE_ALL, DoDeleteFile ) )
  799.             ret = FALSE;
  800.     }
  801.     else
  802.         ret = DeleteFile( FileName );
  803.  
  804.     return ret;
  805. }
  806.  
  807.  
  808. //-----------------< Standard Extension Information >----------------//
  809.  
  810. // WhenLoaded
  811. //
  812. //
  813. //
  814. //
  815. void _cdecl EXTERNAL WhenLoaded( void )
  816. {
  817.     WORD idEditMenu;
  818.     WORD idDiskMenu;
  819.  
  820.     DoStatusBox( Banner, NULL );
  821.  
  822.     //Initialize extension
  823.  
  824.     //  Define macros for menus
  825.     fExecute( DefineDiskOpenFiles   );
  826.     fExecute( DefineDiskDeleteFiles );
  827.     fExecute( DefineDiskTouchFiles  );
  828.  
  829.     //  Add Disk menu
  830.     idEditMenu = IdFindPwbMenuItem( "~Edit", 0, FALSE );
  831.     if( (idDiskMenu = IdAddPwbMenuItem(
  832.                       TM_ENABLED|TM_UNCHECKED|TM_SUBMENU|TM_NORECORD,
  833.                       0, idEditMenu,
  834.                       "~Disk",
  835.                       "Disk operations menu", NULL, NULL )
  836.         ) == 0 )
  837.     {
  838.         DoStatusBox( NULL, NULL );   //Close status box
  839.         DoMessageBox( Banner, "Can't add Disk menu!", NULL, MBOX_OK|MBOX_NOHELP|MBOX_CAPTION, 0 );
  840.         return;
  841.     }
  842.  
  843.     //  Assume that once there is a Disk menu, none of the other items
  844.     //  will fail to add.
  845.  
  846.     //  Open Files...
  847.     IdAddPwbMenuItem( TM_ENABLED|TM_COMMAND, idDiskMenu, 0,
  848.                       "~Open Files...",
  849.                       "Open multiple files", NULL,
  850.                       "DiskOpenFiles" );
  851.     //  Touch Files...
  852.     IdAddPwbMenuItem( TM_ENABLED|TM_COMMAND, idDiskMenu, 0,
  853.                       "~Touch Files...",
  854.                       "Touch multiple files", NULL,
  855.                       "DiskTouchFiles" );
  856.     //  separator bar
  857.     IdAddPwbMenuItem( TM_SEPARATOR|TM_NORECORD, idDiskMenu, 0, NULL, NULL, NULL, NULL );
  858.  
  859.     //  Delete Files...
  860.     IdAddPwbMenuItem( TM_ENABLED|TM_COMMAND, idDiskMenu, 0,
  861.                       "~Delete Files...",
  862.                       "Delete multiple files", NULL,
  863.                       "DiskDeleteFiles" );
  864.  
  865.     DoStatusBox( NULL, NULL );   //Close status box
  866.  
  867. }
  868.  
  869. //
  870. // Command description table.
  871. //
  872. struct cmdDesc cmdTable[] =
  873. {
  874.     { "OpenFiles",   OpenFiles,   0, NOARG|NULLARG|TEXTARG|BOXSTR|NOWINDOWS|ICONFOCUS },
  875.     { "TouchFiles",  TouchFiles,  0, NOARG|NULLARG|TEXTARG|BOXSTR|NOWINDOWS|ICONFOCUS },
  876.     { "DeleteFiles", DeleteFiles, 0, NOARG|NULLARG|TEXTARG|BOXSTR|NOWINDOWS|ICONFOCUS },
  877.     { NULL, NULL, 0, 0 } //end-of-table
  878. };
  879.  
  880. //
  881. // Switch description table.
  882. //
  883. struct swiDesc swiTable[] = { { NULL, NULL, 0 } };
  884.