home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1998 August / VPR9808B.BIN / APUPDATE / VC / Tx300d / TX300D.LZH / CMD.C < prev    next >
Text File  |  1997-05-07  |  23KB  |  858 lines

  1. // WZ EDITOR 標準機能 コマンドライン
  2. // Copyright 1995-96 TY
  3.  
  4. //{###コマンドライン}
  5. //MS-DOSのCOMMAND.COMのような機能を提供します。
  6. //1.00F ディレクトリ対応copy/move/delete thanks m.osakoさん
  7.  
  8. //1.00H2 rename -> fileDelete for long filename 対応
  9.  
  10. #include <windows.h>
  11. #include <windowsx.h>
  12. #include "_filer.h"
  13. #include "dialog.h"
  14.  
  15. #ifdef __FLAT__
  16. static WIN32_FIND_DATA gfn_ffd;
  17. static HANDLE gfn_hfind = INVALID_HANDLE_VALUE;
  18. #else
  19. extern "shell.dll" {
  20.     HINSTANCE WINAPI FindExecutable(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult);
  21.     HINSTANCE WINAPI ShellExecute(HWND,LPCSTR,LPCSTR,LPCSTR,LPCSTR,int);
  22. }
  23. static FILEFIND gfn_filefind;
  24. static BOOL gfn_filefinding;
  25. #endif
  26. static mchar *gfn_szarg;
  27. static mchar gfn_szfilename[CCHPATHNAME];
  28.  
  29. static mchar *getfilename(mchar szfilename[CCHPATHNAME],mchar *szarg,BOOL fwild)
  30. {
  31.     mchar *szarg0 = szarg;
  32.     
  33.     #ifdef __FLAT__
  34.     if (gfn_hfind != INVALID_HANDLE_VALUE) {
  35.         while(1) {
  36.             if (FindNextFile(gfn_hfind,&gfn_ffd)) {
  37.                 if (gfn_ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
  38.                 strcpy(szfilename,gfn_szfilename);
  39.                 pathSetFileName(szfilename,gfn_ffd.cFileName);
  40.                 return gfn_szarg;
  41.             } else {
  42.                 //2.00B WZ32でcmd("del *.*")が失敗した
  43.                 break;
  44.             }
  45.         }
  46.         FindClose(gfn_hfind);
  47.         gfn_hfind = INVALID_HANDLE_VALUE;
  48.     }
  49.     #else
  50.     if (gfn_filefinding) {
  51.         if (!fileFindNext(&gfn_filefind)) {
  52.             strcpy(szfilename,gfn_szfilename);
  53.             pathSetFileName(szfilename,gfn_filefind.name);
  54.             return gfn_szarg;
  55.         }
  56.         gfn_filefinding = FALSE;
  57.     }
  58.     #endif
  59.     if (!szarg) return NULL;
  60.     if (szfilename) szfilename[0] = 0;
  61.     szarg = strGetWordTop(szarg);
  62.     if (!*szarg) return NULL;
  63.     int len = strGetWordLen(szarg);
  64.     if (szfilename) {
  65.         strcpylen(szfilename,szarg,len);
  66.         pathFormLong(szfilename);//1.00H2 
  67.     }
  68.     szarg += len;
  69.     gfn_szarg = szarg;
  70.     if (fwild) {
  71.         if (
  72.             szfilename[0] != '-' &&    // スイッチはそのまま返す
  73.             !pathIsFileName(szfilename)
  74.         ) {
  75. #ifdef __FLAT__
  76.     #if 1    //2.00B WZ32でcmd("del *.*")が"."を削除しようとして失敗した
  77.             gfn_hfind = FindFirstFile(szfilename,&gfn_ffd);
  78.             if (gfn_hfind != INVALID_HANDLE_VALUE) {
  79.                 while(1) {
  80.                     if (gfn_ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  81.                         if (FindNextFile(gfn_hfind,&gfn_ffd)) {
  82.                         } else {
  83.                             FindClose(gfn_hfind);
  84.                             gfn_hfind = INVALID_HANDLE_VALUE;
  85.                             break;
  86.                         }
  87.                     } else {
  88.                         break;
  89.                     }
  90.                 }
  91.                 if (gfn_hfind != INVALID_HANDLE_VALUE) {
  92.                     strcpy(gfn_szfilename,szfilename);
  93.                     pathSetFileName(szfilename,gfn_ffd.cFileName);
  94.                     return gfn_szarg;
  95.                 }
  96.             }
  97.     #else
  98.             gfn_hfind = FindFirstFile(szfilename,&gfn_ffd);
  99.             if (gfn_hfind != INVALID_HANDLE_VALUE) {
  100.                 strcpy(gfn_szfilename,szfilename);
  101.                 pathSetFileName(szfilename,gfn_ffd.cFileName);
  102.                 return gfn_szarg;
  103.             }
  104.     #endif
  105. #else
  106.             if (!fileFindFirst(szfilename,FA_NORMAL,&gfn_filefind)) {
  107.                 gfn_filefinding = TRUE;
  108.                 strcpy(gfn_szfilename,szfilename);
  109.                 pathSetFileName(szfilename,gfn_filefind.name);
  110.                 return gfn_szarg;
  111.             }
  112. #endif
  113.         }
  114.     }
  115.     return szarg;
  116. }
  117.  
  118.  
  119. static int questionOverwrite(mchar* szfilename)
  120. {
  121. //2.96A 970213 上書きコピー確認で、キャンセル、すべて上書き、追加
  122.     HDIALOG hd = dialog("上書き確認");
  123.     dialogCaption(hd,szfilename);
  124.     dialogCaption(hd,"は存在します。");
  125.     dialogCaption(hd,"上書きコピーしてもよろしいですか?");
  126.     dialogSetFocus(hd,IDNO);
  127.     dialogSetH(hd);
  128.     dialogControlID(hd,IDYES);
  129.     dialogCmd(hd,"はい(&Y)",12);
  130.     dialogControlID(hd,IDNO);
  131.     dialogCmdDefault(hd,"いいえ(&N)",12);
  132.     dialogControlID(hd,IDCANCEL);
  133.     dialogCmd(hd,"キャンセル",12);
  134.     dialogControlID(hd,IDIGNORE);
  135.     dialogCmd(hd,"すべて上書き(&A)",20);
  136.     int ret = dialogOpen(hd);
  137.     if (ret) return ret;
  138.     if (!ret) return IDCANCEL;
  139. }
  140.  
  141. #define FILECOPYEX_NOOVERWRITE    2
  142. #define FILECOPYEX_CANCEL        3    //2.96A 970213 
  143.  
  144. // return 1:OK
  145. //        0:ERR
  146. //        FILECOPYEX_NOOVERWRITE:上書きしなかった
  147. //        FILECOPYEX_CANCEL:キャンセル
  148. static BOOL fileCopyEx(mchar *szsrc,mchar *szdst,BOOL* fConfirmOverwrite)
  149. {
  150.     if (*fConfirmOverwrite && fileIsExist(szdst)) {
  151. #if 1//2.96A 970213 
  152.         int ret = questionOverwrite(szdst);
  153.         switch(ret) {
  154.             case IDNO: return FILECOPYEX_NOOVERWRITE;
  155.             case IDCANCEL: {
  156.                 return FILECOPYEX_CANCEL;
  157.             }
  158.             case IDIGNORE: {
  159.                 *fConfirmOverwrite = FALSE;
  160.                 break;
  161.             }
  162.         }
  163. #else
  164.         if (question("%s は存在します。\n上書きコピーしてもよろしいですか?",szdst) != IDYES) {
  165.             return FILECOPYEX_NOOVERWRITE;
  166.         }
  167. #endif
  168.     }
  169.     return fileCopy(szsrc,szdst);
  170. }
  171.  
  172. // パスの最後が \ マークか?
  173. // return:
  174. //         \  TRUE
  175. //        !\  FALSE
  176. BOOL check_enmark(mchar *szd)
  177. {
  178.     mchar *p = strGetLast(szd);
  179.     if (*p == '\\') return TRUE;
  180.     return FALSE;
  181. }
  182.  
  183. // パスがディレクトリか?
  184. BOOL cmd_pathIsDirectory(mchar *path)
  185. {
  186.     mchar buff[CCHPATHNAME];
  187.     strcpy(buff,path);
  188.     pathFormDir(buff);
  189.     return pathIsDirectory(buff);
  190. }
  191.  
  192. static BOOL _fdirtime;    //2.00E mkdirでできたディレクトリのtimeを記録するか
  193.                         // 記録したらFALSEにリセットする
  194. #ifdef __FLAT__
  195. static FILETIME _dirtime;        //2.00E 記録した時間
  196. #else
  197. static DOSFILETIME _dirtime;    //2.00E 記録した時間
  198. #endif
  199.  
  200. // 対象ディレクトリが存在しなければ、mkdir
  201. void check_dst_dir(mchar *szdstname)
  202. {
  203.     mchar szd[CCHPATHNAME];
  204.     strcpy( szd, szdstname );
  205.     pathFormDir(szd);
  206. #if 1//1.00H2 WZ32に対応
  207.     if (!pathIsDirectory(szd)) {
  208.         mkdir(szd);
  209.     #if 1//2.00E 
  210.         if (_fdirtime) {
  211.             #ifdef __FLAT__
  212.             WIN32_FIND_DATA find;
  213.             HANDLE handle = FindFirstFile(szd,&find);
  214.             BOOL ret = (handle != INVALID_HANDLE_VALUE);
  215.             #else
  216.             FILEFIND find;
  217.             BOOL ret = !fileFindFirst(szd,FA_DIREC,&find);
  218.             #endif
  219.             if (ret) {
  220.                 _fdirtime = FALSE;
  221.                 #ifdef __FLAT__
  222.                 _dirtime = find.ftCreationTime;
  223.                 FindClose(handle);
  224.                 #else
  225.                 _dirtime = MAKELONG(find.wr_time,find.wr_date);
  226.                 #endif
  227.             }
  228.         }
  229.     #endif
  230.     }
  231. #else
  232.     FILEFIND find;
  233.     if ( fileFindFirst(szd,FA_DIREC,&find) ) {
  234.         mkdir(szd);
  235.     }
  236. #endif
  237. }
  238.  
  239. #define MAX_DIRDEPTH    10        // 最大ディレクトリ深さ
  240. #define ENMFILE            0x12    // "No more files" error code
  241.  
  242. #ifdef __FLAT__
  243.     #define ffdGetFileName(ffd)    ((ffd).cFileName)
  244.     #define ffdGetAtrDirectory(ffd)    ((ffd).dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  245. #else
  246.     #define ffdGetFileName(ffd)    ((ffd).name)
  247.     #define ffdGetAtrDirectory(ffd)    ((ffd).attrib & FA_DIREC)
  248. #endif
  249.  
  250. // ディレクトリを削除
  251. BOOL dir_remove(mchar *szsrc)
  252. {
  253.     mchar szcurdir[CCHPATHNAME];
  254.     mchar szd[CCHPATHNAME];
  255.     int ret;
  256.     
  257.     strcpy(szd,szsrc);
  258.     pathFormDir(szd);
  259.     // 削除するディレクトリのドライブのカレントディレクトリをルートに
  260.     driveGetCurDir(szd[0],szcurdir);
  261.     driveSetCurDir(0,chartostr(szd[0])+\":\");//1.00F カレントディレクトリが削除できなかった
  262.     // delete
  263.     ret = !rmdir(szd);
  264.     // カレントディレクトリを戻す
  265.     driveSetCurDir(0,szcurdir);
  266.     return ret;
  267. }
  268.  
  269. // ----------------------------------------------------- m.osako ---
  270. // ディレクトリ毎コピー・削除
  271. // 返り値仕様変更 by TY
  272. // return TRUE: 正常終了
  273. //          FALSE: 失敗
  274. //        FILECOPYEX_NOOVERWRITE:上書きしなかったファイルがあった
  275. //        FILECOPYEX_CANCEL:キャンセル
  276. // -----------------------------------------------------------------
  277. int dirCopy(HWND hwnd, int id, mchar *szsrc, mchar *szdst,BOOL* fConfirmOverwrite,BOOL fMove,BOOL fDelete)
  278. {
  279.     #ifdef __FLAT__
  280.     WIN32_FIND_DATA find[MAX_DIRDEPTH];
  281.     HANDLE thandle[MAX_DIRDEPTH];
  282.     int i;
  283.     for (i = 0;i < MAX_DIRDEPTH;i++) {
  284.         thandle[i] = INVALID_HANDLE_VALUE;
  285.     }
  286.     #else
  287.     FILEFIND find[MAX_DIRDEPTH];
  288.     int        fattr = FA_DIREC|FA_ARCH|FA_RDONLY|FA_HIDDEN|FA_SYSTEM;
  289.     #endif
  290.     mchar    *psrc[MAX_DIRDEPTH], *pdst[MAX_DIRDEPTH];
  291.     int nest = 0;        // 処理中のディレクトリ階層
  292.     int result = TRUE;    // 返り値(コピー中にエラー発生したらFALSEになる)
  293.     BOOL fCopy = !fDelete;
  294.     BOOL f = TRUE;        // findfirst flag
  295.  
  296. //    attention("%s->%s", szsrc, szdst);
  297.     _fdirtime = TRUE;//2.00E 
  298.     while(1) {
  299.         int ret;//TY
  300.         if (fCopy) check_dst_dir(szdst);
  301.         if (f) {
  302.             #ifdef __FLAT__
  303.             thandle[nest] = FindFirstFile(szsrc+"*.*",&find[nest]);
  304.             ret = (thandle[nest] == INVALID_HANDLE_VALUE);
  305.             #else
  306.             ret = fileFindFirst(szsrc+"*.*",fattr,&find[nest]);
  307.             #endif
  308.         } else {
  309.             #ifdef __FLAT__
  310.             ret = !FindNextFile(thandle[nest],&find[nest]);
  311.             #else
  312.             ret = fileFindNext(&find[nest]);
  313.             #endif
  314.         }
  315.         f = FALSE;
  316.         while(!ret) {
  317. //information(szsrc + ffdGetFileName(find[nest]));
  318.             if (ffdGetFileName(find[nest])[0] != '.') {
  319.                 if (ffdGetAtrDirectory(find[nest])) {
  320.                     if (nest+1 >= MAX_DIRDEPTH) {
  321.                         attention( "%d階層を越えます",MAX_DIRDEPTH );
  322.                         return FALSE;
  323.                     }
  324.                     #ifdef __FLAT__
  325.                     BOOL fSkip = (fCopy && !_fdirtime && (CompareFileTime(&find[nest].ftCreationTime,&_dirtime) >= 0));
  326.                     #else
  327.                     BOOL fSkip = (fCopy && !_fdirtime && MAKELONG(find[nest].wr_time,find[nest].wr_date) >= _dirtime);
  328.                     #endif
  329.                     if (fSkip) {
  330.                         //2.00E filerでディレクトリ\testを\test\testにコピーすると無限ループした
  331.                         // コピー中に作成したディレクトリも、コピー元のディレクトリとみなしていたため。
  332.                         // コピー中に最初に作成したディレクトリの作成日時を保持し、この日時より
  333.                         // 新しいディレクトリをコピー元で見つけた時は、そのディレクトリはコピーしないことにした
  334.                     } else {
  335.                         f = TRUE;
  336.                         psrc[nest] = szsrc + strlen(szsrc);
  337.                         strcat(szsrc,ffdGetFileName(find[nest]));
  338.                         strcat(szsrc,"\\");
  339.                         if (fCopy) {
  340.                             pdst[nest] = szdst + strlen(szdst);
  341.                             strcat(szdst,ffdGetFileName(find[nest]));
  342.                             strcat(szdst,"\\");
  343.                         }
  344.                         nest++;
  345.                         break;
  346.                     }
  347.                 } else {
  348.                     if (fDelete) {
  349.                         if (!fileDelete(szsrc + ffdGetFileName(find[nest]))) {
  350.                             result = FALSE;
  351.                             break;
  352.                         }
  353.                     } else if (fCopy) {
  354.                         SetDlgItemText(hwnd,id,ffdGetFileName(find[nest]) + " を " + szdst + " にコピー中");
  355. //                        wait(1000);
  356.                         mchar* szsrcfilename = szsrc + ffdGetFileName(find[nest]);
  357.                         int ret = fileCopyEx(szsrcfilename,szdst + ffdGetFileName(find[nest]),fConfirmOverwrite);
  358.                         if (ret == FALSE) {
  359.                             result = FALSE;
  360.                         } else if (ret == FILECOPYEX_NOOVERWRITE) {
  361.                             if (result == TRUE) result = ret;
  362.                         } else if (ret == FILECOPYEX_CANCEL) {
  363.                             //2.96A 970213 
  364.                             result = ret;
  365.                             break;
  366.                         } else if (fMove) {
  367.                             fileDelete(szsrcfilename);
  368.                         }
  369.                     }
  370.                 }
  371.             }
  372.             #ifdef __FLAT__
  373.             ret = !FindNextFile(thandle[nest],&find[nest]);
  374.             #else
  375.             ret = fileFindNext(&find[nest]);
  376.             #endif
  377.         }
  378.         if (result == FALSE) break;//1.00H エラー発生対応
  379.         if (result == FILECOPYEX_CANCEL) {
  380.             break;//2.96A 970213 
  381.         }
  382.         if (f) {
  383.             // ネスト
  384.             //2.00E WZ32でディレクトリのコピー、削除するとハングアップした
  385.         } else {
  386.             #ifdef __FLAT__
  387.             BOOL fNoMoreFile = (GetLastError() == ERROR_NO_MORE_FILES);
  388.             #else
  389.             BOOL fNoMoreFile = (ret == ENMFILE);
  390.             #endif
  391.             if (!fNoMoreFile) {
  392.                 //2.00E まだファイルがあるのに抜けたならerror
  393.                 result = FALSE;
  394.                 break;
  395.             }
  396.             #ifdef __FLAT__
  397.             if (nest) {
  398.                 FindClose(thandle[nest]);
  399.                 thandle[nest] = INVALID_HANDLE_VALUE;
  400.             }
  401.             #endif
  402.             if (fDelete) {
  403.                 if (!dir_remove(szsrc)) {
  404.                     result = FALSE;
  405.                     break;
  406.                 }
  407.             }
  408.             if (nest) {
  409.                 // 階層ディレクトリの中をコピーしていた場合
  410.                 nest--;
  411.                 *psrc[nest] = 0;
  412.                 if (fCopy) {
  413.                     *pdst[nest] = 0;
  414.                 }
  415.             } else {
  416.                 if (fCopy) {
  417.                     // 階層では無いので終了
  418.                     break;
  419.                 }
  420.             }
  421.         }
  422.     }
  423. #ifdef __FLAT__
  424.     for (i = 0;i < MAX_DIRDEPTH;i++) {
  425.         FindClose(thandle[i]);
  426.     }
  427. #endif
  428.     return result;
  429. }
  430.  
  431. // ----------------------------------------------------- m.osako ---
  432. // ディレクトリ毎削除
  433. //
  434. // 返り値仕様変更 by TY
  435. // return TRUE: 正常終了
  436. //          FALSE: 失敗
  437. // -----------------------------------------------------------------
  438. BOOL dirDel(mchar *szsrc)
  439. {
  440.     return dirCopy(NULL,-1,szsrc,NULL,FALSE,FALSE,TRUE);
  441. }
  442.  
  443.  
  444. void parsefile(mchar *szfile, mchar *szfilename)
  445. {
  446. // szfilenameからディレクトリ名を抜き出す
  447.     mchar szwk[CCHPATHNAME];
  448.     strcpy(szwk,szfilename);
  449.     pathFormDir(szwk);
  450.     strcpy(szfile,pathGetFileName(szwk));
  451.     pathSetDir(szfile);
  452. }
  453.  
  454. //##cmd
  455.  
  456. int cmd_rename(mchar *szarg)
  457. {
  458.     mchar szfilename[CCHPATHNAME];
  459.     mchar szdstname[CCHPATHNAME];
  460.     szarg = getfilename(szfilename,szarg,FALSE);
  461.     szarg = getfilename(szdstname,szarg,FALSE);
  462.     if (szarg) {
  463.         pathFormDir(szfilename);
  464.         pathFormDir(szdstname);
  465.         if (!rename(szfilename,szdstname)) return 1;
  466.     }
  467.     return 0;
  468. }
  469.  
  470. // ディレクトリのコピーは、"directoryname\"の様に最後に"\"をつけて指定しないといけない
  471. int cmd_mcopy(mchar *szarg)
  472. {
  473.     int n = 0;
  474.     mchar szfilename[CCHPATHNAME];
  475.     mchar szdstname[CCHPATHNAME];
  476.     mchar szsrcpath[CCHPATHNAME] = {0};    //コピー元のパス
  477.     szarg = getfilename(szdstname,szarg,FALSE);
  478.     pathFormDir(szdstname);
  479.     mchar *dstfilename = szdstname + strlen(szdstname);
  480.     *dstfilename++ = '\\';
  481.     BOOL fConfirmOverwrite = FALSE;
  482.     //
  483.     HDIALOG hd = dialog("コピー");
  484.     int id = dialogCaptionDynamic(hd,NULL,80);//2.00B 
  485.     dialogSetNoButton(hd);
  486.     HWND hwnd = dialogCreate(hd);
  487.     BOOL fail = FALSE;
  488.     check_dst_dir(szdstname);
  489.     while(1) {
  490.         szarg = getfilename(szfilename,szarg,TRUE);
  491.         if (!szarg) break;
  492.         if (szfilename[0] == '-') {//1.00F スイッチは無視
  493.             if (szfilename[1] == 'p') {
  494.                 strcpy(szsrcpath,szfilename + 2);
  495.                 pathFormLong(szsrcpath);//1.94 -p"path"に対応してなかった
  496.                 pathSetDir(szsrcpath);
  497.             } else if (szfilename[1] == 'o') {
  498.                 fConfirmOverwrite = TRUE;
  499.             }
  500.         } else {
  501.             strcpy(dstfilename,pathGetFileName(szfilename));
  502.             {
  503.                 mchar c = *dstfilename;
  504.                 *dstfilename = 0;//ファイル名を消去
  505.                 SetDlgItemText(hwnd,id,pathGetFileName(szfilename) + " を " + szdstname + " にコピー中");
  506.                 *dstfilename = c;
  507.             }
  508.             if (cmd_pathIsDirectory(szfilename)) {//TY
  509.                 // directory
  510.                 mchar szfile[CCHFILENAME];
  511.                 parsefile(szfile, szfilename);
  512.                 int ret = dirCopy(hwnd, id, szsrcpath+szfilename, szdstname + szfile,&fConfirmOverwrite,FALSE,FALSE);
  513. //information("%d",ret);
  514.                 if (ret == 0) {
  515.                     fail = TRUE;
  516.                     break;
  517.                 } else if (ret == FILECOPYEX_CANCEL) {
  518.                     //2.96A 970213 
  519.                     break;
  520.                 }
  521.             } else {
  522.                 // single file
  523.                 int ret = fileCopyEx(szsrcpath + szfilename,szdstname,&fConfirmOverwrite);
  524.                 if (ret == 0) {
  525.                     fail = TRUE;
  526.                     break;
  527.                 } else if (ret == FILECOPYEX_CANCEL) {
  528.                     //2.96A 970213 
  529.                     break;
  530.                 }
  531.             }
  532.             n++;
  533.         }
  534.     }
  535.     dialogFree(hwnd);
  536.     if (fail) attention(szsrcpath + szfilename+" を "+szdstname+" にコピー失敗しました");
  537.     return n;
  538. }
  539.  
  540. // ディレクトリの移動は、"directoryname\"の様に最後に"\"をつけて指定しないといけない
  541. int cmd_mmove(mchar *szarg)
  542. {
  543.     int n = 0;
  544.     mchar szfilename[CCHPATHNAME];
  545.     mchar szdstname[CCHPATHNAME];
  546.     szarg = getfilename(szdstname,szarg,FALSE);
  547.     pathFormDir(szdstname);
  548.     mchar *dstfilename = szdstname + strlen(szdstname);
  549.     *dstfilename++ = '\\';
  550.     *dstfilename = 0;
  551.     BOOL fConfirmOverwrite = FALSE;
  552.     BOOL fail = FALSE;
  553.     //
  554.     HDIALOG hd = dialog("移動");
  555.     int id = dialogCaptionDynamic(hd,NULL,80);//2.00B 
  556.     dialogSetNoButton(hd);
  557.     HWND hwnd = dialogCreate(hd);
  558.     check_dst_dir(szdstname);
  559.     while(1) {
  560.         szarg = getfilename(szfilename,szarg,TRUE);
  561.         if (!szarg) break;
  562.         if (szfilename[0] == '-') {//1.00F スイッチは無視
  563.             if (szfilename[1] == 'o') {
  564.                 fConfirmOverwrite = TRUE;
  565.             }
  566.         } else {
  567.             strcpy(dstfilename,pathGetFileName(szfilename));
  568.             {
  569.                 mchar c = *dstfilename;
  570.                 *dstfilename = 0;//ファイル名を消去
  571.                 SetDlgItemText(hwnd,id,pathGetFileName(szfilename) + " を "+szdstname+" に移動中...");
  572.                 *dstfilename = c;
  573.             }
  574.             if (szfilename[0] == szdstname[0]) {
  575.                 // 同一ドライブ内なら、rename
  576.                 if (!stricmp(szfilename,szdstname)) {
  577.                     //1.00F 移動元と移動先が同じディレクトリの場合、ファイルが削除されていた
  578.                 } else if (!rename(szfilename,szdstname)) {
  579.                     // rename OK
  580.                     n++;
  581.                 } else {
  582.                     // rename 失敗
  583.                     if( cmd_pathIsDirectory(szfilename) )//TY
  584.                     {
  585.                         // directory
  586.                         mchar szfile[CCHFILENAME];
  587.                         parsefile(szfile, szfilename);
  588.                         int ret = dirCopy(hwnd, id, szfilename, szdstname+szfile,&fConfirmOverwrite,TRUE,FALSE);
  589.                         if (ret == 0) {
  590.                             fail = TRUE;
  591.                             break;
  592.                         } else if (ret == FILECOPYEX_CANCEL) {
  593.                             //2.96A 970213 
  594.                             break;
  595.                         } else {
  596.                             if (ret == TRUE) dirDel(szfilename);
  597.                             n++;
  598.                         }
  599.                     } else {
  600.                         // single file
  601.                         int ret = fileCopyEx(szfilename,szdstname,&fConfirmOverwrite);
  602.                         if (ret == FALSE) {
  603.                             fail = TRUE;
  604.                             break;
  605.                         } else if (ret == TRUE) {
  606.                             fileDelete(szfilename);
  607.                             n++;
  608.                         } else if (ret == FILECOPYEX_CANCEL) {
  609.                             //2.96A 970213 
  610.                             break;
  611.                         }
  612.                     }
  613.                 }
  614.             } else {
  615.                 // ドライブが異なれば、コピー後に削除
  616.                 if( cmd_pathIsDirectory(szfilename) )//TY
  617.                 {
  618.                     // directory
  619.                     mchar szfile[CCHFILENAME];
  620.                     parsefile(szfile, szfilename);
  621.                     int ret = dirCopy(hwnd, id, szfilename, szdstname+szfile,&fConfirmOverwrite,TRUE,FALSE);
  622.                     if (ret == FALSE) {
  623.                         fail = TRUE;
  624.                         break;
  625.                     } else if (ret == FILECOPYEX_CANCEL) {
  626.                         //2.96A 970213 
  627.                         break;
  628.                     } else {
  629.                         if (ret == TRUE) dirDel(szfilename);
  630.                         n++;
  631.                     }
  632.                 } else {
  633.                     // single file
  634.                     //1.00F3 異なるドライブ間でファイル移動すると失敗した
  635.                     int ret = fileCopyEx(szfilename,szdstname,&fConfirmOverwrite);
  636.                     if (ret == TRUE) {
  637.                         fileDelete(szfilename);
  638.                         n++;
  639.                     } else if (ret == FALSE) {
  640.                         fail = TRUE;
  641.                         break;
  642.                     } else if (ret == FILECOPYEX_CANCEL) {
  643.                         //2.96A 970213 
  644.                         break;
  645.                     }
  646.                 }
  647.             }
  648.         }
  649.     }
  650.     dialogFree(hwnd);
  651.     if (fail) attention(szfilename+" の移動に失敗しました");
  652.     return n;
  653. }
  654.  
  655. int cmd_mkdir(mchar *szarg)
  656. {
  657.     mchar szfilename[CCHPATHNAME];
  658.     szarg = getfilename(szfilename,szarg,FALSE);
  659.     if (szarg) {
  660.         if (!mkdir(szfilename)) return 1;
  661.     }
  662.     return 0;
  663. }
  664.  
  665. int cmd_mkfile(mchar *szarg)
  666. {
  667.     int n = 0;
  668.     mchar szfilename[CCHPATHNAME];
  669.     
  670.     szarg = getfilename(szfilename,szarg,FALSE);
  671.     if (szarg) {
  672.         HFILE hf = _lopen(szfilename,OF_READ);
  673.         if (hf != HFILE_ERROR) {
  674.             _lclose(hf);
  675.         } else {
  676.             hf = _lcreat(szfilename,0);
  677.             if (hf != HFILE_ERROR) {
  678.                 _lclose(hf);
  679.                 n++;
  680.             }
  681.         }
  682.     }
  683.     return n;
  684. }
  685.  
  686. static int _cmd_open(mchar *szarg,mchar *sw)
  687. {
  688.     int n = 0;
  689.     mchar szfilename[CCHPATHNAME];
  690.     while(1) {
  691.         szarg = getfilename(szfilename,szarg,TRUE);
  692.         if (!szarg) break;
  693.         if (sw) strcat(szfilename,sw);
  694.         txOpenForkFast(text,szfilename);
  695.         n++;
  696.     }
  697.     return n;
  698. }
  699.  
  700. int cmd_open(mchar *szarg)
  701. {
  702.     return _cmd_open(szarg,NULL);
  703. }
  704.  
  705. int cmd_openread(mchar *szarg)
  706. {
  707.     return _cmd_open(szarg," --R");
  708. }
  709.  
  710. //1.01
  711. static BOOL fileIsOpenWz(mchar* szfilename)
  712. {
  713. // szfilenameのファイルをWZで開くかどうか返す
  714.     mchar szcommand[CCHPATHNAME];
  715.     if (FindExecutable(szfilename,NULL,szcommand) > 32) {
  716.         mchar *szfilename = pathGetFileName(szcommand);
  717.         // notepadが関連付けられてたらWZで開く
  718.         if (!stricmp(szfilename,"notepad.exe")) return TRUE;
  719.         return FALSE;
  720.     }
  721.     return TRUE;
  722. }
  723.  
  724. //1.00H4 
  725. int cmd_winopen(mchar* szarg)
  726. {
  727.     int n = 0;
  728.     mchar szfilename[CCHPATHNAME];
  729.     while(1) {
  730.         szarg = getfilename(szfilename,szarg,TRUE);
  731.         if (!szarg) break;
  732.         if (
  733.             fileIsOpenWz(szfilename) ||
  734.             ShellExecute(text->hwndbase,"open",szfilename,NULL,NULL,SW_SHOWNORMAL) <= 32
  735.                 //2.00E マインスイーパーの起動がおかしかったのでSW_SHOW->SW_SHOWNORMALに変更
  736.                 // 開けなかったらWZで開く
  737.         ) {
  738.             txOpenForkFast(text,szfilename);
  739.         }
  740.         n++;
  741.     }
  742.     return n;
  743. }
  744.  
  745. int cmd_view(mchar *szarg)
  746. {
  747.     return _cmd_open(szarg," -v");
  748. }
  749.  
  750. // ディレクトリの削除は、"directoryname\"の様に最後に"\"をつけて指定しないといけない
  751. int cmd_del(mchar *szarg)
  752. {
  753.     int n = 0;
  754.     mchar szfilename[CCHPATHNAME];
  755.     HDIALOG hd = dialog("削除");
  756.     int id = dialogCaptionDynamic(hd,NULL,80);//2.00B 
  757.     dialogSetNoButton(hd);
  758.     HWND hwnd = dialogCreate(hd);
  759.     BOOL fail = FALSE;
  760.     while(1) {
  761.         szarg = getfilename(szfilename,szarg,TRUE);
  762.         if (!szarg) break;
  763.         SetDlgItemText(hwnd,id,szfilename+ " を削除中...");
  764.         if (cmd_pathIsDirectory(szfilename)) {// directory
  765.             if (dirDel(szfilename)) {
  766.                 n++;
  767.             }
  768.         } else {
  769.             if (fileDelete(szfilename)) {
  770.                 n++;
  771.             }
  772.         }
  773.     }
  774.     dialogFree(hwnd);
  775.     return n;
  776. }
  777.  
  778. //##cmd実行
  779. int TXAPI cmd(mchar *szcommand)
  780. {
  781. // DOSのcommand.comの内部コマンドの様な機能を提供します
  782. // 例:
  783. // cmd(\"mcopy a:\dst file1 file2 file3"); file1,2,3をa:\dstにコピー
  784. // cmd(\"mcopy a:\dst -pa:\src file1 file2 file3");
  785. //      a:\srcのfile1,2,3をa:\dstにコピー
  786. // cmd(\"mcopy a:\dst dir1\ file2 file3"); dir1\,file2,3をa:\dstにコピー
  787. // cmd(\"mmove a:\dst\ file1 file2 file3"); file1,2,3をa:\dstに移動
  788. // cmd(\"rename src dst); srcをdstに名前変更
  789. // cmd(\"mkdir dst"); dstディレクトリを作成
  790. // cmd(\"mkfile dst"); dstファイルを作成
  791. // cmd(\"open file1 file2 file3"); file1,2,3をオープン
  792. // cmd(\"openread file1 file2 file3"); file1,2,3をリードオンリーオープン(1.00Fで追加)
  793. // cmd(\"winopen file1 file2 file3"); file1,2,3を関連づけられたアプリでオープン(1.00H4で追加)
  794. // cmd(\"view file1 file2 file3"); file1,2,3をビュー
  795. // cmd(\"del file1 file2 file3"); file1,2,3を削除
  796. // cmd(\"del dir1\ file2 file3"); dir1\ file2,3を削除
  797. // ※mcopy,mmove,open,view,delはワイルドカードも使えます。
  798. // ※区切り記号は、空白、タブの他に'|'も使えます。
  799. // 例:
  800. // cmd(\"commandname args");
  801. // マクロ"commandname.cmd_main"を引数argsを持って呼び出す。
  802. // 参考:lha.c
  803.     int n = 0;
  804.     
  805.     if (szcommand) {
  806.         mchar *pcmd = strGetWordTop(szcommand);
  807.         int lchcmd = strGetWordLen(pcmd);
  808.         int cmd = 0;
  809.         if (lchcmd) {
  810.             mchar *p = pcmd + lchcmd;
  811.             mchar szcmd[CCHWORD];
  812.             PMACROFUNC func;
  813.             
  814.             strcpy(szcmd,"cmd_");
  815.             mcharcpy(szcmd + 4,pcmd,lchcmd);
  816.             szcmd[4 + lchcmd] = 0;
  817.             mchar *szext = pathGetExt(szcmd);
  818.             if (
  819.                 !stricmp(szext,".exe") ||
  820.                 !stricmp(szext,".pif")//1.00C PIFも起動できるように
  821.             ) {
  822.                 WinExec(szcommand,SW_SHOW);
  823.                 return 1;
  824.             } else if (!stricmp(szext,".txe")) {//1.00C TXEも起動できるように
  825.                 //1.00H2 
  826.                 wzExec(szcommand);
  827.                 return 1;
  828.             } else if (macroGetFuncAddress(szcmd,&func)) {
  829.                 // このマクロ内に関数"cmd_コマンド名"があればそれを実行
  830.                 DWORD ret = 0;
  831.                 macroCallAddress(&func,&ret,1,p);
  832.                 return ret;
  833.             } else {
  834.                 // このマクロ内になければ"コマンド名.cmd_main"を実行
  835.                 DWORD ret = 0;
  836.                 mcharcpy(szcmd,pcmd,lchcmd);
  837.                 strcpy(szcmd+lchcmd,".cmd_main");
  838.                 macroCall(szcmd,&ret,1,p);
  839.                 return ret;
  840.             }
  841.         }
  842.     }
  843.     return n;
  844. }
  845.  
  846. //{###コマンドライン}
  847.  
  848. BOOL TXAPI exec(LPBYTE szcmd)
  849. {
  850. // szcmdのコマンドラインを実行します。
  851. // 例:exec("wz.exe filer.txe");    // WZ Filerを起動
  852.     if (WinExec(szcmd,SW_SHOW) < 32) {
  853.         return FALSE;
  854.     }
  855.     return TRUE;
  856. }
  857.  
  858.