home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1999 January / VPR9901A.BIN / APUPDATE / VC / Tx300d / TX300D.LZH / FILER.C < prev    next >
C/C++ Source or Header  |  1997-10-17  |  93KB  |  3,652 lines

  1. // WZ Filer
  2. // Copyright 1995-97 TY
  3. // Thanks to: y.mikomeさん/dieさん/千葉誠さん/熊谷武さん/m.osakoさん (古株順??)
  4.  
  5. //2.96 970211 従来のファイラーは、WZの高速オープンによる仕様変更の関係で動作
  6. // しなくなりました。また、度々の改良でプログラムがぐにゅぐにゅなので新しく
  7. // 作り直すことにしました。
  8.  
  9. //2.96A 970213 ファイラー改良
  10. // アトリビュートの変更、日付の変更をサポート、WZ32での動作の高速化
  11. // 上書きコピー確認 : キャンセル、すべて上書きボタン追加
  12. // ファイルの複製
  13.  
  14. //2.99D 970401 ファイル|コピー(P) -> コピー(C) VZユーザに使いにくかった
  15.  
  16. // ファイラーは高速オープンの対象にはしない。
  17. // ファイルオープンダイアログから起動されることもあるから。
  18.  
  19. #pragma TXE
  20.  
  21. #include <windows.h>
  22. #include <windowsx.h>
  23. #include "dialog.h"
  24. #include "_filer.h"
  25.  
  26. // drive
  27. #define IDM_DRIVETOP        100
  28. #define IDM_DRIVEEND        199
  29. // sort
  30. #define IDM_SORTNAME        200
  31. #define IDM_SORTEXT            201
  32. #define IDM_SORTNEW            202
  33. #define IDM_SORTOLD            203
  34. #define IDM_SORTBIG            204
  35. #define IDM_SORTSMALL        205
  36. #define IDM_SORTDIR            206
  37. #define SORT_N                7
  38. // other
  39. #define IDM_CMDLINE            1000
  40. #define WZSC_HISTORYFIRST    2000
  41. // display
  42. permanent BOOL p_fDispToolbar = FALSE;        // ツールバーを表示?
  43. permanent BOOL p_fDispFunctionKey = TRUE;    // ファンクションキーを表示?
  44. permanent BOOL p_fDispStatusbar = TRUE;        // ステータスバーを表示?
  45. permanent BOOL p_fDispGene = FALSE;            // 世代履歴ファイルも表示
  46. permanent BOOL p_fDouble = FALSE;            // ダブルウィンドウ?
  47. permanent BOOL p_fDoubleH = FALSE;            // ダブルウィンドウ:上下分割
  48. permanent BOOL p_fDoubleSize = TRUE;        // ダブルウィンドウ:サイズを拡大
  49. permanent int p_rateDouble = 50;            // ダブルウィンドウ時のfiler1の幅の比率
  50. // file op.
  51. permanent BOOL p_fConfirmOverwrite = FALSE;    // 上書きコピー確認
  52. permanent BOOL p_fConfirmDel = TRUE;        // 削除時確認
  53. permanent BOOL p_fConfirmCopy = TRUE;        // copy時確認
  54. // path
  55. permanent BOOL p_fLong = defined(__FLAT__);    // ロングファイル名モード
  56. permanent txstr p_szBinExt = ".exe .com .lzh .dll";    // バイナリファイルの拡張子
  57. permanent txstr p_szPath1;
  58. permanent txstr p_szPath2;
  59. permanent txstr p_szMask1;
  60. permanent txstr p_szMask2;
  61. // ui
  62. permanent BOOL p_fDirJumpRoot = FALSE;    // ディレクトリ移動後、..\へカーソル動かす
  63. permanent BOOL p_fIconize = FALSE;        // ファイルオープン/チャイルド操作後、アイコン化
  64. permanent BOOL p_fMenuKey = TRUE;        // 英字キー生押しでメニューオープン
  65. permanent BOOL p_fEscClose = FALSE;        // [ESC]で閉じる
  66. permanent BOOL p_fSelectMove = FALSE;    // スペースでカーソルを移動
  67. //sort
  68. permanent int p_modeSort = 3;            // ソートモード
  69. permanent int p_modeSort2 = 0;            // ソートモード2
  70. #if 0//3.00A3 970508 
  71. permanent int p_filer2modeSort = 3;        //2.99B 970322 ダブル側のソートモード
  72. permanent int p_filer2modeSort2 = 0;    //2.99B 970322 ダブル側のソートモード2
  73. #endif
  74. // window
  75. permanent BOOL p_fSaveWindowPos = TRUE;    // ウィンドウ位置を保存
  76. permanent int p_xWindow = 0;            // ウィンドウ位置x
  77. permanent int p_yWindow = 0;            // ウィンドウ位置y
  78. permanent int p_cxWindow = 400;            // ウィンドウサイズx
  79. permanent int p_cyWindow = 480;            // ウィンドウサイズy
  80. // font
  81. permanent BOOL p_lfBold = TRUE;                // 太字表示?
  82. permanent txstr p_lfFaceName = "FixedSys";    // フォント名
  83. permanent BYTE p_lfHeight = 10;                // ポイント数
  84. // color
  85. permanent COLORREF p_rgbBack = RGB(0xFF,0xFF,0xFF);
  86. permanent COLORREF p_rgbText = RGB(0,0,0);
  87. permanent COLORREF p_rgbBlock = RGB(0xC0,0xDC,0xC0);
  88. permanent COLORREF p_rgbBlockText = RGB(0,0,0);
  89. permanent COLORREF p_rgbBinary = RGB(0x00,0x00,0x80);
  90. permanent COLORREF p_rgbDirectory = RGB(0x00,0x80,0x00);
  91. permanent COLORREF p_rgbReadonly = RGB(0x80,0x80,0x80);
  92. permanent COLORREF p_rgbHidden = RGB(0xC0,0xC0,0xC0);
  93. permanent COLORREF p_rgbSystem = RGB(0x80,0x00,0x80);
  94. //2.99 970318 preview
  95. #define DEFAULT_PREVIEW_RATE    70
  96. static HWND _hwndPreview;                //2.99 970317 preview dialog
  97. static HWND _hwndPreviewPartition;        //2.99 970318 partition filer,preview
  98. permanent BOOL p_fPreview = TRUE;        //2.99 970318 
  99. permanent int p_ratePreview = DEFAULT_PREVIEW_RATE;//2.99 970318 プレビュー時のMainWindowの比率
  100. static BOOL _fPreviewDirty;                //3.00B1 970613 
  101.  
  102. // 一時設定
  103. static BOOL _fViewMode = FALSE;
  104. static BOOL _fReadOnly = FALSE;
  105. static BOOL _fOpenClose = FALSE;        // オープン後閉じる
  106. static BOOL _fEscClose = FALSE;
  107. static HWND _hwndParent = NULL;
  108.  
  109. static TX* _textFiler;        // filer base text
  110.  
  111. // filer context
  112. typedef struct {
  113.     TX* text;                    // text
  114.     // info window
  115.     HWND hwndInfo;
  116.     int cxInfo;                    //
  117.     int cyInfo;                    //
  118.     // env
  119.     mchar szPath[CCHPATHNAME];    // パス
  120.     mchar szMask[CCHPATHNAME];    // マスク
  121.     // status
  122.     int nSel;                    // 選択されたファイル数
  123.     int nSelDir;                // 選択されたディレクトリ数
  124.     DWORD cbSel;                // 選択されたファイルのファイルサイズの合計
  125.     DWORD cbDiskFree;            // ドライブの空き容量
  126.     // sort
  127.     int modeSort;                // ソートモード
  128.     int modeSort2;                // ソートモード2
  129.     int nDir;                    // ディレクトリ数
  130.     int nFile;                    // ファイル数
  131.     int nDirFile;                // ディレクトリ数+ファイル数
  132. } FILER;
  133. static FILER tFiler[2];
  134. static FILER* filer1 = &tFiler[0];
  135. static FILER* filer2 = &tFiler[1];
  136. static HWND _hwndPartition;
  137.  
  138. static void filerGetCurFilename(FILER *filer,mchar szfilename[CCHFILENAME]);
  139. static void cmdline(mchar* szcmdline,BOOL fMultiOpen);
  140. static void previewFlush(void);
  141.  
  142. //## text op.
  143.  
  144. static BYTE* txGetBuffX(TX* text,IBUFF offset)
  145. {
  146. // textの現在行頭から、offsetバイト目のテキストバッファを取得する。
  147.     IBUFF cury = text->cury;
  148.     if (text->fHigh) {
  149.         cury = (IBUFF)(txGetParaTop(text) - text->temp1);
  150.     }
  151.     IBUFF offsetNow = text->cur0 - cury;
  152.     if (offset < offsetNow) {
  153.         return &text->buff[text->cury + offset];
  154.     } else {
  155.         IBUFF d = offset - offsetNow;
  156.         if (d >= text->sizebuff - text->cur) {
  157.             // EOFを越える場合はNULLを返す。
  158.             return NULL;
  159.         }
  160.         return &text->buff[text->cur + (offset - offsetNow)];
  161.     }
  162. }
  163.  
  164. static int txGetCharX(TX* text,IBUFF offset)
  165. {
  166. // textの現在行頭から、offsetバイト目の文字を取得する。
  167. // 漢字は考慮しない。
  168.     BYTE* p = txGetBuffX(text,offset);
  169.     if (p) return *p;
  170.     return 0;
  171. }
  172.  
  173. //## 汎用op
  174.  
  175. static void my_chdir(mchar *szpath)
  176. {
  177.     mchar buff[CCHPATHNAME];
  178.     strcpy(buff,szpath);
  179.     pathForm(buff);
  180.     driveSetCurDir(buff[0],buff);
  181. }
  182.  
  183. //## filer basic
  184.  
  185. static FILER* filerGetFocus(void)
  186. {
  187.     if (filer2->text == textf) return filer2;
  188.     return filer1;
  189. }
  190.  
  191. static FILER* filerGetOther(FILER* filer)
  192. {
  193.     if (p_fDouble) {
  194.         return (filer == filer1) ? filer2 : filer1;
  195.     } else {
  196.         return NULL;
  197.     }
  198. }
  199.  
  200. static void filerDoCaption(FILER* filer)
  201. {
  202.     BOOL fCd = FALSE;
  203.     txstr sz = filer->szPath;
  204.     pathSetFileName(sz,NULL);
  205.     {//2.98 970307 filer:カレントディレクトリを[]で括って表示
  206.         mchar szcd[CCHPATHNAME];
  207.         driveGetCurDir(sz[0],szcd);
  208.         pathSetDir(szcd);
  209. //statprintf("%s %s %d",sz,szcd,pathCmp(szcd,sz,NULL));wait(500);
  210.         if (pathCmp(szcd,sz,NULL) == 0) {
  211.             fCd = TRUE;
  212.         }
  213.     }
  214.     sz += filer->szMask;
  215.     if (fCd) {
  216.         sz = "[" + sz;
  217.         sz += "]";
  218.     }
  219.     SetWindowText(_textFiler->hwndbase,"WZ Filer - " + sz);
  220. }
  221.  
  222. static void DoCaption(void)
  223. {
  224.     filerDoCaption(filerGetFocus());
  225. }
  226.  
  227. static BOOL filerIsSelected(FILER* filer)
  228. {
  229.     return (filer->nSel + filer->nSelDir);
  230. }
  231.  
  232. static void filerChdir(FILER* filer)
  233. {
  234. // ドライブを変更したときに、以前に表示したパスが表示されるように、
  235. // 現在のszPathをカレントディレクトリにセットするための関数。
  236. // Windowsはプロセス毎にカレントディレクトリが保持されるから、これで良いだろう。
  237.     my_chdir(filer->szPath);
  238.     DoCaption();
  239. }
  240.  
  241. //##WinFile
  242.  
  243. #ifndef __FLAT__
  244.  
  245. #include "appctrl.h"
  246. static BOOL _fWinFileAlready;
  247.  
  248. HWND winfileOpen(void)
  249. {
  250. // ファイルマネージャを起動
  251.     static mchar szclass[] = "WFS_Frame";
  252.     _fWinFileAlready = FALSE;
  253.     HWND hwnd = FindWindow(szclass,0);
  254.     if (hwnd) {    // すでに起動している
  255.         _fWinFileAlready = TRUE;
  256.         return hwnd;
  257.     }
  258.     if (WinExec("winfile.exe",SW_HIDE) < 32) return NULL;
  259. //    if (WinExec("winfile.exe",SW_SHOW) < 32) return NULL;
  260.     hwnd = FindWindow(szclass,0);
  261.     return hwnd;
  262. }
  263.  
  264. void winfileClose(HWND hwnd)
  265. {
  266.     if (!_fWinFileAlready) PostMessage(hwnd,WM_CLOSE,0,0);
  267. }
  268.  
  269. static BOOL WaitWindowOpen(mchar* szcaption,mchar* szcaption2)
  270. {
  271. // szcaptionまたはszcaption2の窓が開くのを待つ。最大3秒待つ
  272.     DWORD msWait = 0;
  273.     while (1) {
  274.         if (apSearchWindow(szcaption)) break;
  275.         if (szcaption2 && apSearchWindow(szcaption2)) break;
  276.         sleep(100);
  277.         msWait += 100;
  278.         if (msWait > 3000) return FALSE;
  279.     }
  280.     return TRUE;
  281. }
  282.  
  283. static BOOL WaitWindowClose(mchar* szcaption,mchar* szcaption2)
  284. {
  285. // szcaptionの窓が閉じるのを待つ
  286.     while (1) {
  287.         if (apSearchWindow(szcaption)) {
  288.             // Exist
  289.         } else if (szcaption2 && apSearchWindow(szcaption2)) {
  290.             // Exist
  291.         } else {
  292.             break;
  293.         }
  294.         sleep(800);
  295.     }
  296.     return TRUE;
  297. }
  298.  
  299. #endif
  300.  
  301. static BOOL CommandWinFile(mchar* szcaption,WPARAM wParam)
  302. {
  303. #ifdef __FLAT__
  304.     return FALSE;
  305. #else
  306.     BOOL ret = FALSE;
  307.     HWND hwnd = winfileOpen();
  308.     if (hwnd) {
  309.         sleep(500);
  310.         PostMessage(hwnd,WM_COMMAND,wParam,0);
  311.         if (WaitWindowOpen(szcaption,NULL)) {
  312.             WaitWindowClose(szcaption,NULL);
  313.             ret = TRUE;
  314.         }
  315.         winfileClose(hwnd);
  316.     }
  317.     return ret;
  318. #endif
  319. }
  320.  
  321. static BOOL availableWinFile(void)
  322. {
  323. #ifdef __FLAT__
  324.     attention("32bit版では実行できません");
  325.     return FALSE;
  326. #else
  327.     DWORD version = GetVersion();
  328.     BYTE major = LOBYTE(LOWORD(version));
  329.     BYTE minor = HIBYTE(LOWORD(version));
  330.     if (major == 3 && minor <= 11) return TRUE;
  331.     attention("この環境では実行できません");
  332.     return FALSE;
  333. #endif
  334. }
  335.  
  336. //FWINDEV のVBの会議室では、複数ディスクの連続フォーマットで監視が落
  337. //ちるので、 GetLastActivePopup を使う必要があるようなことを書いてあっ
  338. //たが、特に必要ないみたい。
  339. DiskFormat
  340. {
  341. // ディスクのフォーマット
  342.     if (!availableWinFile()) return FALSE;
  343.     return CommandWinFile("フロッピー ディスクのフォーマット",203);
  344. }
  345.  
  346. DiskCopy
  347. {
  348. // ディスクコピー
  349.     if (!availableWinFile()) return FALSE;
  350.     return CommandWinFile("フロッピー ディスクのコピー",201);
  351. }
  352.  
  353. // Windowsの供給元によって関連づけが違うみたい。
  354. Associate
  355. {
  356. // 関連づけ
  357.     if (!availableWinFile()) return FALSE;
  358. #ifndef __FLAT__
  359.     mchar* szcaption = "関連付けるプログラムの設定";
  360.     mchar* szcaption2 = "関連付けるアプリケーションの設定";
  361.     HWND hwnd = winfileOpen();
  362.     if (hwnd) {
  363.         sleep(500);
  364.         PostMessage(hwnd,WM_COMMAND,103,0);  // 関連づけ
  365.         if (WaitWindowOpen(szcaption,szcaption2)) {
  366.             mchar szfilename[CCHFILENAME];
  367.             filerGetCurFilename(filerGetFocus(),szfilename);
  368.             mchar* szext = pathGetExt(szfilename);
  369.             if (szext[0] && szext[1]) {
  370.                 apPostStr(&szext[1]);
  371.             }
  372.             WaitWindowClose(szcaption,szcaption2);
  373.         }
  374.         winfileClose(hwnd);
  375.     }
  376. #endif
  377. }
  378.  
  379. //## info window
  380.  
  381. static txstr _szClassInfo;
  382. static const int cygapInfo = 2;
  383.  
  384. static void numstrcomma(long num,mchar szstr[20])
  385. {
  386. // numをカンマつきで13桁でszstrに文字列としてセットします
  387.     mchar *dst = szstr;
  388.     BOOL f = FALSE;
  389.     UCHAR c;
  390.     
  391.     dst += 13;
  392.     c = num % 10;num /= 10;*--dst = c + '0';f = (!num);
  393.     if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
  394.     if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
  395.     if (!f) *--dst = ','; else *--dst = ' ';
  396.     if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
  397.     if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
  398.     if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
  399.     if (!f) *--dst = ','; else *--dst = ' ';
  400.     if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
  401.     if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
  402.     if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
  403.     if (!f) *--dst = ','; else *--dst = ' ';
  404.     if (!f) {c = num % 10;num /= 10;*--dst = c + '0';f = (!num);} else *--dst = ' ';
  405.     dst += 13;
  406.     *dst = 0;
  407. }
  408.  
  409. static void infoSprint(FILER* filer,mchar szdst[80])
  410. {
  411.     mchar szsize[20];
  412.     if (filer->nSel + filer->nSelDir) {
  413.         numstrcomma(
  414.             (filer->cbSel / 1024) + (filer->cbSel % 1024 > 0),
  415.             szsize
  416.         );
  417.         sprintf(szdst," %dfiles %sKB total ",filer->nSel+filer->nSelDir,strGetWordTop(szsize));
  418.     } else {
  419.         numstrcomma(filer->cbDiskFree / 1024,szsize);
  420.         sprintf(szdst," %dfiles %sKB free ",filer->nFile + filer->nDir,strGetWordTop(szsize));
  421.     }
  422. }
  423.  
  424. static int infoGetCy(void)
  425. {
  426. #if 1//2.99B 970322 
  427.     return systemfontGetCy() + cygapInfo * 2;
  428. #else
  429.     TEXTMETRIC tm;
  430.     HDC hdc = GetDC(text->hwndbase);
  431.     SelectObject(hdc,GetStockObject(GetSystemFontNo()));
  432.     GetTextMetrics(hdc,&tm);
  433.     ReleaseDC(text->hwndbase,hdc);
  434. //    return tm.tmAveCharWidth;//cxSysChar
  435.     return tm.tmHeight + cygapInfo * 2;
  436. #endif
  437. }
  438.  
  439. LRESULT TXCALLBACK wndprocInfo(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  440. {
  441.     switch(message) {
  442.         case WM_PAINT: {
  443.             RECT r;
  444.             GetClientRect(hwnd,&r);
  445.             int cx = rectCx(&r);
  446.             int cy = rectCy(&r);
  447.             //
  448.             PAINTSTRUCT ps;
  449.             HDC hdc = BeginPaint(hwnd,&ps);
  450.             HFONT hfont0 = NULL;
  451.             HPEN hpen0 = NULL;
  452.             HBRUSH hbrush0 = NULL;
  453.             //
  454.             FILER *filer = filer1;
  455.             if (hwnd == filer2->hwndInfo) filer = filer2;
  456.             //
  457.             if (_fwin40) {
  458.                 hpen0 = SelectObject(hdc,text1->hpenBtnFace);
  459.             } else {
  460.                 hpen0 = SelectObject(hdc,text1->hpenWindowFrame);
  461.             }
  462.             hbrush0 = SelectObject(hdc,text1->hbrushBtnFace);
  463.             Rectangle(hdc,-1,-1,cx + 1,cy);
  464.             //
  465.             hfont0 = SelectObject(hdc,GetStockObject(GetSystemFontNo()));
  466.             SetTextColor(hdc,GetSysColor(COLOR_BTNTEXT));
  467.             SetBkColor(hdc,GetSysColor(COLOR_BTNFACE));
  468.             {
  469.                 txstr sz;
  470.                 sz += " ";
  471.                 sz += filer->szPath;
  472.                 pathSetFileName(sz,NULL);
  473.                 sz += filer->szMask;
  474.                 TextOut(hdc,0,2,sz,strlen(sz));
  475.                 //
  476.                 mchar szbuff[80];
  477.                 infoSprint(filer,szbuff);
  478.                 SIZE size;
  479.                 GetTextExtentPoint(hdc,szbuff,strlen(szbuff),&size);
  480.                 TextOut(hdc,cx - size.cx - 1,cygapInfo,szbuff,strlen(szbuff));
  481.             }
  482.             if (hfont0) SelectObject(hdc,hfont0);
  483.             if (hbrush0) SelectObject(hdc,hbrush0);
  484.             if (hpen0) SelectObject(hdc,hpen0);
  485.             EndPaint(hwnd,&ps);
  486.             return 0;
  487.         }
  488.     }
  489.     return DefWindowProc(hwnd,message,wParam,lParam);
  490. }
  491.  
  492. static void filerDispInfo(FILER *filer)
  493. {
  494.     InvalidateRect(filer->hwndInfo,NULL,FALSE);
  495.     SendMessage(filer->hwndInfo,WM_PAINT,0,0);
  496. }
  497.  
  498. //##fileratr
  499.  
  500. static FILERATR _fileratr;
  501.  
  502. #define FILER_OFFSETBASE    (FILER_LCXMASK + 1)
  503.  
  504. #define ID_FILENAME            1
  505. #define ID_FILEEXT            2
  506. #define ID_FILEDATE            3
  507. #define ID_FILESIZE            5
  508. #define ID_FILEDIRECTORY    7
  509.  
  510. //                          ファイル名 拡張子  日付   サイズ   ディレクトリ
  511. static BOOL _fbacksort[]={0, 0,     0,      1, 0,  1, 0,  1,};
  512. static int _size[] =     {0, 8,     3,     14,14, 13,13,  5,};
  513. //
  514. static int _offset[] =   {0, 0,     9,     28,28, 13,13, 21,};
  515. static int _offsetsort[]={0, 0,     0,     28,28, 13,13, 21,};
  516. static int _sizesort[]=  {0,12,    12,     14,14, 13,13,  5,};
  517.  
  518. static void fileratrInit(void)
  519. {
  520.     _fileratr.fLong = p_fLong;
  521.     _fileratr.szexts = p_szBinExt;
  522.     if (_fileratr.fLong) {
  523.         _fileratr.iFileName = FILER_OFFSETBASE + 28;
  524.         _fileratr.lchLine = FILER_LCXMASK + CCHPATHNAME + 32;
  525.         _size[ID_FILENAME] = _size[ID_FILEEXT] = CCHPATHNAME;
  526.     } else {
  527.         _fileratr.iFileName = FILER_OFFSETBASE;
  528.         _fileratr.lchLine = FILER_LCXMASK + 44;
  529.         _size[ID_FILENAME] = 8;
  530.         _size[ID_FILEEXT] = 3;
  531.     }
  532.     {
  533.         _offset[ID_FILENAME] = 0;
  534.         if (_fileratr.fLong) {
  535.             _offset[ID_FILEDATE]  = _offset[ID_FILEDATE+1] = 0;
  536.             _offset[ID_FILESIZE]  = _offset[ID_FILESIZE+1] = _offset[ID_FILEDATE] + _size[ID_FILEDATE] + 1;
  537.             _offset[ID_FILEDIRECTORY]  = _offset[ID_FILESIZE] + 8;
  538.             _offset[ID_FILEEXT] = _offset[ID_FILENAME] = _offset[ID_FILESIZE] + _size[ID_FILESIZE];
  539.         } else {
  540.             _offset[ID_FILEEXT] = _size[ID_FILENAME] + 1;
  541.             _offset[ID_FILESIZE]  = _offset[ID_FILESIZE+1] = _offset[ID_FILEEXT] + _size[ID_FILEEXT] + 1;
  542.             _offset[ID_FILEDATE]  = _offset[ID_FILEDATE+1] = _offset[ID_FILESIZE] + _size[ID_FILESIZE] + 2;
  543.             _offset[ID_FILEDIRECTORY]  = _offset[ID_FILESIZE] + 8;
  544.         }
  545.         //
  546.         memcpy(_offsetsort,_offset,sizeof(_offsetsort));
  547.         _offsetsort[ID_FILEEXT] = _offsetsort[ID_FILENAME];
  548.         //
  549.         memcpy(_sizesort,_size,sizeof(_sizesort));
  550.         if (!_fileratr.fLong) {
  551.             _sizesort[ID_FILEEXT] = _sizesort[ID_FILENAME] = _size[ID_FILENAME] + 1 + _size[ID_FILEEXT];
  552.         }
  553.     }
  554. #if 0
  555. {
  556.     int i;
  557.     for (i = ID_FILENAME;i <= ID_FILEDIRECTORY;i++) {
  558.         information("%d",_offsetsort[i]);
  559.     }
  560. }
  561. #endif
  562. }
  563.  
  564. //##sort
  565.  
  566. static mchar* filenameGetExt(mchar* szfilename)
  567. {
  568. // ファイル名から拡張子のポインタを返す。
  569. // 拡張子がなければ、NULLを返す
  570. // 汎用のpathGetExtは遅いので、その代わり
  571.     mchar* p0 = NULL;
  572.     mchar* p = szfilename;
  573.     while(1) {
  574.         mchar* p1 = strchr(p,'.');
  575.         if (!p1) {
  576.             if (p0) return p0;
  577.             return p + strlen(p);
  578.         }
  579.         p0 = p1;
  580.         p = p1 + 1;
  581.     }
  582. }
  583.  
  584. // 拡張子でのソート時に、ファイル名でもソートする
  585. // WZ32ではファイル名が小文字で表示されることもあるので、
  586. // 大小文字を区別しないでソートする
  587. int cmpkey(mchar* pstr1,mchar* pstr2,int size,LPARAM lCust)
  588. {
  589.     if (_fileratr.fLong) {
  590.         mchar* szext1 = filenameGetExt(pstr1);
  591.         mchar* szext2 = filenameGetExt(pstr2);
  592.         int ret = stricmp(szext1,szext2);
  593.         if (ret != 0) return ret;
  594.         // ファイル名でソート
  595.         // pstr内を書き換えるとまずい
  596.         int len1 = szext1 - pstr1;
  597.         int len2 = szext2 - pstr2;
  598.         int len = len1;
  599.         if (len > len2) len = len2;
  600.         ret = strnicmp(pstr1,pstr2,len);
  601.         if (ret != 0) return ret;
  602.         return len1 - len2;
  603.     } else {
  604.         int ret = strnicmp(
  605.             pstr1 + _offset[ID_FILEEXT],
  606.             pstr2 + _offset[ID_FILEEXT],
  607.             _size[ID_FILEEXT]
  608.         );
  609.         if (ret != 0) return ret;
  610.         return strnicmp(
  611.             pstr1,
  612.             pstr2,
  613.             _size[ID_FILENAME]
  614.         );
  615.     }
  616. }
  617.  
  618. //1.00F ソートオプションを2つまで指定できる
  619. int cmpkey2(mchar* pstr1,mchar* pstr2,int size,LPARAM lCust)
  620. {
  621.     FILER *filer = (FILER*)lCust;
  622.     int ret;
  623.     
  624.     // key1
  625.     if (filer->modeSort) {
  626.         if (_fileratr.fLong && filer->modeSort == ID_FILEEXT) {
  627.             int off = _offset[ID_FILEEXT];
  628.             ret = stricmp(filenameGetExt(pstr1+off),filenameGetExt(pstr2+off));
  629.         } else {
  630.             ret = strnicmp(
  631.                 pstr1 + _offset[filer->modeSort],
  632.                 pstr2 + _offset[filer->modeSort],
  633.                 _size[filer->modeSort]
  634.             );
  635.         }
  636.         if (ret != 0) {
  637.             if (_fbacksort[filer->modeSort]) return -ret;//1.00H 
  638.             return ret;
  639.         }
  640.     }
  641.     // key2
  642.     if (_fileratr.fLong && filer->modeSort2 == ID_FILEEXT) {
  643.         int off = _offset[ID_FILEEXT];
  644.         ret = stricmp(filenameGetExt(pstr1+off),filenameGetExt(pstr2+off));
  645.     } else {
  646.         ret = strnicmp(
  647.             pstr1 + _offset[filer->modeSort2],
  648.             pstr2 + _offset[filer->modeSort2],
  649.             _size[filer->modeSort2]
  650.         );
  651.     }
  652.     if (_fbacksort[filer->modeSort2]) return -ret;
  653.     return ret;
  654. }
  655.  
  656. static void _filerSort(FILER *filer)
  657. {
  658.     // modeSortが変な値のときアプリケーションエラーになる
  659.     if (filer->modeSort > SORT_N) filer->modeSort = SORT_N;
  660.     if (filer->modeSort2 > SORT_N) filer->modeSort2 = SORT_N;
  661.     //
  662.     TX* text = filer->text;
  663.     int address = txGetAddress(text);
  664.     SORTARG arg;
  665.     //
  666.     text->fUndisp++;
  667.     txJumpFileEnd(text);
  668.     text->fEditable = TRUE;
  669.     //
  670.     memset(&arg,0,sizeof(arg));
  671.     arg.sizeStruct = sizeof(SORTARG);
  672.     arg.lchLine = _fileratr.lchLine;
  673.     arg.fNoSenseCase = TRUE;
  674.     //
  675.     if (filer->nDir) {
  676.         txJumpFileTop(text);
  677.         if (
  678.             txGetCharX(text,_fileratr.iFileName) == '.' &&
  679.             txGetCharX(text,_fileratr.iFileName + 1) == '.'//2.99B 970322 
  680.         ) {
  681.             // ".."はソートしない
  682.             arg.lineTop = 2;
  683.         } else {
  684.             arg.lineTop = 1;
  685.         }
  686.         arg.lineEnd = 1 + filer->nDir - 1;
  687.         // ディレクトリは必ず名前順でソートする
  688.         arg.iItem = FILER_OFFSETBASE + _offsetsort[ID_FILENAME];
  689.         arg.lchItem = _sizesort[ID_FILENAME];
  690.         arg.fBack = FALSE;
  691. //information("%d %d %d",arg.lchLine,arg.iItem,arg.lchItem);
  692.         txSort(text,&arg);
  693.     }
  694.     arg.lineTop = 1 + filer->nDir;
  695.     arg.lineEnd = arg.lineTop + filer->nFile - 1;
  696.     if (filer->modeSort2 && filer->modeSort2 != filer->modeSort) {
  697.         // ソートオプションを2つ指定できるようにした
  698.         arg.iItem = FILER_OFFSETBASE;
  699.         arg.lchItem = _fileratr.lchLine ? (_fileratr.lchLine - 1 - arg.iItem) : 0;
  700.         arg.fBack = FALSE;
  701.         PMACROFUNC pfunc;
  702.         macroGetFuncAddress("cmpkey2",&pfunc);
  703.         arg.pfuncCmpKey = &pfunc;
  704.         arg.lCust = (LPARAM)filer;
  705.         txSort(text,&arg);
  706.         arg.pfuncCmpKey = NULL;
  707.     } else {
  708.         arg.iItem = FILER_OFFSETBASE + _offsetsort[filer->modeSort];
  709.         arg.lchItem = _sizesort[filer->modeSort];
  710.         arg.fBack = _fbacksort[filer->modeSort];
  711.         if (filer->modeSort == ID_FILEEXT) {
  712.             PMACROFUNC pfunc;
  713.             macroGetFuncAddress("cmpkey",&pfunc);
  714.             arg.pfuncCmpKey = &pfunc;
  715.             txSort(text,&arg);
  716.             arg.pfuncCmpKey = NULL;
  717.         } else {
  718.             txSort(text,&arg);
  719.         }
  720.     }
  721.     //
  722.     text->fEditable = FALSE;
  723.     text->fUndisp--;
  724.     txJumpAddress(text,address);
  725. }
  726.  
  727. static void filerSort(FILER *filer)
  728. {
  729.     tx *text = filer->text;
  730.     if (filer->modeSort || filer->modeSort2) {
  731.         _filerSort(filer);
  732.         txJumpPara(text,filer->nDir + 1);
  733.         txSetLy(text,filer->nDir + 1);
  734.     }
  735. }
  736.  
  737. //##load
  738.  
  739. static void filerClearSel(FILER* filer)
  740. {
  741.     filer->nFile = filer->nDir = filer->nSel = filer->nSelDir = 0;
  742.     filer->cbSel = 0;
  743. }
  744.  
  745. static int filerAddPath(FILER* filer,mchar* szpath)
  746. {
  747. // filerのカーソル位置にszpathのファイルを検索して挿入
  748. // 挿入したファイル数を返す。
  749. // カーソル位置は変化しない。
  750. // 表示は更新しない。
  751.     int ret = 0;
  752.     TX* text = filer->text;
  753.     NPARA npara = text->npara;
  754.     text->fUndisp++;
  755.         txJumpParaTop(text);
  756.         text->fEditable = TRUE;
  757.         _fileratr.fld = FLD_FILE | FLD_HIDDEN;
  758.         ret = _filerLoadDisk(text,szpath,&_fileratr);
  759.         if (ret) {
  760.             filer->nFile += ret;
  761.             filer->nDirFile += ret;
  762.             filerSort(filer);
  763.         }
  764.         txJumpNpara(text,npara);
  765.         text->fEditable = FALSE;
  766.         txJumpNpara(text,npara);
  767.     text->fUndisp--;
  768.     filerDispInfo(filer);
  769.     return ret;
  770. }
  771.  
  772. #define FLP_NOMOVE        0
  773. #define FLP_JUMPDIRTOP    1
  774. #define FLP_JUMPFILETOP    2
  775.  
  776. static void filerLoadPath(FILER* filer,BOOL flpMode)
  777. {
  778.     TX* text = filer->text;
  779.     BOOL fNeedLoadDir = TRUE;
  780.     NPARA npara = text->npara;
  781.     int ly = text->ly;
  782.     
  783.     filerClearSel(filer);
  784.     text->fEditable = TRUE;
  785.     text->fUndisp++;
  786.     txDeleteText(text);
  787.     {
  788.         mchar *p = filer->szMask;
  789.         if (!p[0]) p = "*.*";
  790.         WORD fld = FLD_NORMAL | FLD_HIDDEN;
  791.         if (filer->modeSort) fld = FLD_FILE;
  792.         if (!p_fDispGene) fld |= FLD_NOUNDO;
  793.         while(*p) {
  794.             mchar* p1;
  795.             while(1) {
  796.                 p1 = strchrs(p,"; ");
  797.                 if (!p1) {
  798.                     p1 = p + strlen(p);
  799.                     break;
  800.                 }
  801.                 if (p1 != p) break;
  802.                 p++;
  803.             }
  804.             mchar szmask[CCHWORD];
  805.             if (*p == '.') {
  806.                 // '*'を追加
  807.                 szmask[0] = '*';
  808.                 strcpylenmax(szmask+1,p,p1 - p,cchof(szmask)-1);
  809.             } else {
  810.                 sstrcpylen(szmask,p,p1 - p);
  811.             }
  812.             p = p1;
  813.             //
  814.             if (!filer->modeSort && !strcmp(szmask,"*.*")) fNeedLoadDir = FALSE;
  815.             pathSetFileName(filer->szPath,szmask);
  816.             _fileratr.fld = fld;
  817. //information("%s %s",szmask,filer->szPath);
  818.             filer->nFile += _filerLoadDisk(text,filer->szPath,&_fileratr);
  819.         }
  820.     }
  821.     if (_fileratr.fLong) {
  822.         // 少なくともiFileName+1まで有功文字を入れておかないと、
  823.         // アプリエラーになる。
  824.         txInsert(text," 5  (End)                                     ");
  825.     } else {
  826.         txInsert(text," 5  -------------- <End of Dir> --------------");
  827.     }
  828.     txJumpFileTop(text);
  829.     DoCaption();
  830.     //
  831.     if (fNeedLoadDir) {
  832.         _fileratr.fld = FLD_DIR | FLD_HIDDEN;
  833.         if (!p_fDispGene) _fileratr.fld |= FLD_NOUNDO;
  834.         filer->nDir = _filerLoadDisk(text,filer->szPath,&_fileratr);
  835.         if (flpMode) {
  836.             if (filer->nFile == 0 || flpMode == FLP_JUMPDIRTOP) {
  837.                 txJumpFileTop(text);
  838.             } else {
  839.                 txJumpPara(text,filer->nDir + 1);
  840.             }
  841.         }
  842.     } else {
  843.         if (flpMode) {
  844.             txJumpFileTop(text);
  845.         }
  846.     }
  847.     filer->nDirFile = filer->nFile + filer->nDir;
  848.     filerSort(filer);
  849.     //
  850.     filer->cbDiskFree = driveGetFree(filer->szPath[0]);
  851.     //
  852.     if (flpMode == 0) {
  853.         txJumpNpara(text,npara);
  854.         txSetLy(text,ly);
  855.     }
  856.     //
  857.     text->fUndisp--;
  858.     text->fEdit = FALSE;
  859.     text->fEditable = FALSE;
  860.     txDispAll(text);
  861.     filerDispInfo(filer);
  862.     previewFlush();//3.00A3 970508 パスを変えたときにプレビューを更新
  863. }
  864.  
  865. static void filerSetFocus(FILER* filer)
  866. {
  867.     SetFocus(filer->text->hwndtext);
  868. }
  869.  
  870. static void filerInitPath(FILER* filer)
  871. {
  872. // カレントフォルダに初期化
  873.     driveGetCurDir(0,filer->szPath);
  874.     pathSetDir(filer->szPath);
  875.     strcpy(filer->szMask,"*.*");
  876. }
  877.  
  878. //## path
  879.  
  880. static void _filerSetPath(FILER* filer,mchar *szpath,BOOL fcd)
  881. {
  882. // fcd:カレントディレクトリを見る?
  883.     if (szpath) {
  884.         if (pathGetFull(szpath)) {
  885.             strcpy(filer->szPath,szpath);
  886.         } else {
  887.             txstr sz = filer->szPath;
  888.             int drive = 0;
  889.             
  890.             if (isalpha(szpath[0]) && szpath[1] == ':') {    // ドライブ名付き
  891.                 drive = szpath[0];
  892.                 szpath += 2;
  893.             }
  894.             if (drive == 0 && !fcd) {
  895.                 pathSetFileName(sz,"");
  896.                 pathFormDir(sz);
  897.             } else {
  898.                 driveGetCurDir(drive,sz);
  899.                 pathFormDir(sz);
  900.             }
  901.             if (szpath[0] == '\\') {
  902.                 sz[2] = 0;
  903.                 sz += szpath;
  904.             } else {
  905.                 sz += "\\";
  906.                 sz += szpath;
  907.             }
  908.             //
  909.             sstrcpy(filer->szPath,sz);
  910.         }
  911.         if (!strchr(filer->szPath,'*') && !strchr(filer->szPath,'?')) {
  912.             if (pathIsDirectory(filer->szPath)) {
  913.                 txstr sz = filer->szPath;
  914.                 pathFormDir(sz);
  915.                 sz += "\\";
  916.                 sz += filer->szMask;
  917.                 //
  918.                 sstrcpy(filer->szPath,sz);
  919.             }
  920.         }
  921.         sstrcpy(filer->szMask,pathGetFileName(filer->szPath));
  922.         if (!filer->szMask[0]) strcpy(filer->szMask,"*.*");
  923. #ifndef __FLAT__
  924.         if (filer->text->fDispPathLc) {
  925.             strlwr(filer->szPath);
  926.             strlwr(filer->szMask);
  927.         } else {
  928.             strupr(filer->szPath);
  929.             strupr(filer->szMask);
  930.         }
  931. #endif
  932.     }
  933. }
  934.  
  935. static void filerSetPath(FILER* filer,mchar *szpath)
  936. {
  937.     mchar *name = pathGetFileName(szpath);
  938.     
  939.     if (name == szpath) {    // ファイル名のみ
  940.         _filerSetPath(filer,szpath,FALSE);
  941.     } else {
  942.         _filerSetPath(filer,szpath,TRUE);
  943.     }
  944.     filerLoadPath(filer,FLP_JUMPFILETOP);
  945.     filerDispInfo(filer);
  946. }
  947.  
  948. static BOOL filerIsCurDirFile(FILER* filer)
  949. {
  950. // ".."の場合はFALSEを返す。
  951.     TX* text = filer->text;
  952.     // "."で始まるディレクトリは誤動作防止のため、ディレクトリ名とはみなさない
  953.     // ".."をディレクトリとみなすと、削除やコピーで、意外なディレクトリを削除したりコピーした。
  954.     if (txGetCharX(text,_fileratr.iFileName) == '.') {
  955. #if 1//2.99B 970322 "."で始まるファイルが開けなかった
  956.         mchar c = txGetCharX(text,_fileratr.iFileName+1);
  957.         if (c == 0) return FALSE;
  958.         if (c == '.') {
  959.             mchar c = txGetCharX(text,_fileratr.iFileName+2);
  960.             if (
  961.                 c == 0 ||
  962.                 ispathsepa(c)    //3.00A 970502 WZ16 Filerで"..\"を削除できてしまっていた
  963.             ) return FALSE;
  964.         }
  965. #else
  966.         return FALSE;
  967. #endif
  968.     }
  969.     //
  970.     return (text->npara <= filer->nDirFile);
  971. }
  972.  
  973. static BOOL filerIsCurDir(FILER* filer)
  974. {
  975. // ".."の場合もTRUEを返す。
  976.     return (txGetCharX(filer->text,FILER_IDIRECTORY) == FATR_DIR);
  977. }
  978.  
  979. static BOOL filerIsCurFile(FILER* filer)
  980. {
  981. // カーソル位置のファイルがディレクトリでなく、ファイルの場合にTRUEを返す
  982. //2.99 970318 new
  983.     return (!filerIsCurDir(filer) && filerIsCurDirFile(filer));
  984. }
  985.  
  986. static DWORD filerGetCurFileSize(FILER* filer)
  987. {
  988.     TX* text = filer->text;
  989.     IBUFF off = FILER_OFFSETBASE + _offset[ID_FILESIZE];
  990.     int len = _size[ID_FILESIZE];
  991.     DWORD ret = 0;
  992.     while(len--) {
  993.         mchar c = txGetCharX(text,off++);
  994.         if (isdigit(c)) {
  995.             ret *= 10;
  996.             ret += c - '0';
  997.         } else {
  998.             // 3桁区切り用のカンマ等
  999.         }
  1000.     }
  1001.     return ret;
  1002. }
  1003.  
  1004. static void filerMarkAll(FILER* filer,int mode)
  1005. {
  1006.     TX* text = filer->text;
  1007.     txSetUndispEx(text);
  1008.     txSetHigh(text);
  1009.     txJumpFileTop(text);
  1010.     filer->cbSel = 0;
  1011.     do {
  1012. //statprintf("%d",text->npara);
  1013.         if (filerIsCurDirFile(filer)) {
  1014.             if (mode == TXLB_SELECT && filerIsCurDir(filer)) {
  1015.                 // ディレクトリはマークしない
  1016.             } else {
  1017.                 *txGetBuffX(text,0) = mode;
  1018.                 if (mode == TXLB_SELECT) filer->cbSel += filerGetCurFileSize(filer);
  1019.             }
  1020.         }
  1021.     } while(txNextPara(text));
  1022.     filer->nSel = filer->nSelDir = 0;
  1023.     if (mode == TXLB_SELECT) {
  1024.         filer->nSel = filer->nFile;
  1025.     }
  1026.     txResetHigh(text);
  1027.     txSetDispEx(text);
  1028. }
  1029.  
  1030. static void _filerCurSelectSet(FILER* filer)
  1031. {
  1032. // 表示は更新しない
  1033.     TX* text = filer->text;
  1034.     if (!filerIsCurDirFile(filer)) return;
  1035.     BYTE* buff = txGetBuffX(text,0);
  1036.     if (!buff) return;
  1037.     if (*buff == TXLB_NORMAL) {
  1038.         *buff = TXLB_SELECT;
  1039.         if (filerIsCurDir(filer)) {
  1040.             filer->nSelDir++;
  1041.         } else {
  1042.             filer->cbSel += filerGetCurFileSize(filer);
  1043.             filer->nSel++;
  1044.         }
  1045.     }
  1046. }
  1047.  
  1048. static void _filerCurSelectClear(FILER* filer)
  1049. {
  1050. // 表示は更新しない
  1051.     TX* text = filer->text;
  1052.     if (!filerIsCurDirFile(filer)) return;
  1053.     BYTE* buff = txGetBuffX(text,0);
  1054.     if (!buff) return;
  1055.     if (*buff == TXLB_SELECT) {
  1056.         *buff = TXLB_NORMAL;
  1057.         if (filerIsCurDir(filer)) {
  1058.             filer->nSelDir--;
  1059.         } else {
  1060.             filer->cbSel -= filerGetCurFileSize(filer);
  1061.             filer->nSel--;
  1062.         }
  1063.     }
  1064. }
  1065.  
  1066. static void _filerCurSelectReverse(FILER* filer)
  1067. {
  1068.     TX* text = filer->text;
  1069.     if (!filerIsCurDirFile(filer)) return;
  1070.     if (txGetCharX(text,0) == TXLB_SELECT) {
  1071.         _filerCurSelectClear(filer);
  1072.     } else {
  1073.         _filerCurSelectSet(filer);
  1074.     }
  1075. }
  1076.  
  1077. static void filerCurSelectReverse(FILER* filer)
  1078. {
  1079. // カーソル位置のファイルを選択
  1080. // 表示の更新も行う
  1081.     TX* text = filer->text;
  1082.     txJumpLineTop(text);
  1083.     _filerCurSelectReverse(filer);
  1084.     txDispText(text,text->ly,text->ly);
  1085.     filerDispInfo(filer);
  1086. }
  1087.  
  1088. //3.00A 970430 filer.sel復活
  1089. sel
  1090. {
  1091.     filerCurSelectReverse(filerGetFocus());
  1092. }
  1093.  
  1094. static void filerMarkClearAll(FILER* filer)
  1095. {
  1096.     filerMarkAll(filer,TXLB_NORMAL);
  1097.     filerDispInfo(filer);
  1098. }
  1099.  
  1100. static void filerMarkSetAll(FILER* filer)
  1101. {
  1102.     filerMarkAll(filer,TXLB_SELECT);
  1103.     filerDispInfo(filer);
  1104. }
  1105.  
  1106. //## cmd
  1107.  
  1108. // sztop[0]には' ',
  1109. // sztop[1]からファイラーのファイル名表示イメージのまま
  1110. // 検索文字列を渡して下さい。
  1111. static BOOL searchfile(TX* text,mchar *sztop)
  1112. {
  1113.     if (text->fHigh) {
  1114.         while(1) {
  1115.             if (!txSearchEx(text,sztop,SEARCH_NOSENSECASE)) return FALSE;
  1116.             IBUFF lx = txGetAddress(text) - txGetParaTop(text);
  1117.             if (lx == _fileratr.iFileName - 1) return TRUE;
  1118.         }
  1119.     } else {
  1120.         while(1) {
  1121.             if (!txSearchEx(text,sztop,SEARCH_NOSENSECASE)) return FALSE;
  1122.             if (text->lx == _fileratr.iFileName - 1) return TRUE;
  1123.         }
  1124.     }
  1125. }
  1126.  
  1127. compare
  1128. {
  1129. // フォルダの内容の比較
  1130.     if (!p_fDouble) {
  1131.         information("ダブルウィンドウモードで実行してください");
  1132.         return FALSE;
  1133.     }
  1134.     static BOOL fCmpExist = TRUE;
  1135.     static BOOL fCmpDate = TRUE;
  1136.     static BOOL fCmpOld = FALSE;
  1137.     static BOOL fCmpSize = FALSE;
  1138.     static BOOL fCmpSmall = FALSE;
  1139.     HDIALOG hd = dialog("ディレクトリの比較");
  1140.     dialogSetGroupRight(hd,35 * DTCX);
  1141.     dialogGroup(hd,"存在");
  1142.         dialogCheck(hd,"存在チェック(&E)",&fCmpExist);
  1143.     dialogGroupEnd(hd);
  1144.     dialogGroup(hd,"日付");
  1145.         dialogCheck(hd,"比較(&D)",&fCmpDate);
  1146.         dialogRadioIDI(hd,&fCmpOld,"新しい(&N)","古い(&O)");
  1147.     dialogGroupEnd(hd);
  1148.     dialogGroup(hd,"サイズ");
  1149.         dialogCheck(hd,"比較(&F)",&fCmpSize);
  1150.         dialogRadioIDI(hd,&fCmpSmall,"大きい(&L)","小さい(&S)");
  1151.     dialogGroupEnd(hd);
  1152.     if (dialogOpen(hd)) {
  1153.         BOOL fCmpNew = FALSE;
  1154.         BOOL fCmpBig = FALSE;
  1155.         if (fCmpDate) {
  1156.             fCmpNew = !fCmpOld;
  1157.         } else {
  1158.             fCmpOld = FALSE;
  1159.         }
  1160.         if (fCmpSize) {
  1161.             fCmpBig = !fCmpSmall;
  1162.         } else {
  1163.             fCmpSmall = FALSE;
  1164.         }
  1165.         FILER* filer = filerGetFocus();
  1166.         FILER* filer2 = filerGetOther(filer);
  1167.         TX* textf = filer->text;    // フォーカスのあるテキスト
  1168.         TX* textv = filer2->text;    // 相手先
  1169.         txSetUndispEx(textf);
  1170.         txSetUndispEx(textv);
  1171.         txSetHigh(textf);
  1172.         txSetHigh(textv);
  1173.         filerMarkClearAll(filer);
  1174.         filerMarkClearAll(filer2);
  1175.         txJumpFileTop(textf);
  1176.         do {
  1177.             if (!filerIsCurDir(filer) && filerIsCurDirFile(filer)) {
  1178.                 mchar *curf = textf->buff + textf->cur + FILER_OFFSETBASE;
  1179.                 mchar buff[CCHFILENAME];
  1180.                 buff[0] = ' ';
  1181.                 if (_fileratr.fLong) {
  1182.                     strcpy(buff+1,curf+_offset[ID_FILENAME]);
  1183.                 } else {
  1184.                     int size = _offset[ID_FILEEXT] + _size[ID_FILEEXT] - _offset[ID_FILENAME];
  1185.                     strcpylen(buff+1,curf+_offset[ID_FILENAME],size);
  1186.                 }
  1187.                 txJumpFileTop(textv);
  1188.                 if (searchfile(textv,buff)) {    // 相手先に、存在する
  1189.                     if (fCmpDate || fCmpSize) {// 比較オプションを[存在チェック]のみにした場合も、正しく動作するように
  1190.                         txJumpParaTop(textv);
  1191.                         mchar *curv = textv->buff + textv->cur + FILER_OFFSETBASE;
  1192.                         int cmpnew = memcmp(
  1193.                             curf + _offset[ID_FILEDATE],
  1194.                             curv + _offset[ID_FILEDATE],
  1195.                             _size[ID_FILEDATE]
  1196.                         );
  1197.                         int cmpbig = memcmp(
  1198.                             curf + _offset[ID_FILESIZE],
  1199.                             curv + _offset[ID_FILESIZE],
  1200.                             _size[ID_FILESIZE]
  1201.                         );
  1202.                         if (
  1203.                             (
  1204.                                 (!fCmpNew && !fCmpOld) ||    // 両方指定されてない
  1205.                                 (fCmpNew && cmpnew > 0) ||
  1206.                                 (fCmpOld && cmpnew < 0)
  1207.                             ) && 
  1208.                             (
  1209.                                 (!fCmpBig && !fCmpSmall) ||    // 両方指定されてない
  1210.                                 (fCmpBig && cmpbig > 0) ||
  1211.                                 (fCmpSmall && cmpbig < 0)
  1212.                             )
  1213.                         ) {
  1214.                             _filerCurSelectSet(filer);
  1215.                         }
  1216.                     }
  1217.                 } else {
  1218.                     if (fCmpExist) {
  1219.                         _filerCurSelectSet(filer);
  1220.                     }
  1221.                 }
  1222.             }
  1223.         } while(txNextPara(textf));
  1224.         txResetHigh(textf);
  1225.         txResetHigh(textv);
  1226.         txSetDispEx(textf);
  1227.         txSetDispEx(textv);
  1228.         filerDispInfo(filer);
  1229.         filerDispInfo(filer2);
  1230.     }
  1231.     return TRUE;
  1232. }
  1233.  
  1234. sup
  1235. {
  1236. // 上移動して選択
  1237.     txUp(text);
  1238.     filerCurSelectReverse(filerGetFocus());
  1239. }
  1240.  
  1241. sdown
  1242. {
  1243. // 選択して下移動
  1244.     filerCurSelectReverse(filerGetFocus());
  1245.     txDown(text);
  1246. }
  1247.  
  1248. SwitchDouble
  1249. {
  1250. // ダブルウィンドウ/シングルウィンドウ切り替え
  1251.     HWND hwnd = text->hwndbase;
  1252.     if (IsZoomed(hwnd) || IsIconic(hwnd)) {
  1253.         // シングルウィンドウの状態で[最大表示]の時に、おかしな表示にならない様に
  1254.         ShowWindow(hwnd,SW_SHOWNORMAL);
  1255.     }
  1256.     //
  1257.     p_fDouble ^= 1;
  1258.     //
  1259.     RECT r;
  1260.     GetWindowRect(hwnd,&r);
  1261.     if (p_fDoubleSize) {
  1262.         int cx = rectCx(&r);
  1263.         int cy = rectCy(&r);
  1264.         if (p_fDouble) {
  1265.             p_fDoubleH ? (cy *= 2) : (cx *= 2);
  1266.         } else {
  1267.             p_fDoubleH ? (cy /= 2) : (cx /= 2);
  1268.         }
  1269.         MoveWindow(hwnd,r.left,r.top,cx,cy,TRUE);
  1270.     }
  1271.     if (p_fDouble) {
  1272.         filerLoadPath(filer2,FLP_JUMPFILETOP);
  1273.     }
  1274.     SendMessage(text->hwndbase,WM_TXFLUSHWINDOWSIZE,0,0);
  1275.     if (p_fDouble) {
  1276.         filerSetFocus(filer2);
  1277.     } else {
  1278.         filerSetFocus(filer1);
  1279.         filerClearSel(filer2);// 選択をクリア
  1280.     }
  1281.     previewFlush();//3.00A3 970508 ダブルウィンドウON/OFF時にプレビューを更新
  1282.     return TRUE;
  1283. }
  1284.  
  1285. SwitchWindow
  1286. {
  1287. // ダブルウィンドウ時のウィンドウの切り替え
  1288.     if (p_fDouble) {
  1289.         filerSetFocus(filerGetFocus() == filer1 ? filer2 : filer1);
  1290.         previewFlush();//3.00A3 970508 ダブルウィンドウ時のウィンドウの切り替えでプレビューをフラッシュするようにした
  1291.         return TRUE;
  1292.     }
  1293.     return FALSE;
  1294. }
  1295.  
  1296. uiAbout
  1297. {
  1298.     ABOUTINFO info;
  1299.     structClear(info);
  1300.     info.szicon = "iconWzFiler";
  1301.     info.szappname = "WZ Filer for Windows";
  1302.     info.szversion = "version " + VER_WZFILER;
  1303.     info.szcopyright = "Copyright(c)1995-97 TY";
  1304.     info.szcopyright2 = "programed by TX-C";
  1305.     about(&info);
  1306. }
  1307.  
  1308. uiSetPath
  1309. {
  1310. // パスの入力
  1311.     static txstr szpath;
  1312.     HDIALOG hd = dialog("パス・マスク");
  1313.     
  1314.     dialogControlHist(hd,HIST_PATH);
  1315.     dialogStr(hd,"パス・マスク(&P):",szpath,12,40);
  1316.     
  1317.     if (dialogOpen(hd)) {
  1318.         if (szpath == "") {
  1319.             call("menu.FILERパスリスト");
  1320.         } else {
  1321.             FILER* filer = filerGetFocus();
  1322.             filerChdir(filer);
  1323.             filerSetPath(filer,szpath);
  1324.         }
  1325.     }
  1326. }
  1327.  
  1328. void markClearAll(void)
  1329. {
  1330.     filerMarkClearAll(filerGetFocus());
  1331. }
  1332.  
  1333. markAll
  1334. {
  1335.     filerMarkSetAll(filerGetFocus());
  1336. }
  1337.  
  1338. markReverseAll
  1339. {
  1340. // 選択/非選択入れ替え
  1341.     FILER* filer = filerGetFocus();
  1342.     TX* text = filer->text;
  1343.     txSetUndispEx(text);
  1344.     txSetHigh(text);
  1345.     txJumpFileTop(text);
  1346.     do {
  1347.         if (filerIsCurDirFile(filer)) {
  1348.             if (!filerIsCurDir(filer)) _filerCurSelectReverse(filer);
  1349.         }
  1350.     } while(txNextPara(text));
  1351.     txResetHigh(text);
  1352.     txSetDispEx(text);
  1353.     filerDispInfo(filer);
  1354. }
  1355.  
  1356. close
  1357. {
  1358.     txQuit(_textFiler);
  1359. }
  1360.  
  1361. //## filer cmd
  1362.  
  1363. #define CCHARG    32000
  1364.  
  1365. static void filerGetCurFilename(FILER *filer,mchar szfilename[CCHFILENAME])
  1366. {
  1367. // ".."の場合はNULLを返す。
  1368.     TX* text = filer->text;
  1369.     
  1370.     if (!filerIsCurDirFile(filer)) {
  1371.         szfilename[0] = 0;
  1372.         return;
  1373.     }
  1374.     // text->buff direct access
  1375.     txJumpLineTop(text);
  1376.     mchar *src = text->buff + text->cur;
  1377.     src += _fileratr.iFileName;
  1378.     //
  1379.     mchar *dst = szfilename;
  1380.     int len = _size[ID_FILENAME];
  1381.     
  1382.     if (_fileratr.fLong) {
  1383.         strcpy(dst,src);
  1384.         dst += strlen(dst);
  1385.         if (txGetCharX(text,FILER_IDIRECTORY) == FATR_DIR) {
  1386.             *dst++ = '\\';    // ディレクトリ記号
  1387.         }
  1388.         *dst = 0;
  1389.     } else {
  1390.         while(len--) {
  1391.             mchar c = *src++;
  1392.             if (c == ' ') {
  1393.                 src += len;
  1394.                 break;
  1395.             }
  1396.             *dst++ = c;
  1397.         }
  1398.         // "."/"\"の分
  1399.         if (*src != ' ') *dst++ = *src++;
  1400.         // 拡張子
  1401.         len = _size[ID_FILEEXT];
  1402.         while(len--) {
  1403.             mchar c = *src++;
  1404.             if (c == ' ') break;
  1405.             *dst++ = c;
  1406.         }
  1407.         if (*src == '\\') *dst++ = '\\';    // ディレクトリ記号
  1408.         *dst = 0;
  1409.     }
  1410. //    information(szfilename);
  1411. }
  1412.  
  1413. static void filerGetCurFilenameFull(FILER *filer,mchar szfilename[CCHPATHNAME])
  1414. {
  1415.     mchar sz[CCHFILENAME];
  1416.     filerGetCurFilename(filer,sz);
  1417.     strcpy(szfilename,filer->szPath);
  1418.     pathSetFileName(szfilename,sz);
  1419. }
  1420.  
  1421. static BOOL filerOpenDir(FILER* filer,mchar *szfilename)
  1422. {
  1423.     TX* text = filer->text;
  1424.     mchar sz[CCHFILENAME + 2] = {0};
  1425. #if 1//2.99F 970404 filerでBSで上のディレクトリに上がったとき、そのディレクトリにカーソルがセットされなかった
  1426.     if (szfilename[0] == '.' && szfilename[1] == '.' && ispathsepa(szfilename[2]) && szfilename[3] == 0)
  1427. #else
  1428.     if (szfilename[0] == '.' && szfilename[1] == '0'/*2.99B*/)
  1429. #endif
  1430.     {
  1431.         mchar *szpath = pathGetFileName(filer->szPath);
  1432.         if (szpath - filer->szPath == 3) {
  1433.             // ルート
  1434.             return FALSE;
  1435.         }
  1436.         // 親に移動
  1437.         szpath[-1] = 0;
  1438.         // [BS]で親ディレクトリに移る際、"11","111"の区別を厳密に
  1439.         sz[0] = ' ';
  1440.         strcpy(sz + 1,pathGetFileName(filer->szPath));
  1441.         if (!_fileratr.fLong) {
  1442.             strcat(sz,"\\\\");
  1443.         }
  1444.     } else {
  1445.         pathSetFileName(filer->szPath,szfilename);
  1446.         pathSetDir(filer->szPath);
  1447.     }
  1448.     //
  1449.     txSetUndisp(text);
  1450.     filerLoadPath(filer,FLP_JUMPDIRTOP);
  1451.     if (p_fDirJumpRoot) txJumpFileTop(text);
  1452.     if (sz[0]) {
  1453.         txJumpFileTop(text);
  1454.         while(1) {
  1455.             if (txSearchEx(text,sz,SEARCH_NOSENSECASE)) {
  1456.                 txJumpParaTop(text);
  1457.                 if (_fileratr.fLong) {
  1458.                     //2.00B Filer:親ディレクトリに戻ったときのカーソル位置を改善
  1459.                     mchar szfilename[CCHPATHNAME];
  1460.                     filerGetCurFilename(filer,szfilename);
  1461.                     pathFormDir(szfilename);
  1462.                     if (!stricmp(szfilename,sz + 1)) {
  1463.                         break;
  1464.                     } else {
  1465.                         if (!txDown(text)) break;
  1466.                     }
  1467.                 } else {
  1468.                     break;
  1469.                 }
  1470.             } else {
  1471.                 break;
  1472.             }
  1473.         }
  1474.     }
  1475.     txSetDisp(text);
  1476.     filerDispInfo(filer);
  1477.     return TRUE;
  1478. }
  1479.  
  1480. //1.00F ディレクトリが選択されているか、ディレクトリにカーソルがあればTRUEを返す
  1481. static BOOL filersIsDirOpen(void)
  1482. {
  1483.     if (filer1->nSelDir || filer2->nSelDir) {
  1484.         statprintf("ディレクトリが選択されています");
  1485.         return TRUE;
  1486.     } else {
  1487.         FILER* filer = filerGetFocus();
  1488.         if (filerIsCurDir(filer)) {//1.00H4 
  1489.             mchar szfilename[CCHFILENAME];
  1490. #if 1    //3.00A2 970503 3.00AのWZ16 Filerで"..\"をEnterしても何もしなくなった
  1491.         //3.00A2 970503 WZ Filerで"..\"をEnterしてもフォルダ名に戻らなかった
  1492.             TXCHAR c1 = txGetCharX(text,_fileratr.iFileName);
  1493.             TXCHAR c2 = txGetCharX(text,_fileratr.iFileName+1);
  1494.             TXCHAR c3 = txGetCharX(text,_fileratr.iFileName+2);
  1495.             if (c1 == '.' && c2 == '.' && (c3 == 0 || ispathsepa(c3))) {
  1496.                 // filerGetCurFilenameで".."は得られないので自前で得る
  1497.                 strcpy(szfilename,"..\\");
  1498.             } else {
  1499.                 filerGetCurFilename(filer,szfilename);
  1500.                 pathFormDir(szfilename);
  1501.             }
  1502. #else
  1503.             if (
  1504.                 txGetCharX(text,_fileratr.iFileName) == '.' &&
  1505.                 txGetCharX(text,_fileratr.iFileName+1) == '.' &&//2.99B 970322 
  1506.                 txGetCharX(text,_fileratr.iFileName+2) == 0        //2.99B 970322 
  1507.             ) {
  1508.                 // filerGetCurFilenameで".."は得られないので自前で得る
  1509.                 strcpy(szfilename,"..");
  1510.             } else {
  1511.                 filerGetCurFilename(filer,szfilename);
  1512.                 pathFormDir(szfilename);
  1513.             }
  1514. #endif
  1515.             filerOpenDir(filer,szfilename);
  1516.             return TRUE;
  1517.         }
  1518.     }
  1519.     return FALSE;
  1520. }
  1521.  
  1522. static BOOL argCheckSize(mchar* tbuff,mchar* p)
  1523. {
  1524.     if (p - tbuff + CCHPATHNAME > CCHARG) {
  1525.         attention("ファイル指定が多すぎます");
  1526.         return FALSE;
  1527.     }
  1528.     return TRUE;
  1529. }
  1530.  
  1531. static int argMake(FILER* filer,mchar* tbuff,mchar *buff,BOOL fDouble,BOOL fShort)
  1532. {
  1533. // tbuff:バッファ先頭,buff:書き込む位置,fDouble:dstの内容も出力
  1534. // 出力したファイル数を返す
  1535. // !fLongでも""で囲む。理由:ディレクトリ名に' 'が入っている場合がある
  1536. //2.00E 従来末尾に' 'が付いたが付かないようにした
  1537. //2.00E4 fShort=TRUEなら、""で括らない。for DOSソフト起動
  1538. #if 1///3.00B1 970612 左で選択し、右で開くと左のパスが右のパスになった
  1539.     mchar szfilename[CCHPATHNAME];
  1540.     mchar *dst = buff;
  1541.     int ret = 0;
  1542.     BOOL fFirst = TRUE;
  1543.     BOOL fErr = FALSE;//3.00B1 970613 WZ Filerで"ファイル指定が多すぎます"のエラーの後に画面Silentのままになった
  1544.     for (int i = 0;i < 2;i++) {
  1545.         TX* text = filer->text;
  1546.         
  1547.         if (filer->nSel + filer->nSelDir) {
  1548.             NLINE npara = text->npara;
  1549.             txSetUndispEx(text);
  1550.             txJumpFileTop(text);
  1551.             do {
  1552.                 if (txGetCharX(text,0) == TXLB_SELECT) {
  1553.                     if (!argCheckSize(tbuff,dst)) {
  1554.                         fErr = TRUE;
  1555.                         break;
  1556.                     }
  1557.                     filerGetCurFilenameFull(filer,szfilename);//2.00B ダブルウィンドウでの%src2がおかしかった
  1558.                     if (!fShort) *dst++ = '"';
  1559.                     strcpy(dst,szfilename);
  1560.                     dst += strlen(szfilename);
  1561.                     if (!fShort) *dst++ = '"';
  1562.                     *dst++ = ' ';
  1563.                     ret++;
  1564.                 }
  1565.             } while(txNextPara(text));
  1566.             txJumpPara(text,npara);
  1567.             txSetDispEx(text);
  1568.         } else {
  1569.             if (filerIsCurDirFile(filer)) {
  1570.                 if (!argCheckSize(tbuff,dst)) {
  1571.                     fErr = TRUE;
  1572.                     break;
  1573.                 }
  1574.                 filerGetCurFilenameFull(filer,szfilename);//2.00B ダブルウィンドウでの%src2がおかしかった
  1575.                 if (!fShort) *dst++ = '"';
  1576.                 strcpy(dst,szfilename);
  1577.                 dst += strlen(szfilename);
  1578.                 if (!fShort) *dst++ = '"';
  1579.                 *dst++ = ' ';//2.00B 
  1580.                 ret++;
  1581.             }
  1582.         }
  1583.         if (!fDouble) break;
  1584.         filer = filerGetOther(filer);
  1585.         if (!filer) break;
  1586.         if (!(filer->nSel + filer->nSelDir)) break;// 選択されてなければ止め
  1587.     }
  1588.     if (fErr) {
  1589.         *buff = 0;
  1590.         return 0;
  1591.     }
  1592.     if (ret) dst--;//2.00E 末尾の' 'を取る
  1593.     *dst = 0;
  1594.     return ret;
  1595. #else
  1596.     mchar szfullname[CCHPATHNAME];
  1597.     if (fShort) {
  1598.         strcpy(szfullname,"");
  1599.     } else {
  1600.         strcpy(szfullname,"\"");
  1601.     }
  1602.     strcat(szfullname,filer->szPath);
  1603.     mchar *szfilename = pathGetFileName(szfullname);
  1604.     mchar *dst = buff;
  1605.     int ret = 0;
  1606.     BOOL fFirst = TRUE;
  1607.     for (int i = 0;i < 2;i++) {
  1608.         TX* text = filer->text;
  1609.         
  1610.         if (filer->nSel + filer->nSelDir) {
  1611.             NLINE npara = text->npara;
  1612.             txSetUndispEx(text);
  1613.             txJumpFileTop(text);
  1614.             do {
  1615.                 if (txGetCharX(text,0) == TXLB_SELECT) {
  1616.                     if (!argCheckSize(tbuff,dst)) return 0;
  1617.                     filerGetCurFilename(filer,szfilename);//2.00B ダブルウィンドウでの%src2がおかしかった
  1618.                     strcpy(dst,szfullname);
  1619.                     dst += strlen(szfullname);
  1620.                     if (!fShort) *dst++ = '"';
  1621.                     *dst++ = ' ';
  1622.                     ret++;
  1623.                 }
  1624.             } while(txNextPara(text));
  1625.             txJumpPara(text,npara);
  1626.             txSetDispEx(text);
  1627.         } else {
  1628.             if (filerIsCurDirFile(filer)) {
  1629.                 if (!argCheckSize(tbuff,dst)) return 0;
  1630.                 filerGetCurFilename(filer,szfilename);//2.00B ダブルウィンドウでの%src2がおかしかった
  1631.                 strcpy(dst,szfullname);
  1632.                 dst += strlen(szfullname);
  1633.                 if (!fShort) *dst++ = '"';
  1634.                 *dst++ = ' ';//2.00B 
  1635.                 ret++;
  1636.             }
  1637.         }
  1638.         if (!fDouble) break;
  1639.         filer = filerGetOther(filer);
  1640.         if (!filer) break;
  1641.         if (!(filer->nSel + filer->nSelDir)) break;// 選択されてなければ止め
  1642.     }
  1643.     if (ret) dst--;//2.00E 末尾の' 'を取る
  1644.     *dst = 0;
  1645.     return ret;
  1646. #endif
  1647. }
  1648.  
  1649. // ファイラーコマンドライン
  1650. static int _cmdfiler(mchar *szcmdline,mchar* tbuff)
  1651. {
  1652.     FILER* filer = filerGetFocus();
  1653.     TX* text = filer->text;
  1654.     BOOL fShort = FALSE;
  1655.     mchar szdstfilename[CCHPATHNAME] = {0};
  1656.     mchar *dst = tbuff;
  1657.     mchar *p = szcmdline;
  1658.     mchar szfind[CCHFILENAME] = {0};
  1659.     BOOL ret = TRUE;
  1660.     BOOL flushsrc = FALSE;
  1661.     BOOL flushdst = FALSE;
  1662.     int nFile = 0;
  1663.     
  1664.     if (
  1665.         strisid(szcmdline,"open") ||
  1666.         strisid(szcmdline,"view") ||
  1667.         strisid(szcmdline,"winopen")
  1668.     ) {
  1669.         if (filersIsDirOpen()) return 1;
  1670.     }
  1671.     //1.99H カーソルlyを保存
  1672.     int ly = text->ly;
  1673.     if (ret) {
  1674.         while(1) {
  1675.             p = strGetWordTop(p);
  1676.             if (!*p) break;
  1677.             int len = strGetWordLen(p);
  1678.             mchar c = p[len];
  1679.             p[len] = 0;
  1680.             //
  1681.             if (!argCheckSize(tbuff,dst)) {
  1682.                 ret = FALSE;
  1683.                 break;
  1684.             }
  1685.             //
  1686.             if (p[0] == '/' || p[0] == '-') {//1.00C スイッチ指定中の"%"に対応
  1687.                 mchar *pp;
  1688.                 if (pp = strchr(p,'%')) {
  1689.                     int l = pp - p;
  1690.                     strncpy(dst,p,l);
  1691.                     dst += l;
  1692.                     //
  1693.                     p = pp;
  1694.                     len -= l;
  1695.                 }
  1696.             }
  1697.             if (p[0] == '%') {
  1698.                 if (!strcmp(p,"%srcpath")) {//3.00B1 970522 %srcpathはWZ32では""で括る様にした
  1699.                     #ifdef __FLAT__//3.00B1 970522 WZ32 FilerからWZ Grepを起動すると空白を含むパスが途切れた
  1700.                     *dst++ = '"';
  1701.                     #endif
  1702.                     strcpy(dst,filer->szPath);
  1703.                     pathSetFileName(dst,NULL);
  1704.                     dst += strlen(dst);
  1705.                     mchar *src = filer->szMask;
  1706.                     if (*src == '.') *dst++ = '*';
  1707.                     while(1) {
  1708.                         if (*src == ';' && src[1] == '.') {
  1709.                             *dst++ = ';';
  1710.                             *dst++ = '*';
  1711.                             *dst++ = '.';
  1712.                             src += 2;
  1713.                         } else if (*src) {
  1714.                             *dst++ = *src++;
  1715.                         } else {
  1716.                             break;
  1717.                         }
  1718.                     }
  1719.                     #ifdef __FLAT__//3.00B1 970522 
  1720.                     *dst++ = '"';
  1721.                     #endif
  1722.                 } else if (!strcmp(p,"%-o")) {    //1.00F
  1723.                     if (p_fConfirmOverwrite) {
  1724.                         strcpy(dst,"-o");dst += strlen(dst);
  1725.                     }
  1726.                 } else if (!strcmp(p,"%-s")) {
  1727.                     //2.00E4 filer.fcmdの引数に" %-s "を指定すると、DOSソフト起動のためにファイル名を""で括らない様にした
  1728.                     fShort = TRUE;
  1729.                 } else if (!strcmp(p,"%*")) {//1.00F
  1730.                     flushsrc = TRUE;
  1731.                     flushdst = TRUE;
  1732.                 } else if (!strcmp(p,"%*src")) {//1.00F
  1733.                     flushsrc = TRUE;
  1734.                 } else if (!strcmp(p,"%*dst")) {//1.00F
  1735.                     flushdst = TRUE;
  1736. // 以下、可変長コマンド。
  1737. // 可変長コマンドは誤動作防止のため、最後に持ってくる。
  1738.                 } else if (!strncmp(p,"%src",4)) {//可変長
  1739.                     nFile = argMake(filer,tbuff,dst,(strchr(p,'2') != NULL),fShort);
  1740. //information(tbuff);
  1741.                     if (!nFile) {
  1742.                         ret = FALSE;
  1743.                         break;
  1744.                     } else {
  1745.                         dst += strlen(dst);
  1746.                         if (strchr(p,'1')) {
  1747.                             if (filer->nSel + filer->nSelDir) {
  1748.                                 attention("選択中は実行できません");
  1749.                                 ret = FALSE;
  1750.                                 break;
  1751.                             }
  1752.                         }
  1753.                     }
  1754.                 } else if (!strncmp(p,"%dst",4)) {//可変長
  1755.                     FILER *filer2 = filerGetOther(filer);
  1756.                     if (filer2) {
  1757.                         strcpy(szdstfilename,filer2->szPath);
  1758.                         pathSetFileName(szdstfilename,NULL);
  1759.                     } else {
  1760.                         mchar *szcaption = p + 4;
  1761.                         while(1) {
  1762.                             HDIALOG hd = dialog(szcaption);
  1763.                             dialogStrC(hd,(szcaption)+"先:",szdstfilename,strlen(szcaption)+4,cchof(szdstfilename),30);
  1764.                             if (dialogOpen(hd)) {
  1765.                                 if (!szdstfilename[0]) {
  1766.                                     attention((szcaption)+"先を指定してください");
  1767.                                     continue;
  1768.                                 }
  1769.                                 if (!pathGetFull(szdstfilename)) {
  1770.                                     // 絶対パスに変換
  1771.                                     txstr sz = szdstfilename;
  1772.                                     strcpy(szdstfilename,filer->szPath);
  1773.                                     pathSetFileName(szdstfilename,sz);
  1774.                                 }
  1775.                             } else {
  1776.                                 ret = FALSE;
  1777.                             }
  1778.                             break;
  1779.                         }
  1780.                     }
  1781.                     // !fLongでも""で囲む。理由:ディレクトリ名に' 'が入っている場合がある
  1782.                     *dst++ = '"';
  1783.                     strcpy(dst,szdstfilename);dst += strlen(dst);
  1784.                     *dst++ = '"';
  1785.                 } else if (!strncmp(p,"%input",6)) {//可変長
  1786.                     mchar *szcaption = p + 6;
  1787.                     BOOL fnew = FALSE;
  1788.                     if (!strncmp(szcaption,"new",3)) {
  1789.                         fnew = TRUE;
  1790.                         szcaption += 3;
  1791.                     }
  1792.                     HDIALOG hd = dialog(szcaption);
  1793.                     mchar szfullname[CCHPATHNAME];
  1794.                     mchar szfilename[CCHFILENAME];
  1795.                     int width = CCHFILENAME;
  1796.                     #ifdef __FLAT__
  1797.                     width = 40;
  1798.                     #endif
  1799.                     if (fnew) {
  1800.                         szfilename[0] = 0;
  1801.                     } else {
  1802.                         filerGetCurFilename(filer,szfilename);
  1803.                     }
  1804.                     dialogStrC(hd,szcaption+":",szfilename,strlen(szcaption)+2,width);
  1805.                     if (dialogOpen(hd)) {
  1806.                         strcpy(szfullname,filer->szPath);
  1807.                         pathSetFileName(szfullname,szfilename);
  1808.                     } else {
  1809.                         ret = FALSE;
  1810.                         break;
  1811.                     }
  1812.                     // !fLongでも""で囲む。理由:ディレクトリ名に' 'が入っている場合がある
  1813.                     *dst++ = '"';
  1814.                     strcpy(dst,szfullname);dst += strlen(dst);
  1815.                     *dst++ = '"';
  1816.                     strcpy(szfind,pathGetFileName(szfullname));
  1817.                 }
  1818.                 *dst++ = ' ';
  1819.             } else {
  1820.                 strcpy(dst,p);
  1821.                 dst += len;
  1822.                 *dst++ = ' ';
  1823.             }
  1824.             //
  1825.             p[len] = c;
  1826.             p += len;
  1827.         }
  1828.         *dst = 0;
  1829.     }
  1830. //information(tbuff);
  1831.     if (strisid(tbuff,"del") && p_fConfirmDel && ret) {
  1832.         if (question("%d 個のファイルを削除します。よろしいですか?",nFile) != IDYES) ret = FALSE;
  1833.     }
  1834.     if (strisid(tbuff,"mcopy") && p_fConfirmCopy && ret) {
  1835.         if (question("%d 個のファイルを %s にコピーします。よろしいですか?",nFile,szdstfilename) != IDYES) ret = FALSE;
  1836.     }
  1837.     if (strisid(tbuff,"mmove") && p_fConfirmCopy && ret) {
  1838.         if (question("%d 個のファイルを移動します。よろしいですか?",nFile) != IDYES) ret = FALSE;
  1839.     }
  1840.     txSetUndisp(text);
  1841.     if (ret) {
  1842.         ret = cmd(tbuff);
  1843.         if (flushsrc) filerLoadPath(filer,0);
  1844.         if (flushdst) {
  1845.             FILER* filer2 = filerGetOther(filer);
  1846.             if (filer2) filerLoadPath(filer2,0);
  1847.         }
  1848.         if (szfind[0]) {
  1849.             mchar *pext;
  1850.             txJumpFileTop(text);
  1851.             if (!_fileratr.fLong) {
  1852.                 if (pext = strchr(szfind,'.')) {
  1853.                     // 拡張子を正規化
  1854.                     mchar buff[CCHFILENAME];
  1855.                     *pext = 0;
  1856.                     sprintf(buff,"%-8s.%s",szfind,pext+1);
  1857.                     strcpy(szfind,buff);
  1858.                 }
  1859.             }
  1860.             txSearchEx(text,szfind,SEARCH_NOSENSECASE);
  1861.         }
  1862.     }
  1863.     if (text->npara < text->lcywindow) {
  1864.         // 先頭行からカーソルまでの行が全て表示できるのに
  1865.         // スクロール表示されて先頭行が見えないことがあった
  1866.         txSetLy(text,text->npara);
  1867.     } else {
  1868.         txSetLy(text,ly);
  1869.     }
  1870.     txSetDisp(text);
  1871.     return ret;
  1872. }
  1873.  
  1874. // マーク情報を使ったマルチコマンドが可能になるように
  1875. // _cmdfilerとmarkClearAllに分割した
  1876. int cmdfiler(mchar *szcmdline)
  1877. {
  1878.     mchar* szWork = malloc(CCHARG);
  1879.     if (!szWork) {
  1880.         attention("メモリが足りません");
  1881.         return 0;
  1882.     }
  1883.     int ret = _cmdfiler(szcmdline,szWork);
  1884.     free(szWork);
  1885.     if (ret) {
  1886.         filerMarkClearAll(filer1);
  1887.         filerMarkClearAll(filer2);
  1888.     }
  1889.     return ret;
  1890. }
  1891.  
  1892. static void cmdOpenFilesSuccess(void)
  1893. {
  1894.     _fReadOnly = FALSE;
  1895.     if (p_fIconize) ShowWindow(text->hwndbase,SW_MINIMIZE);
  1896.     if (_fOpenClose) {
  1897. #if 1//2.99 970319 ファイルの挿入からファイラーを起動してファイルを選択するとアプリエラーになった
  1898.         PostMessage(_textFiler->hwndbase,WM_TXQUIT,0,0);
  1899. #else
  1900.         txQuit(_textFiler);
  1901. #endif
  1902.     }
  1903. }
  1904.  
  1905. static mchar* argCreate(void)
  1906. {
  1907.     mchar* buff = memAlloc(CCHARG);
  1908.     if (buff) {
  1909.         mchar *p = buff;
  1910.         if (!argMake(filerGetFocus(),buff,p,TRUE,FALSE)) {//3.00A 970429 NULL->FALSE
  1911.             memFree(buff);
  1912.             return NULL;
  1913.         }
  1914.         return buff;
  1915.     } else {
  1916.         attention("メモリが不足しています");
  1917.     }
  1918.     return NULL;
  1919. }
  1920.  
  1921. static int cmdOpenFiles(mchar* szcmdstd)
  1922. {
  1923.     if (filersIsDirOpen()) return 1;
  1924.     int ret = 0;
  1925.     if (_hwndParent) {
  1926.         // vzuiInsertFileで複数ファイルを挿入できるように
  1927.         // ファイル名は必ず""で括られる
  1928.         mchar* szcmd = argCreate();
  1929.         if (szcmd) {
  1930.             wndtxSendStr(_hwndParent,WM_TXFILERSELECTED,0,szcmd);
  1931.             memFree(szcmd);
  1932.             _hwndParent = NULL;
  1933.             DoCaption();
  1934.             cmdOpenFilesSuccess();
  1935.         }
  1936.         return 0;
  1937.     }
  1938.     if (_fViewMode) {
  1939.         if (ret = cmdfiler("view %src2")) cmdOpenFilesSuccess();
  1940.     } else if (_fReadOnly) {
  1941.         if (ret = cmdfiler("openread %src2")) cmdOpenFilesSuccess();
  1942.     } else {
  1943.         if (ret = cmdfiler(szcmdstd)) cmdOpenFilesSuccess();
  1944.     }
  1945.     return ret;
  1946. }
  1947.  
  1948. openfiles
  1949. {
  1950. // WZでオープン
  1951.     cmdOpenFiles("open %src2");
  1952. }
  1953.  
  1954. openfileswin
  1955. {
  1956. // 関連付けされたアプリケーションでオープン
  1957.     cmdOpenFiles("winopen %src2");
  1958. }
  1959.  
  1960. back
  1961. {
  1962. // 一つ上のディレクトリに移動
  1963.     filerOpenDir(filerGetFocus(),\"..\");
  1964. }
  1965.  
  1966. BOOL TXCMD mask(mchar* szmask)
  1967. {
  1968.     FILER* filer = filerGetFocus();
  1969.     filerChdir(filer);
  1970.     if (!strcmp(szmask,".")) {// マスク"."対応
  1971.         filerSetPath(filer,wzGetEnv(WZENV_EXT));
  1972.     } else {
  1973.         filerSetPath(filer,szmask);
  1974.     }
  1975.     return TRUE;
  1976. }
  1977.  
  1978. windowFlush
  1979. {
  1980. // ファイルリストの更新
  1981.     FILER* filer = filerGetFocus();
  1982.     filerLoadPath(filer,0);
  1983.     FILER* filer2 = filerGetOther(filer);
  1984.     if (filer2) filerLoadPath(filer2,0);
  1985. }
  1986.  
  1987. //## op filer
  1988.  
  1989. #define OPFILER_SETATR        0
  1990. #define OPFILER_SETDATE        1
  1991. #define OPFILER_DUPLICATE    2
  1992.  
  1993. static BOOL opFilerExec(FILER* filer,mchar* szfilename,int op,DWORD arg)
  1994. {
  1995.     switch(op) {
  1996.         case OPFILER_SETATR: {
  1997.             WORD atr = (WORD)arg;
  1998.             if (!fileAtr(szfilename,&atr,TRUE)) {
  1999.                 return TRUE;
  2000.             } else {
  2001.                 information("%s\nアトリビュートの設定に失敗しました。",szfilename);
  2002.                 return FALSE;
  2003.             }
  2004.             break;
  2005.         }
  2006.         case OPFILER_SETDATE: {
  2007.             HFILE hfile = hfileOpenWrite(szfilename);
  2008.             if (hfile != HFILE_ERROR) {
  2009.                 hfileSetDate(hfile,arg);
  2010.                 hfileClose(hfile);
  2011.                 return TRUE;
  2012.             } else {
  2013.                 information("%s\n日付の設定に失敗しました。",szfilename);
  2014.                 return FALSE;
  2015.             }
  2016.             break;
  2017.         }
  2018.         case OPFILER_DUPLICATE: {
  2019.             mchar szdstname[CCHPATHNAME];
  2020.             strcpy(szdstname,szfilename);
  2021.             mchar szsrcname[CCHPATHNAME];
  2022.             strcpy(szsrcname,szdstname);
  2023.             mchar szext[CCHPATHNAME];
  2024.             {
  2025.                 mchar* p = pathGetExt(szdstname);
  2026.                 strcpy(szext,p);
  2027.                 *p = 0;
  2028.             }
  2029.             mchar* p = pathGetFileName(szdstname);
  2030.             int lchFilename = strlen(p);
  2031.             mchar* dst = p + lchFilename;
  2032.             #ifndef __FLAT__
  2033.             if (lchFilename >= 8) dst--;
  2034.             #endif
  2035.             for (int i = 0;i < 10 + 26;i++) {
  2036.                 mchar* q = dst;
  2037.                 *q++ = i < 10 ? i + '0' : i - 10 + 'A';
  2038.                 strcpy(q,szext);
  2039. //information(szdstname);
  2040.                 if (!fileIsExist(szdstname)) {
  2041.                     if (fileCopy(szsrcname,szdstname)) {
  2042.                         _filerCurSelectClear(filer);
  2043.                         //
  2044.                         TX* text = filer->text;
  2045.                         int n = filerAddPath(filer,szdstname);
  2046.                         if (n) {
  2047.                             _filerCurSelectSet(filer);
  2048.                             txNextPara(text);
  2049.                         }
  2050.                         txDispTextAll(text);
  2051.                         return TRUE;
  2052.                     }
  2053.                     break;
  2054.                 }
  2055.             }
  2056.             information("%s の複製を作成できません",szsrcname);
  2057.             return FALSE;
  2058.         }
  2059.     }
  2060. }
  2061.  
  2062. static int opFiler(int op,DWORD arg)
  2063. {
  2064.     FILER* filer = filerGetFocus();
  2065.     BOOL fErr = FALSE;
  2066.     int ret = 0;
  2067.     for (int i = 0;i < 2;i++) {
  2068.         TX* text = filer->text;
  2069.         if (filer->nSel + filer->nSelDir) {
  2070.             NLINE npara = text->npara;
  2071.             txSetUndispEx(text);
  2072.             txJumpFileTop(text);
  2073.             do {
  2074.                 if (txGetCharX(text,0) == TXLB_SELECT) {
  2075.                     mchar szfilename[CCHPATHNAME];
  2076.                     filerGetCurFilenameFull(filer,szfilename);
  2077.                     if (opFilerExec(filer,szfilename,op,arg)) {
  2078.                         ret++;
  2079.                     } else {
  2080.                         fErr = TRUE;
  2081.                         break;
  2082.                     }
  2083.                 }
  2084.             } while(txNextPara(text));
  2085.             txJumpPara(text,npara);
  2086.             txSetDispEx(text);
  2087.         } else {
  2088.             if (filerIsCurDirFile(filer)) {
  2089.                 mchar szfilename[CCHPATHNAME];
  2090.                 filerGetCurFilenameFull(filer,szfilename);
  2091.                 if (opFilerExec(filer,szfilename,op,arg)) {
  2092.                     ret++;
  2093.                 } else {
  2094.                     fErr = TRUE;
  2095.                     break;
  2096.                 }
  2097.             }
  2098.         }
  2099.         //
  2100.         if (op == OPFILER_DUPLICATE) {
  2101.             filerDispInfo(filer);
  2102.         } else {
  2103.             filerLoadPath(filer,0);
  2104.         }
  2105.         if (fErr) break;
  2106.         filer = filerGetOther(filer);
  2107.         if (!filer) break;
  2108.         if (!filerIsSelected(filer)) break;// 選択されてなければ止め
  2109.     }
  2110.     return ret;
  2111. }
  2112.  
  2113. static void tmFromDosfiletime(TM* tm,DOSFILETIME dft)
  2114. {
  2115.     WORD time = LOWORD(dft);
  2116.     WORD date = HIWORD(dft);
  2117.     tm->tm_sec = (time & 0x1F) * 2;
  2118.     tm->tm_min = (time >> 5) & 0x3F;
  2119.     tm->tm_hour = (time >> 11) & 0x1F;
  2120.     tm->tm_mday = (date & 0x1F);
  2121.     tm->tm_mon = ((date >> 5) & 0x0F) - 1;
  2122.     tm->tm_year = ((date >> 9) & 0x7F) + 80;
  2123. }
  2124.  
  2125. static DOSFILETIME tmToDosfiletime(TM* tm)
  2126. {
  2127.     WORD time = 0;
  2128.     WORD date = 0;
  2129.     time |= (tm->tm_sec) / 2;
  2130.     time |= tm->tm_min << 5;
  2131.     time |= tm->tm_hour << 11;
  2132.     date |= tm->tm_mday;
  2133.     date |= (tm->tm_mon + 1) << 5;
  2134.     date |= (tm->tm_year - 80) << 9;
  2135.     return MAKELONG(time,date);
  2136. }
  2137.  
  2138. duplicate
  2139. {
  2140.     return opFiler(OPFILER_DUPLICATE,0);
  2141.     FILER* filer = filerGetFocus();
  2142.     mchar szfilename[CCHPATHNAME];
  2143.     filerGetCurFilenameFull(filer,szfilename);
  2144.     opFilerExec(filer,szfilename,OPFILER_DUPLICATE,0);
  2145. }
  2146.  
  2147. uiDate
  2148. {
  2149.     BOOL ret = FALSE;
  2150.     FILER* filer = filerGetFocus();
  2151.     mchar szfilename[CCHPATHNAME];
  2152.     filerGetCurFilenameFull(filer,szfilename);
  2153.     HFILE hfile = hfileOpen(szfilename);
  2154.     DOSFILETIME dft = 0;
  2155.     if (hfile != HFILE_ERROR) {
  2156.         dft = hfileGetDate(hfile);
  2157.         hfileClose(hfile);
  2158.     }
  2159.     if (dft) {
  2160.         TM tm;
  2161.         tmFromDosfiletime(&tm,dft);
  2162.         tm.tm_year += 1900;
  2163.         tm.tm_mon++;
  2164.         //
  2165.         HDIALOG hd = dialog("ファイルの日付");
  2166.         dialogSetH(hd);
  2167.         dialogIntI(hd,"日付(&D):",&tm.tm_year,10,5);
  2168.         dialogIntI(hd,"/",&tm.tm_mon,1,3);
  2169.         dialogIntI(hd,"/",&tm.tm_mday,1,3);
  2170.         dialogLF(hd);
  2171.         dialogIntI(hd,"時刻(&T):",&tm.tm_hour,12,3);
  2172.         dialogIntI(hd,":",&tm.tm_min,1,3);
  2173.         dialogIntI(hd,":",&tm.tm_sec,1,3);
  2174.         if (dialogOpen(hd)) {
  2175.             if (tm.tm_year >= 1900) tm.tm_year -= 1900;
  2176.             tm.tm_mon--;
  2177.             DOSFILETIME dft = tmToDosfiletime(&tm);
  2178.             ret = opFiler(OPFILER_SETDATE,dft);
  2179.         }
  2180.     }
  2181.     return ret;
  2182. }
  2183.  
  2184. uiAtr
  2185. {
  2186.     BOOL ret = FALSE;
  2187.     FILER* filer = filerGetFocus();
  2188.     mchar szfilename[CCHPATHNAME];
  2189.     filerGetCurFilenameFull(filer,szfilename);
  2190.     WORD atr;
  2191.     if (!fileAtr(szfilename,&atr,FALSE)) {
  2192.         BOOL fReadOnly = ((atr & FA_RDONLY) != 0);
  2193.         BOOL fHidden = ((atr & FA_HIDDEN) != 0);
  2194.         BOOL fSystem = ((atr & FA_SYSTEM) != 0);
  2195.         HDIALOG hd = dialog("ファイルのアトリビュート");
  2196.         dialogCheck(hd,"書き込み不可(&R)",&fReadOnly);
  2197.         dialogCheck(hd,"隠しファイル(&H)",&fHidden);
  2198.         dialogCheck(hd,"システムファイル(&S)",&fSystem);
  2199.         if (dialogOpen(hd)) {
  2200.             atr &= ~(FA_RDONLY|FA_HIDDEN|FA_SYSTEM);
  2201.             if (fReadOnly) atr |= FA_RDONLY;
  2202.             if (fHidden) atr |= FA_HIDDEN;
  2203.             if (fSystem) atr |= FA_SYSTEM;
  2204.             ret = opFiler(OPFILER_SETATR,atr);
  2205.         }
  2206.     }
  2207.     return ret;
  2208. }
  2209.  
  2210. //## mouse interface
  2211.  
  2212. static NPARA _nparamouse = 0;
  2213.  
  2214. MouseL
  2215. {
  2216.     FILER* filer = filerGetFocus();
  2217.     if (filer->nSelDir + filer->nSel) markClearAll();
  2218.     _nparamouse = 0;
  2219. }
  2220.  
  2221. MouseL2
  2222. {
  2223.     POINT pointcur;
  2224.     GetCursorPos(&pointcur);
  2225.     sleep(100);
  2226.     openfiles();
  2227.     SetCursorPos(pointcur.x,pointcur.y);
  2228. }
  2229.  
  2230. MouseLS
  2231. {
  2232.     FILER* filer = filerGetFocus();
  2233.     TX* text = filer->text;
  2234.     if (_nparamouse == 0) _nparamouse = text->npara;
  2235.     int nparatop;
  2236.     int nparaend;
  2237.     if (_nparamouse <= text->npara) {
  2238.         nparatop = _nparamouse;
  2239.         nparaend = text->npara;
  2240.     } else {
  2241.         nparatop = text->npara;
  2242.         nparaend = _nparamouse;
  2243.     }
  2244.     txSetUndispEx(text);
  2245.     markClearAll();
  2246.     for (NPARA i = nparatop;i <= nparaend;i++) {
  2247.         txJumpPara(text,i);
  2248.         _filerCurSelectReverse(filer);
  2249.     }
  2250.     txSetDispEx(text);
  2251.     filerDispInfo(filer);
  2252. }
  2253.  
  2254. //## help
  2255.  
  2256. static void WinHelpFiler(UINT fuCommand,DWORD dwData)
  2257. {
  2258.     helpContext("wz",IDH_FILER);
  2259. }
  2260.  
  2261. uiHelp
  2262. {
  2263. // ヘルプ(目次)
  2264.     WinHelpFiler(HELP_CONTENTS,0L);
  2265. }
  2266.  
  2267. uiHelpKeyword
  2268. {
  2269. // ヘルプ(キーワード)
  2270.     WinHelpFiler(HELP_PARTIALKEY,(LPARAM)"");
  2271. }
  2272.  
  2273. help
  2274. {
  2275.     uiHelp();
  2276. }
  2277.  
  2278. //## sort cmds
  2279.  
  2280. static void filerFlushSortMenu(FILER* filer)
  2281. {
  2282.     HMENU hmenu = GetSubMenu(GetMenu(_textFiler->hwndbase),2);
  2283.     BOOL _fCheck = FALSE;
  2284.     int idm;
  2285.     
  2286.     for (idm = IDM_SORTNAME;idm <= IDM_SORTDIR;idm++) {
  2287.         BOOL fCheck = (
  2288.             (idm == IDM_SORTNAME + filer->modeSort - 1) &&
  2289.             (filer->modeSort2 == 0 || filer->modeSort2 == filer->modeSort)
  2290.         );
  2291.         CheckMenuItem(
  2292.             hmenu,
  2293.             idm,
  2294.             fCheck ? MF_CHECKED : MF_UNCHECKED
  2295.         );
  2296.         if (fCheck) _fCheck = TRUE;
  2297.     }
  2298.     {
  2299.         static int idm;
  2300.         if (idm == 0) idm = IDM_WZCMDTOP + wzcmdRegister("\m.uiSortEx");
  2301.         BOOL fCheck = !_fCheck;
  2302.         if (filer->modeSort == 0 && filer->modeSort2 == 0) fCheck = FALSE;
  2303.         CheckMenuItem(
  2304.             hmenu,
  2305.             idm,
  2306.             MF_BYCOMMAND|(fCheck ? MF_CHECKED : MF_UNCHECKED)
  2307.         );
  2308.     }
  2309. }
  2310.  
  2311. static int filerDeleteDir(FILER* filer)
  2312. {
  2313. // ディレクトリをfiler->textから消すする
  2314. // 消した数を返す
  2315.     TX* text = filer->text;
  2316.     int ndelete = 0;
  2317.     txJumpFileTop(text);
  2318.     txSetHigh(text);
  2319.     while(1) {
  2320.         if (text->buff[text->cur + FILER_IDIRECTORY] == FATR_DIR) {
  2321.             txDeletePara(text);
  2322.             ndelete++;
  2323.         } else {
  2324.             if (!txNextPara(text)) break;
  2325.         }
  2326.     }
  2327.     txResetHigh(text);
  2328.     return ndelete;
  2329. }
  2330.  
  2331. static void filerSortInit(FILER *filer)
  2332. {
  2333. #if 1
  2334.     //3.00A3 970508 ソートメニューでソート方法を変更しても永久記憶しないようにし、Filerを起動すると設定ダイアログで設定したソート方法で表示するようにした(WZ2の仕様に合わせた)
  2335. #else
  2336.     //2.99B 970322 filer:ソートが永久記憶されなかった
  2337.     if (filer == filer2) {
  2338.         p_filer2modeSort = filer->modeSort;
  2339.         p_filer2modeSort2 = filer->modeSort2;
  2340.     } else {
  2341.         p_modeSort = filer->modeSort;
  2342.         p_modeSort2 = filer->modeSort2;
  2343.     }
  2344. #endif
  2345.     //
  2346.     if (filer->modeSort || filer->modeSort2) {
  2347.         TX* text = filer->text;
  2348.         
  2349.         txSetUndisp(text);
  2350.         text->fEditable = TRUE;
  2351.         filer->nFile = filer->nDirFile - filerDeleteDir(filer);
  2352.         txJumpFileTop(text);
  2353.         _fileratr.fld = FLD_DIR | FLD_HIDDEN;
  2354.         if (!p_fDispGene) _fileratr.fld |= FLD_NOUNDO;
  2355.         filer->nDir = _filerLoadDisk(text,filer->szPath,&_fileratr);
  2356.         filer->nDirFile = filer->nDir + filer->nFile;
  2357.         filerSort(filer);
  2358.         txSetDisp(text);
  2359.         text->fEditable = FALSE;
  2360.     } else {
  2361.         filerLoadPath(filer,FLP_JUMPFILETOP);
  2362.     }
  2363. }
  2364.  
  2365. static void sortSet(int id)
  2366. {
  2367.     FILER* filer = filerGetFocus();
  2368.     id = id - IDM_SORTNAME + 1;
  2369.     if (filer->modeSort == id && filer->modeSort2 == 0) {
  2370.         filer->modeSort = 0;
  2371.     } else {
  2372.         filer->modeSort = id;
  2373.         filer->modeSort2 = 0;
  2374.     }
  2375.     filerSortInit(filer);
  2376.     filerFlushSortMenu(filer);
  2377. }
  2378.  
  2379. static void dialogAddSort(HDIALOG hd,mchar* szcaption,int* data,int wcaption,int wtext)
  2380. {
  2381.     dialogSelectID(hd,szcaption,data,wcaption,wtext,
  2382.         "ソートしない","ファイル名","拡張子","新しい順",
  2383.         "古い順","大きい順","小さい順","ディレクトリ"
  2384.     );
  2385. }
  2386.  
  2387. uiSortEx
  2388. {
  2389. // 高度なソート
  2390.     FILER* filer = filerGetFocus();
  2391.     HDIALOG hd = dialog("高度なソート");
  2392.     dialogAddSort(hd,"ソート&1:",&filer->modeSort,10,16);
  2393.     dialogAddSort(hd,"ソート&2:",&filer->modeSort2,10,16);
  2394.     if (dialogOpen(hd)) {
  2395.         filerSortInit(filer);
  2396.         filerFlushSortMenu(filer);
  2397.     }
  2398. }
  2399.  
  2400. sortName
  2401. {
  2402. //ファイル名順
  2403.     sortSet(IDM_SORTNAME);
  2404. }
  2405.  
  2406. sortExt
  2407. {
  2408. //拡張子順
  2409.     sortSet(IDM_SORTEXT);
  2410. }
  2411.  
  2412. sortNew
  2413. {
  2414. //新しい順
  2415.     sortSet(IDM_SORTNEW);
  2416. }
  2417.  
  2418. sortOld
  2419. {
  2420. //古い順
  2421.     sortSet(IDM_SORTOLD);
  2422. }
  2423.  
  2424. sortBig
  2425. {
  2426. //大きい順
  2427.     sortSet(IDM_SORTBIG);
  2428. }
  2429.  
  2430. sortSmall
  2431. {
  2432. //小さい順
  2433.     sortSet(IDM_SORTSMALL);
  2434. }
  2435.  
  2436. sortDirectory
  2437. {
  2438. //ディレクトリ
  2439.     sortSet(IDM_SORTDIR);
  2440. }
  2441.  
  2442. pathCur
  2443. {
  2444. // カレンドフォルダを表示
  2445.     FILER* filer = filerGetFocus();
  2446.     filerInitPath(filer);
  2447.     filerLoadPath(filer,FLP_JUMPFILETOP);
  2448. }
  2449.  
  2450. pathSetCur
  2451. {
  2452. // 現在表示しているフォルダをカレントフォルダに設定
  2453.     filerChdir(filerGetFocus());
  2454. }
  2455.  
  2456. SwitchView
  2457. {
  2458. // ビューモードオープン/通常オープン切り替え
  2459.     FILER* filer = filerGetFocus();
  2460.     _fViewMode ^= 1;
  2461.     DoCaption();
  2462.     statprintf(_fViewMode ? "View mode" : "Edit mode");
  2463. }
  2464.  
  2465. minimize
  2466. {
  2467. // アイコン化
  2468.     ShowWindow(_textFiler->hwndbase,SW_MINIMIZE);
  2469. }
  2470.  
  2471. keyDelete
  2472. {
  2473. // Deleteキー割り当てコマンド(ユーザインターフェース)
  2474. // ユーザインターフェースの設定によって動作が変わります
  2475.     if (_textFiler->modeEditor == ME_VZ) {
  2476.         markClearAll();
  2477.     } else {
  2478.         // 削除
  2479.         cmdfiler("del %src %*");
  2480.     }
  2481. }
  2482.  
  2483. keyEsc
  2484. {
  2485. // ESCキー割り当てコマンド
  2486.     FILER* filer = filerGetFocus();
  2487.     if (filerIsSelected(filer)) {
  2488.         filerMarkClearAll(filer);
  2489.         return TRUE;
  2490.     }
  2491.     if (p_fIconize) {
  2492.         // オープンしたらアイコン化 に連動
  2493.         minimize();
  2494.     } else if (p_fEscClose || _fEscClose) {
  2495.         txQuit(_textFiler);
  2496.     } else {
  2497.         txuiOpen(text);
  2498.     }
  2499. }
  2500.  
  2501. //## config
  2502.  
  2503. static void txSetFilerColor(TX* text)
  2504. {
  2505.     text->rgbBack = p_rgbBack;
  2506.     text->rgbText = p_rgbText;
  2507.     text->rgbBlock = p_rgbBlock;
  2508.     text->rgbBlockText = p_rgbBlockText;
  2509.     text->rgbComment = p_rgbBinary;
  2510.     text->rgbString = p_rgbDirectory;
  2511.     text->rgbConst = p_rgbReadonly;
  2512.     text->rgbErrorChar = p_rgbHidden;
  2513.     text->rgbPreprocessor = p_rgbSystem;
  2514. }
  2515.  
  2516. static void txSetFilerFontstyle(TX* text)
  2517. {
  2518.     FONTSTYLE* fs = text->tFontstyle + FONTTX_TEXT;
  2519.     fs->tlfHeight[IFONT_STD] = p_lfHeight;
  2520.     strcpy(fs->tlfFaceName[IFONT_STD],p_lfFaceName);
  2521.     text->lfBold = p_lfBold;
  2522. }
  2523.  
  2524. static void txSetFilerDisp(TX* text)
  2525. {
  2526.     text->fDispToolbar = p_fDispToolbar;
  2527.     text->fDispFunctionKey = p_fDispFunctionKey;
  2528.     text->fDispStatusbar = p_fDispStatusbar;
  2529. }
  2530.  
  2531. static void filerSetModesort(FILER* filer)
  2532. {
  2533. #if 1//3.00A3 970508 ソートの設定がfiler2に効いてなかった
  2534.     filer->modeSort = p_modeSort;
  2535.     filer->modeSort2 = p_modeSort2;
  2536. #else
  2537.     if (filer == filer2) {
  2538.         filer->modeSort = p_filer2modeSort;
  2539.         filer->modeSort2 = p_filer2modeSort2;
  2540.     } else {
  2541.         filer->modeSort = p_modeSort;
  2542.         filer->modeSort2 = p_modeSort2;
  2543.     }
  2544. #endif
  2545. }
  2546.  
  2547. static int _iPageConfig = 0;
  2548.  
  2549. BOOL dlgprocConfig(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  2550. {
  2551.     switch(message) {
  2552.         case WM_TXDIALOGPAGECHANGED: {
  2553.             _iPageConfig = wParam;
  2554.             break;
  2555.         }
  2556.     }
  2557.     return FALSE;
  2558. }
  2559.  
  2560. uiConfig
  2561. {
  2562. // 設定
  2563.     HDIALOG hd0 = dialogbig("WZ Filerの設定");
  2564.     dialogSetHookEx(hd0,"\m.dlgprocConfig");
  2565.     dialogSetStartPage(hd0,_iPageConfig);
  2566.     
  2567.     HDIALOG hd = dialog("ウィンドウ");
  2568.         dialogControlGuide(hd,"文字",6);
  2569.         dialogCheck(hd,"位置とサイズを保存(&P)",&p_fSaveWindowPos);
  2570.         dialogCheck(hd,"ファイルオープン後、アイコン化(&I)",&p_fIconize);
  2571.         dialogCheck(hd,"ツールバー(&T)",&p_fDispToolbar);
  2572.         dialogCheck(hd,"ファンクションキー(&F)",&p_fDispFunctionKey);
  2573.         dialogCheck(hd,"ステータスバー(&A)",&p_fDispStatusbar);
  2574.         dialogCheck(hd,"ダブルウィンドウを、上下に表示(&H)",&p_fDoubleH);
  2575.         dialogCheck(hd,"ダブルウィンドウ時、サイズを拡大(&E)",&p_fDoubleSize);
  2576.     dialogAddPage(hd0,hd);
  2577.     
  2578.     HDIALOG hd = dialog("ユーザインターフェース");
  2579.         dialogCheck(hd,"コピー前に確認(&C)",&p_fConfirmCopy);
  2580.         dialogCheck(hd,"削除前に確認(&D)",&p_fConfirmDel);
  2581.         dialogCheck(hd,"上書きコピー前に確認(&O)",&p_fConfirmOverwrite);
  2582.         dialogCheck(hd,"英字キーでメニューオープン(&M)",&p_fMenuKey);
  2583.         dialogCheck(hd,"{Esc}キーですぐ閉じる(&E)",&p_fEscClose);
  2584.         dialogCheck(hd,"スペース選択でカーソルを移動する(&L)",&p_fSelectMove);
  2585.         dialogCheck(hd,\"ディレクトリ移動後、..\へカーソル動かす(&T)",&p_fDirJumpRoot);
  2586.     dialogAddPage(hd0,hd);
  2587.     
  2588.     HDIALOG hd = dialog("表示");
  2589.         dialogCheck(hd,"WZ Editorの世代履歴ファイルも表示(&G)",&p_fDispGene);
  2590. #ifdef __FLAT__
  2591.         dialogCheck(hd,"ロングファイル名で表示(&L)",&p_fLong);
  2592. #else
  2593.         //3.00A4 970509 WZ16 Filer 「ロングファイル名で表示」->「ファイル名を右側に表示」
  2594.         dialogCheck(hd,"ファイル名を右側に表示(&L)",&p_fLong);
  2595. #endif
  2596.         dialogSetH(hd);
  2597.             dialogCheck(hd,"太字で表示(&B)",&p_lfBold);
  2598.             {
  2599.                 dialogLF(hd);
  2600.                 SELFONTARG arg;
  2601.                 memset(&arg,0,sizeof(arg));
  2602.                 arg.lfPitch = FIXED_PITCH;
  2603.                 arg.lfCharSet = DEFAULT_CHARSET;
  2604.                 dialogSelectFont(hd,"フォント(&F):",14,p_lfFaceName,&p_lfHeight,&arg);
  2605.             }
  2606.             dialogLF(hd);
  2607.         dialogSetV(hd);
  2608.         dialogStrC(hd,"バイナリファイルの拡張子(&E):",p_szBinExt,22,CCHPATHNAME,18);
  2609.         dialogAddSort(hd,"ソート(&S):",&p_modeSort,14,16);
  2610.         dialogAddSort(hd,"ソート2(&T):",&p_modeSort2,14,16);
  2611.     dialogAddPage(hd0,hd);
  2612.     
  2613.     HDIALOG hd = dialog("色");
  2614.         dialogSetH(hd);
  2615.         dialogColor(hd,"通常ファイル(&T)...","通常ファイルの色",&p_rgbText,15,NULL);
  2616.         dialogColor(hd,"背景(&B)...","通常ファイルの背景",&p_rgbBack,11,NULL);
  2617.         dialogLF(hd);
  2618.         dialogColor(hd,"選択ファイル(&S)...","選択ファイルの色",&p_rgbBlockText,15,NULL);
  2619.         dialogColor(hd,"背景(&C)...","選択ファイルの背景",&p_rgbBlock,11,NULL);
  2620.         dialogSetV(hd);
  2621.         dialogLF(hd);
  2622.         dialogColor(hd,"バイナリファイル(&I)...","バイナリファイルの色",&p_rgbBinary,27,NULL);
  2623.         dialogColor(hd,"ディレクトリ(&D)...","ディレクトリの色",&p_rgbDirectory,27,NULL);
  2624.         dialogColor(hd,"リードオンリーファイル(&R)...","リードオンリーファイルの色",&p_rgbReadonly,27,NULL);
  2625.         dialogColor(hd,"隠しファイル(&H)...","隠しファイルの色",&p_rgbHidden,27,NULL);
  2626.         dialogColor(hd,"システムファイル(&F)...","システムファイルの色",&p_rgbSystem,27,NULL);
  2627.     dialogAddPage(hd0,hd);
  2628.     
  2629.     if (dialogOpen(hd0)) {
  2630.         fileratrInit();
  2631.         txSetFilerColor(filer1->text);
  2632.         txSetFilerColor(filer2->text);
  2633.         txSetFilerFontstyle(filer1->text);
  2634.         txSetFilerFontstyle(filer2->text);
  2635.         txSetFilerDisp(filer1->text);
  2636.         txSetFilerDisp(filer2->text);
  2637.         txSetFilerDisp(_textFiler);
  2638.         filerSetModesort(filer1);
  2639.         filerSetModesort(filer2);
  2640.         filerLoadPath(filer1,0);
  2641.         txFlush(filer1->text);
  2642.         if (p_fDouble) {
  2643.             filerLoadPath(filer2,0);
  2644.             txFlush(filer2->text);
  2645.         }
  2646.         filerFlushSortMenu(filerGetFocus());
  2647.         //
  2648.         txFlushUI(filer1->text);
  2649.         txFlush(_textFiler);    //2.99D 970331 ツールバーを非表示から表示に設定するとゴミが出た
  2650.     }
  2651. }
  2652.  
  2653. //##preview
  2654. //2.99 970318 
  2655.  
  2656. static void previewClose(void)
  2657. {
  2658.     if (_hwndPreview) {
  2659.         DestroyWindow(_hwndPreview);
  2660.         _hwndPreview = NULL;
  2661.         if (_hwndPreviewPartition) {
  2662.             DestroyWindow(_hwndPreviewPartition);
  2663.             _hwndPreviewPartition = NULL;
  2664.         }
  2665.         //
  2666.         filer1->text->txnMask = 0;
  2667.         filer2->text->txnMask = 0;
  2668.         SendMessage(_textFiler->hwndbase,WM_TXFLUSHWINDOWSIZE,0,0);
  2669.     }
  2670. }
  2671. preview
  2672. {
  2673.     if (_hwndPreview) {
  2674.         previewClose();
  2675.         p_fPreview = FALSE;
  2676.     } else {
  2677.         _hwndPreview = CreateWindowEx(
  2678.             #ifdef __FLAT__
  2679.             (_fwin40 * WS_EX_CLIENTEDGE),
  2680.             #else
  2681.             0,
  2682.             #endif
  2683.             TXWS_SZCLASS,
  2684.             NULL,
  2685.             TXWS_TEXT|WS_VSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP,
  2686.             CW_USEDEFAULT,CW_USEDEFAULT,
  2687.             CW_USEDEFAULT,CW_USEDEFAULT,
  2688.             _textFiler->hwndbase,
  2689.             NULL,
  2690.             _textFiler->hInstance,
  2691.             NULL
  2692.         );
  2693.         if (_hwndPreview) {
  2694.             _hwndPreviewPartition = CreateWindow(
  2695.                 TXPARTITION_SZCLASS,NULL,
  2696.                 WS_CHILDWINDOW | WS_VISIBLE,
  2697.                 CW_USEDEFAULT,CW_USEDEFAULT,
  2698.                 CW_USEDEFAULT,CW_USEDEFAULT,
  2699.                 _textFiler->hwndbase,
  2700.                 NULL,
  2701.                 _textFiler->hInstance,
  2702.                 NULL
  2703.             );
  2704.             //
  2705.             TX* text = (LPVOID)SendMessage(_hwndPreview,TXWM_GETTX,0,0);
  2706.             text->hwndbase = _textFiler->hwndbase;
  2707.             text->txnMask = TXNM_CONTROLTAB|TXNM_CONTROLF4;
  2708.             txOpenText(text);
  2709.             //
  2710.             filer1->text->txnMask = TXNM_CHANGENPARA|TXNM_CONTROLTAB;
  2711.             filer2->text->txnMask = TXNM_CHANGENPARA|TXNM_CONTROLTAB;
  2712.             SendMessage(_textFiler->hwndbase,WM_TXFLUSHWINDOWSIZE,0,0);
  2713.             p_fPreview = TRUE;
  2714.         }
  2715.     }
  2716. }
  2717.  
  2718. //## API
  2719. //3.00A 970502 filerGetLine,filerGetFilename,filerGetTitle復活
  2720.  
  2721. int TXAPI filerGetLine(txstr str)
  2722. {
  2723. // ファイラーのカレント表示行の内容をstrに取得
  2724. //{#RET}取得したバイト数を返す
  2725. //2.00Bで新設
  2726.     int ret = txGetLine(text,str);
  2727.     strcpy(str,&str[FILER_LCXMASK]);
  2728.     ret -= FILER_LCXMASK;
  2729.     return ret;
  2730. }
  2731.  
  2732. int TXAPI filerGetLineEx(txstr str)
  2733. {
  2734. // ファイラーのカレント表示行の内容をstrに取得
  2735. // ファイル名を先頭として取得
  2736. //{#RET}取得したバイト数を返す
  2737. //3.00C1 971017 new
  2738.     int ret = txGetLine(text,str);
  2739.     {
  2740.         mchar* pFilename = &str[_fileratr.iFileName];
  2741.         int len = _size[ID_FILENAME];
  2742.         memcpy(pFilename,pFilename + len,strlen(pFilename + len) + 1);
  2743.     }
  2744.     {
  2745.         mchar szfilename[CCHFILENAME];
  2746.         filerGetCurFilename(filerGetFocus(),szfilename);
  2747.         str = szfilename + &str[FILER_LCXMASK];
  2748.     }
  2749.     return strlen(str);
  2750. }
  2751.  
  2752. int TXAPI filerGetFilename(txstr str)
  2753. {
  2754. // ファイラーのカレント表示行のファイル名をstrに取得
  2755. //{#RET}取得できたかどうかを返す
  2756. //2.00Bで新設
  2757.     mchar szfilename[CCHFILENAME];
  2758.     filerGetCurFilename(filerGetFocus(),szfilename);
  2759.     str = szfilename;
  2760.     return TRUE;
  2761. }
  2762.  
  2763. int TXAPI filerGetTitle(txstr str)
  2764. {
  2765. // ファイラーのファイル一覧ウィンドウのタイトルをstrに返す
  2766.     FILER* filer = filerGetFocus();
  2767.     strcpy(str,filer->szPath);
  2768.     pathSetFileName(str,filer->szMask);
  2769.     mchar buff[80];
  2770.     infoSprint(filer,buff);
  2771.     str += " ";
  2772.     str += buff;
  2773.     return TRUE;
  2774. }
  2775.  
  2776. //## init
  2777.  
  2778. static void txSetFilerUI(TX* text)
  2779. {
  2780.     strcpy(text->szToolbar,"txe_filer");
  2781.     strcpy(text->szKey,"txe_filer");
  2782.     strcpy(text->szMenu,"bartxe_FILER");
  2783.     //3.00B1 970612 filerでメニューキーでコンテキストメニューが開く様にした
  2784.     sstrcpy(text->szMenuMouseR,"menu.FILERファイル");
  2785.     sstrcpy(text->szMenuMouseRClip,"menu.FILERファイル");
  2786. }
  2787.  
  2788. static void txSetFilerStatusbar(TX* text)
  2789. {
  2790. //3.00A3 970508 new
  2791.     text->fDispPrekey = TRUE;
  2792.     text->fDispPrekeyLeft = FALSE;
  2793.     text->fDispLocate = FALSE;
  2794.     text->fDispSelecting = FALSE;
  2795.     text->fDispEdit = FALSE;
  2796.     text->fDispPagingMode = FALSE;
  2797.     text->fDispSL_RSPACE = FALSE;
  2798.     text->fDispOverwrite = FALSE;
  2799.     text->fDispParaCharatr = FALSE;
  2800.     text->fDispEditmode = FALSE;
  2801.     text->fDispInlineform = FALSE;
  2802. }
  2803.  
  2804. static void filerNewText(FILER* filer)
  2805. {
  2806.     HWND hwndtext = CreateWindowEx(
  2807.         #ifdef __FLAT__
  2808.         (_fwin40 * WS_EX_CLIENTEDGE),
  2809.         #else
  2810.         0,
  2811.         #endif
  2812.         TXWS_SZCLASS,
  2813.         NULL,
  2814.         WS_CHILDWINDOW|WS_VISIBLE|TXWS_TEXT,
  2815.         CW_USEDEFAULT,CW_USEDEFAULT,
  2816.         CW_USEDEFAULT,CW_USEDEFAULT,
  2817.         _textFiler->hwndbase,
  2818.         NULL,
  2819.         _textFiler->hInstance,
  2820.         NULL
  2821.     );
  2822.     if (hwndtext) {
  2823.         TX* text = (LPVOID)SendMessage(hwndtext,TXWM_GETTX,0,0);
  2824.         filer->text = text;
  2825.         text->hwndbase = _textFiler->hwndbase;
  2826. #if 0//2.99B 970322 これくらいの初期化は自動化された
  2827.         text->width = MAXWIDTH;
  2828.         text->fSpaceLeft = FALSE;
  2829.         text->fDispSearch = FALSE;
  2830.         text->fDispEof = FALSE;
  2831.         text->fDispLf = FALSE;
  2832.         text->fDispLocate = FALSE;
  2833.         text->fDispJspace = FALSE;
  2834.         text->fDispLine = FALSE;
  2835.         text->fDispParse = FALSE;
  2836.         text->fDispControlSpace = TRUE;
  2837.         text->fLineD = FALSE;
  2838.         text->fBackup = FALSE;
  2839.         text->fSetWidthByWindow = FALSE;
  2840.         text->fScrollBarH = FALSE;
  2841.         text->fScrollBarV = TRUE;
  2842.         text->fMouseArrow = TRUE;
  2843.         text->modeImeSetFocus = ISF_OFF;
  2844.         text->fVertical = FALSE;
  2845.         text->fPageTurn = FALSE;
  2846.         text->fConfigBinedit = FALSE;
  2847.         text->fConfigInlineform = FALSE;//2.98 970310 
  2848.         text->lfWestern = FALSE;
  2849. #endif
  2850.         text->lfProp = FALSE;
  2851.         text->fSetLocateByMouseFocus = TRUE;//2.99C 970324 foo.cを選択し、別の窓をアクティブにし、bar.cをダブルクリックするとfoo.cが開いた
  2852.         text->searchmode = SEARCH_NOSENSECASE;
  2853.         text->fDispControlSpace = TRUE;
  2854.         text->fDispUnder = TRUE;
  2855.         text->lcxmask = FILER_LCXMASK;
  2856.         text->fListbox = TRUE;
  2857.         text->fTempMem = 1;// WZ32でロングファイルネーム使用時のソートを高速化する
  2858.         text->fUseMenuKey = TRUE;//2.99 970319 
  2859.         txSetFilerColor(text);
  2860.         txSetFilerFontstyle(text);
  2861.         txSetFilerUI(text);
  2862.         txSetFilerStatusbar(text);//3.00A3 970508 
  2863.         //
  2864.         txOpenText(text);
  2865.     }
  2866.     //
  2867.     filer->hwndInfo = CreateWindow(
  2868.         _szClassInfo,NULL,
  2869.         WS_CHILDWINDOW | WS_VISIBLE,
  2870.         CW_USEDEFAULT, CW_USEDEFAULT,
  2871.         CW_USEDEFAULT, CW_USEDEFAULT,
  2872.         _textFiler->hwndbase,
  2873.         NULL,
  2874.         _textFiler->hInstance,
  2875.         NULL
  2876.     );
  2877. }
  2878.  
  2879. HOOKRESULT __wndproctext(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  2880. {
  2881.     TX* text = textTarget;
  2882.     if (text != filer1->text && text != filer2->text) return FALSE;
  2883.     switch(message) {
  2884.         case WM_CHAR: {
  2885.             FILER* filer = filerGetFocus();
  2886.             TX* text = filer->text;
  2887.             BOOL fshift = (GetKeyState(VK_SHIFT) < 0);
  2888.             static mchar *szkana = "チコソシイハキクニマノリモミラセタストカナヒテサンツ";
  2889.             if (iskana(wParam)) {
  2890.                 mchar *p = strchr(szkana,wParam);
  2891.                 if (p) {
  2892.                     int ch = (p - szkana) + 'A';
  2893.                     WZKEY wzkey = txWzkeyFromSzkey(text,chartostr(ch));
  2894.                     if (wzkey) {
  2895.                         WZCMD wzcmd = txKeyGetWzcmd(text,wzkey);
  2896.                         if (wzcmd) SendMessage(text->hwndbase,WM_COMMAND,IDM_WZCMDTOP + wzcmd,0);
  2897.                     }
  2898.                     return HOOK_CAPTURE;
  2899.                 }
  2900.             }
  2901.             if (
  2902.                 (!p_fMenuKey && !fshift) ||
  2903.                 (p_fMenuKey && fshift)
  2904.             ) {
  2905.                 if (isalpha(wParam)) {
  2906.                     NPARA npara = text->npara;// 先頭文字検索で見つからなかったとき、カーソルを移動しないように
  2907.                     int ly = text->ly;
  2908.                     mchar buff[3];
  2909.                     
  2910.                     buff[0] = ' ';
  2911.                     buff[1] = toupper(wParam);
  2912.                     buff[2] = 0;
  2913.                     txSetUndisp(text);
  2914.                     txJumpParaEnd(text);
  2915.                     if (!searchfile(text,buff)) {
  2916.                         txJumpFileTop(text);
  2917.                         if (!searchfile(text,buff)) txJumpPara(text,npara);
  2918.                     }
  2919.                     txJumpParaTop(text);
  2920.                     txSetLy(text,ly);
  2921.                     txSetDisp(text);
  2922.                     previewFlush();//3.00B1 970613 WZ Filer:Shift+英字でもファイルプレビューを更新
  2923.                     return HOOK_CAPTURE;
  2924.                 }
  2925.             }
  2926.             switch(wParam) {
  2927.                 case '*': {
  2928.                     strcpy(filer->szMask,"*.*");
  2929.                     filerLoadPath(filer,FLP_JUMPFILETOP);
  2930.                     return HOOK_CAPTURE;
  2931.                 }
  2932.                 case '/':
  2933.                 case '\\': {
  2934.                     // root
  2935.                     filer->szPath[3] = 0;
  2936.                     filerLoadPath(filer,FLP_JUMPFILETOP);
  2937.                     return HOOK_CAPTURE;
  2938.                 }
  2939.                 case '.': {
  2940.                     // マスクメニューで[Q]を選択するとアプリエラーにならない様に
  2941.                     strcpymax(filer->szMask,wzGetEnv(WZENV_EXT),CCHPATHNAME / 2);
  2942.                     filerLoadPath(filer,FLP_JUMPFILETOP);
  2943.                     return HOOK_CAPTURE;
  2944.                 }
  2945.                 case '0': {
  2946.                     pathCur();
  2947.                     return HOOK_CAPTURE;
  2948.                 }
  2949.                 case ':': {
  2950.                     call("menu.FILERドライブ");
  2951.                     return HOOK_CAPTURE;
  2952.                 }
  2953.                 case ' ': {
  2954.                     if (p_fSelectMove) {//1.00C
  2955.                         fshift ? sup() : sdown();
  2956.                     } else {
  2957.                         filerCurSelectReverse(filer);
  2958.                     }
  2959.                     return HOOK_CAPTURE;
  2960.                 }
  2961.                 case '@': {
  2962.                     call("menu.FILERパスリスト");
  2963.                     return HOOK_CAPTURE;
  2964.                 }
  2965.             }
  2966.             if (isdigit(wParam) && wParam != '0') {
  2967.                 SendMessage(text->hwndbase,WM_COMMAND,IDM_DRIVETOP + wParam - '1',0);
  2968.                 return HOOK_CAPTURE;
  2969.             }
  2970.             break;
  2971.         }
  2972.         case WM_SETFOCUS: {
  2973.             FILER* filer = (hwnd == filer1->text->hwndtext) ? filer1 : filer2;
  2974.             filerFlushSortMenu(filer);
  2975.             filerDispInfo(filer);
  2976.             filerDoCaption(filer);
  2977.             PostMessage(hwnd,WM_TXUSER,0,0);
  2978.             break;
  2979.         }
  2980.         case WM_TXUSER: {
  2981.             // for フォーカス切り替え時の、fListboxの描画フラッシュ
  2982.             txDispAll(text);
  2983.             break;
  2984.         }
  2985.         case WM_KEYUP: {//3.00B1 970613 
  2986.             if (_fPreviewDirty) {
  2987.                 previewFlush();
  2988.             }
  2989.             break;
  2990.         }
  2991.     }
  2992.     return HOOK_CONTINUE;
  2993. }
  2994.  
  2995. //##menu
  2996.  
  2997. static int menuChange(HMENU hmenu,int _idm)
  2998. {
  2999.     int n = GetMenuItemCount(hmenu);
  3000.     int i;
  3001.     for (i = 0;i < n;i++) {
  3002.         int idm = GetMenuItemID(hmenu,i);
  3003.         if (idm == _idm) {
  3004.             DeleteMenu(hmenu,i,MF_BYPOSITION);
  3005.             return i;
  3006.         }
  3007.     }
  3008.     return -1;
  3009. }
  3010.  
  3011. static void driveMenu(HMENU hmenu,int imenu,BOOL fDriveMenu)
  3012. {
  3013.     mchar idrive;
  3014.     #ifdef __FLAT__
  3015.     static mchar szpath[] = " :\\";
  3016.     #endif
  3017.     for (idrive = 0;idrive < 26;idrive++) {
  3018.         #ifdef __FLAT__
  3019.         static mchar *tsztype[] = {
  3020.             "不明","","フロッピーディスク","固定ディスク","ネットワーク","CD-ROM","RAMディスク","??",
  3021.         };
  3022.         szpath[0] = 'A' + idrive;
  3023.         int type = GetDriveType(szpath);
  3024.         if (type > DRIVE_RAMDISK) type = DRIVE_RAMDISK + 1;//tsztypeでサポートしていないtype
  3025.         if (type == 1) continue;
  3026.         #else
  3027.         static mchar *tsztype[] = {
  3028.             "","ROMディスク","フロッピーディスク","固定ディスク","CD-ROM,ネットワーク",
  3029.         };
  3030.         int type = GetDriveType(idrive);
  3031.         if (type == 0) continue;
  3032.         #endif
  3033.         {
  3034.             int id = IDM_DRIVETOP + idrive;
  3035.             mchar buff[100];
  3036.             if (fDriveMenu) {
  3037.                 sprintf(buff,"&%c:\t%s",'A' + idrive,tsztype[type]);
  3038.             } else {
  3039.                 sprintf(buff,"%c: (%s)",'A' + idrive,tsztype[type]);
  3040.             }
  3041.             InsertMenu(hmenu,imenu++,MF_STRING|MF_BYPOSITION,id,buff);
  3042.         }
  3043.     }
  3044. }
  3045.  
  3046. static void jumpMenu(HMENU hmenu,int iposition)
  3047. {
  3048.     int n = histGetCount(HIST_PATH);
  3049.     if (n == 0) {
  3050.         InsertMenu(hmenu,iposition++,MF_STRING|MF_BYPOSITION,-1,"パスヒストリは空です");
  3051.     } else {
  3052.         #define JUMP_N    20
  3053.         int i = JUMP_N;
  3054.         while(i--) {
  3055.             if (n == 0) break;
  3056.             //
  3057.             mchar szpath[CCHPATHNAME];
  3058.             strcpy(szpath,histRead(HIST_PATH,--n));
  3059.             if (pathIsWild(szpath)) {
  3060.                 pathForm(szpath);
  3061.             }
  3062.             //
  3063.             mchar *p;
  3064.             if (pathFormDir(szpath)) {
  3065.                 p = szpath;
  3066.             } else {
  3067.                 p = pathGetFileName(szpath);
  3068.             }
  3069.             int c = toupper(p[0]);
  3070.             strcpy(szpath,histRead(HIST_PATH,n));
  3071.             if (pathGetFileName(szpath) == szpath) {//1.00F filer.uiJump:マスクも表示できるようにした
  3072.                 c = toupper(szpath[0]);
  3073.                 if (!isalpha(c)) {
  3074.                     mchar* szext = pathGetExt(szpath);
  3075.                     if (szext[0] && szext[1] && isalpha(szext[1])) {
  3076.                         c = toupper(szext[1]);
  3077.                     } else {
  3078.                         c = ' ';
  3079.                     }
  3080.                 }
  3081.             } else {
  3082.                 if (pathIsWild(szpath)) {
  3083.                     pathForm(szpath);
  3084.                 }
  3085.             }
  3086.             {
  3087.                 int idm = IDM_WZCMDTOP + wzcmdRegister("filer.mask(["+szpath+"])");
  3088.                 txstr sz = "&" + chartostr(c) + "\t" + szpath;
  3089.                 InsertMenu(hmenu,iposition++,MF_STRING|MF_BYPOSITION,idm,sz);
  3090.             }
  3091.         }
  3092.     }
  3093. }
  3094.  
  3095. static void previewFlush(void)
  3096. {
  3097. //3.00A3 970508 new
  3098.     _fPreviewDirty = FALSE;
  3099.     if (_hwndPreview) {
  3100.         FILER* filer = filerGetFocus();
  3101.         mchar szfilename[CCHPATHNAME] = {0};
  3102.         if (filerIsCurFile(filer)) {
  3103.             filerGetCurFilenameFull(filer,szfilename);
  3104.         }
  3105.         //
  3106.         extern "event" void at_pf(HWND hctrl,mchar* szfilename,int mode);
  3107.         at_pf(_hwndPreview,szfilename,1);
  3108.     }
  3109. }
  3110.  
  3111. static void myPostMessage(HWND hwnd,int message,WPARAM wParam,LPARAM lParam)
  3112. {
  3113.     MSG msg;
  3114.     if (PeekMessage(&msg,hwnd,message,message,PM_NOREMOVE)) {
  3115.         // 既にポストされている場合は、ポストしない
  3116.     } else {
  3117.         PostMessage(hwnd,message,wParam,lParam);
  3118.     }
  3119. }
  3120.  
  3121. static void previewFlushWithoutKeyRepeat(HWND hwnd)
  3122. {
  3123. //3.00B1 970613 ファイラーのファイルプレビューでキーリピート中は更新しないようにした
  3124.     if (
  3125.         (GetAsyncKeyState(VK_UP) < 0) ||
  3126.         (GetAsyncKeyState(VK_DOWN) < 0) ||
  3127.         (GetAsyncKeyState(VK_CONTROL) < 0)
  3128.     ) {
  3129.         _fPreviewDirty = TRUE;
  3130.     } else {
  3131.         previewFlush();
  3132.     }
  3133. }
  3134.  
  3135. HOOKRESULT __wndprocbase(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  3136. {
  3137.     if (textTarget != _textFiler) return FALSE;
  3138.     switch(message) {
  3139.         case WM_SYSCOMMAND: {
  3140.             UINT uID = (UINT)wParam;
  3141.             if ((uID >= WZSC_HISTORYFIRST) &&
  3142.             (uID < WZSC_HISTORYFIRST + text->nDispFileHist)) {
  3143.                 uID -= WZSC_HISTORYFIRST;
  3144.                 txOpenForkFast(
  3145.                 text,
  3146.                 histRead(HIST_FILE, histGetCount(HIST_FILE) - uID - 1));
  3147.             }
  3148.             break;
  3149.         }
  3150.         case WM_COMMAND: {
  3151.             if (
  3152.                 (_hwndPartition && WM_COMMAND_GetHwndCtrl(wParam,lParam) == _hwndPartition) ||
  3153.                 (_hwndPreviewPartition && WM_COMMAND_GetHwndCtrl(wParam,lParam) == _hwndPreviewPartition)
  3154.             ) {
  3155.                 SendMessage(hwnd,WM_TXFLUSHWINDOWSIZE,0,0);
  3156.                 return TRUE;
  3157.             }
  3158.             FILER* filer = filerGetFocus();
  3159.             int id = LOWORD(wParam);
  3160.             if (IDM_DRIVETOP <= id && id <= IDM_DRIVEEND) {
  3161.                 mchar buff[CCHPATHNAME];
  3162.                 UCHAR cDrive = id - IDM_DRIVETOP + 'A';
  3163.                 if (driveGetCurDir(cDrive,buff)) {
  3164.                     filerChdir(filer);
  3165.                     strcpy(filer->szPath,buff);
  3166.                     pathSetDir(filer->szPath);
  3167.                     filerLoadPath(filer,FLP_JUMPFILETOP);
  3168.                 } else {
  3169.                     attention("ドライブの指定が違います\n");
  3170.                 }
  3171.                 return HOOK_CAPTURE;
  3172.             }
  3173.             if (IDM_SORTNAME <= id && id <= IDM_SORTDIR) {
  3174.                 sortSet(id);
  3175.                 return HOOK_CAPTURE;
  3176.             }
  3177.             if (id == IDM_CMDLINE) {
  3178.                 WNDTX_RECEIVE_MEM_ENTER
  3179.                 cmdline((mchar*)lParam,TRUE);
  3180.                 WNDTX_RECEIVE_MEM_EXIT
  3181.                 return HOOK_CAPTURE;
  3182.             }
  3183.             return HOOK_CONTINUE;
  3184.         }
  3185.         case WM_INITMENUPOPUP: {
  3186.             FILER* filer = filerGetFocus();
  3187.             HMENU hmenu = (HMENU)wParam;
  3188.             // サブメニューを生成させるため、先にWZオリジナルの処理をする
  3189.             SendMessage(hwnd,WM_TXINITMENU,(WPARAM)hmenu,0);
  3190.             //
  3191.             static int tidmSort[SORT_N];
  3192.             static int idmDrive;
  3193.             static int idmDriveMenu;
  3194.             static int idmJump;
  3195.             static int idmViewMode;
  3196.             if (tidmSort[0] == 0) {
  3197.                 mchar* tsz[SORT_N] = {
  3198.                     "sortName",
  3199.                     "sortExt",
  3200.                     "sortNew",
  3201.                     "sortOld",
  3202.                     "sortBig",
  3203.                     "sortSmall",
  3204.                     "sortDirectory",
  3205.                 };
  3206.                 int i;
  3207.                 for (i = 0;i < SORT_N;i++) {
  3208.                     tidmSort[i] = IDM_WZCMDTOP + wzcmdRegister("\m." + tsz[i]);
  3209.                 }
  3210.                 //
  3211.                 idmDrive = IDM_WZCMDTOP + wzcmdRegister("\m.driveList");
  3212.                 idmDriveMenu = IDM_WZCMDTOP + wzcmdRegister("\m.driveListMenu");
  3213.                 idmJump = IDM_WZCMDTOP + wzcmdRegister("\m.jumpList");
  3214.                 idmViewMode = IDM_WZCMDTOP + wzcmdRegister("\m.SwitchView");
  3215.             }
  3216.             // drive(メニュー内)
  3217.             {
  3218.                 int i = menuChange(hmenu,idmDrive);
  3219.                 if (i >= 0) driveMenu(hmenu,i,FALSE);
  3220.             }
  3221.             // drive menu(独立したメニュー)
  3222.             {
  3223.                 int i = menuChange(hmenu,idmDriveMenu);
  3224.                 if (i >= 0) driveMenu(hmenu,i,TRUE);
  3225.             }
  3226.             // jump
  3227.             {
  3228.                 int i = menuChange(hmenu,idmJump);
  3229.                 if (i >= 0) jumpMenu(hmenu,i);
  3230.             }
  3231.             // sort
  3232.             {
  3233.                 int n = GetMenuItemCount(hmenu);
  3234.                 int i;
  3235.                 for (i = 0;i < n;i++) {
  3236.                     int idm = GetMenuItemID(hmenu,i);
  3237. //information("%d",idm);
  3238.                     int i;
  3239.                     for (i = 0;i < SORT_N;i++) {
  3240.                         if (idm == tidmSort[i]) {
  3241.                             BOOL fcheck = (
  3242.                                 (i == filer->modeSort - 1) &&
  3243.                                 (filer->modeSort2 == 0 || filer->modeSort2 == filer->modeSort)
  3244.                             );
  3245.                             CheckMenuItem(hmenu,idm,fcheck ? MF_CHECKED : MF_UNCHECKED);
  3246.                             break;
  3247.                         }
  3248.                     }
  3249.                     if (idm == idmDrive) {
  3250.                         InsertMenu(hmenu,i++,MF_STRING|MF_BYPOSITION,1,"aa");
  3251.                         InsertMenu(hmenu,i++,MF_STRING|MF_BYPOSITION,1,"aa");
  3252.                         InsertMenu(hmenu,i++,MF_STRING|MF_BYPOSITION,1,"aa");
  3253.                     }
  3254.                     if (idm == idmViewMode) {
  3255.                         CheckMenuItem(hmenu,idm,_fViewMode ? MF_CHECKED : MF_UNCHECKED);
  3256.                     }
  3257.                 }
  3258.             }
  3259.             return HOOK_CAPTURE;
  3260.         }
  3261.         case WM_TXNOTIFY: {//2.99 970317 
  3262.             if (lParam == TXN_CHANGENPARA) {
  3263. #if 1//3.00A3 970508 
  3264.     #if 1//3.00B1 970613 
  3265.                 previewFlushWithoutKeyRepeat(hwnd);
  3266.     #else
  3267.                 previewFlush();
  3268.     #endif
  3269. #else
  3270.                 if (_hwndPreview) {
  3271.                     FILER* filer = filerGetFocus();
  3272.                     mchar szfilename[CCHPATHNAME] = {0};
  3273.                     if (filerIsCurFile(filer)) {
  3274.                         filerGetCurFilenameFull(filer,szfilename);
  3275.                     }
  3276.                     //
  3277.                     extern "event" void at_pf(HWND hctrl,mchar* szfilename,int mode);
  3278.                     at_pf(_hwndPreview,szfilename,1);
  3279.                 }
  3280. #endif
  3281.             } else if (lParam == TXN_CONTROLTAB) {
  3282. #if 1//3.00A3 970508 WZ FIler:Ctrl+Tabでプレビューと切り替えられる様にした
  3283.                 FILER* filer = filerGetFocus();
  3284.                 static BOOL fFocus2;
  3285.                 if (wParam == _hwndPreview) {
  3286.                     if (fFocus2 && p_fDouble) {
  3287.                         SetFocus(filer2->text->hwndtext);
  3288.                     } else {
  3289.                         SetFocus(filer1->text->hwndtext);
  3290.                     }
  3291.                     macroHookWndBaseReturn(TRUE);
  3292.                     return HOOK_CAPTURE;
  3293.                 } else if (wParam == filer->text->hwndtext) {
  3294.                     fFocus2 = (filer == filer2);
  3295.                     SetFocus(_hwndPreview);
  3296.                     macroHookWndBaseReturn(TRUE);
  3297.                     return HOOK_CAPTURE;
  3298.                 }
  3299. #else
  3300.                 if (wParam == _hwndPreview) {
  3301.                     SetFocus(_textFiler->hwndtext);
  3302.                     macroHookWndBaseReturn(TRUE);
  3303.                     return HOOK_CAPTURE;
  3304.                 } else if (wParam == _textFiler->hwndtext) {
  3305.                     SetFocus(_hwndPreview);
  3306.                     macroHookWndBaseReturn(TRUE);
  3307.                     return HOOK_CAPTURE;
  3308.                 }
  3309. #endif
  3310.             } else if (lParam == TXN_CONTROLF4) {
  3311.                 if (wParam == _hwndPreview) {
  3312.                     previewClose();
  3313.                     macroHookWndBaseReturn(TRUE);
  3314.                     return HOOK_CAPTURE;
  3315.                 }
  3316.             }
  3317.             break;
  3318.         }
  3319.         case WM_TXWINDOWSIZE: {
  3320.             RECT* r0 = (RECT*)lParam;
  3321.             if (_hwndPreview) {//2.99 970318 
  3322.                 int cx = rectCx(r0);
  3323.                 int cy = rectCy(r0);
  3324.                 //
  3325.                 int rate = p_ratePreview;
  3326.                 if (_hwndPreviewPartition) {
  3327.                     rate = SendMessage(_hwndPreviewPartition,WMPB_GETRATE,0,0);
  3328.                     if (rate < 0) {
  3329.                         SendMessage(_hwndPreviewPartition,WMPB_SETRATE,rate = p_ratePreview,0);
  3330.                     }
  3331.                     SendMessage(_hwndPreviewPartition,WMPB_SETRANGE,r0->top,r0->bottom);
  3332.                 }
  3333.                 if (rate < 10 || rate > 90) rate = DEFAULT_PREVIEW_RATE;
  3334.                 p_ratePreview = rate;
  3335.                 //
  3336.                 int cyPreview = (cy * (100-rate)) / 100;
  3337.                 r0->bottom -= cyPreview;
  3338.                 int y = r0->bottom;
  3339.                 MoveWindow(_hwndPreviewPartition,r0->left,y,cx,5,TRUE);
  3340.                 y += 5;
  3341.                 cyPreview -= 5;
  3342.                 MoveWindow(_hwndPreview,r0->left,y,cx,cyPreview,TRUE);
  3343.             }
  3344.             RECT r = *r0;
  3345.             int cyInfo = infoGetCy();
  3346.             int cx = rectCx(&r);
  3347.             int cy = rectCy(&r);
  3348.             int y = r.top;
  3349.             int x = r.left;
  3350.             
  3351.             if (p_fDouble) {
  3352.                 int rate = p_rateDouble;
  3353.                 if (_hwndPartition) {
  3354.                     rate = SendMessage(_hwndPartition,WMPB_GETRATE,0,0);
  3355.                     if (rate < 0) {
  3356.                         SendMessage(_hwndPartition,WMPB_SETRATE,rate = p_rateDouble,0);
  3357.                     }
  3358. #if 1//2.99 970318 特に上下に分割でツールバー等を表示してるとずれた
  3359.                     if (p_fDoubleH) {
  3360.                         SendMessage(_hwndPartition,WMPB_SETRANGE,r.top,r.bottom);
  3361.                     } else {
  3362.                         SendMessage(_hwndPartition,WMPB_SETRANGE,r.left,r.right);
  3363.                     }
  3364. #else
  3365.                     if (p_fDoubleH) {
  3366.                         SendMessage(_hwndPartition,WMPB_SETRANGE,0,cy);
  3367.                     } else {
  3368.                         SendMessage(_hwndPartition,WMPB_SETRANGE,0,cx);
  3369.                     }
  3370. #endif
  3371.                 }
  3372.                 if (rate < 10 || rate > 90) rate = 50;
  3373.                 p_rateDouble = rate;
  3374.                 //
  3375.                 if (p_fDoubleH) {
  3376.                     int cy1 = (long)cy * rate / 100;
  3377.                     MoveWindow(filer1->hwndInfo,x,y,cx,cyInfo,TRUE);y += cyInfo;cy1 -= cyInfo;
  3378.                     MoveWindow(filer1->text->hwndtext,x,y,cx,cy1,TRUE);y += cy1;
  3379.                     //
  3380.                     MoveWindow(_hwndPartition,x,y,cx,5,TRUE);y += 5;
  3381.                     //
  3382.                     MoveWindow(filer2->hwndInfo,x,y,cx,cyInfo,TRUE);y += cyInfo;
  3383.                     MoveWindow(filer2->text->hwndtext,x,y,cx,r.bottom - y,TRUE);
  3384.                 } else {
  3385.                     int cxPartition = 5;
  3386.                     int cx1 = (long)cx * rate / 100;
  3387.                     MoveWindow(filer1->hwndInfo,x,y,cx1,cyInfo,TRUE);y += cyInfo;
  3388.                     MoveWindow(filer1->text->hwndtext,x,y,cx1,r.bottom - y,TRUE);
  3389.                     x += cx1;
  3390.                     //
  3391.                     MoveWindow(_hwndPartition,x,r.top,cxPartition,rectCy(&r),TRUE);
  3392.                     x += cxPartition;
  3393.                     //
  3394.                     int cx2 = r.right - x;
  3395.                     y = r.top;
  3396.                     MoveWindow(filer2->hwndInfo,x,y,cx2,cyInfo,TRUE);y += cyInfo;
  3397.                     MoveWindow(filer2->text->hwndtext,x,y,cx2,r.bottom - y,TRUE);
  3398.                 }
  3399.             } else {
  3400.                 MoveWindow(filer1->hwndInfo,r.left,y,cx,cyInfo,TRUE);y += cyInfo;
  3401.                 MoveWindow(filer1->text->hwndtext,r.left,y,cx,r.bottom - y,TRUE);
  3402.                 //
  3403.                 if (_hwndPartition) MoveWindow(_hwndPartition,-1,-1,0,0,FALSE);
  3404.                 MoveWindow(filer2->hwndInfo,-1,-1,0,0,FALSE);
  3405.                 MoveWindow(filer2->text->hwndtext,-1,-1,0,0,FALSE);
  3406.             }
  3407.             return TRUE;
  3408.         }
  3409.         case WM_SETFOCUS: {
  3410.             if (_textFiler->hwndLastFocus == filer2->text->hwndtext) {
  3411.                 filerSetFocus(filer2);
  3412.             } else {
  3413.                 filerSetFocus(filer1);
  3414.             }
  3415.             return TRUE;
  3416.         }
  3417.         case WM_SIZE://1.01A 
  3418.         case WM_MOVE: {
  3419. #if 1//3.00A3 970508 95のタスクバーを左においているとWZ Filerのウィンドウ位置がずれた。
  3420.             if (p_fSaveWindowPos) {
  3421.                 RECT r;
  3422.                 GetWindowRect(hwnd,&r);
  3423.                 if (!IsIconic(hwnd) && !IsZoomed(hwnd)) {
  3424.                     p_xWindow = r.left;
  3425.                     p_yWindow = r.top;
  3426.                     p_cxWindow = rectCx(&r);
  3427.                     p_cyWindow = rectCy(&r);
  3428.                 }
  3429.             }
  3430. #else
  3431.             if (p_fSaveWindowPos) {
  3432.                 // ファイラーをアイコン化して終了しても、
  3433.                 // アイコン化する前の位置に保存されるようにGetWindowPlacementを使う。
  3434.                 WINDOWPLACEMENT wplace;
  3435.                 wplace.length = sizeof(WINDOWPLACEMENT);
  3436.                 GetWindowPlacement(hwnd,(LPWINDOWPLACEMENT)&wplace);
  3437.                 RECT* r = &wplace.rcNormalPosition;
  3438.                 p_xWindow = r->left;
  3439.                 p_yWindow = r->top;
  3440.                 p_cxWindow = rectCx(r);
  3441.                 p_cyWindow = rectCy(r);
  3442.             }
  3443. #endif
  3444.             break;
  3445.         }
  3446.         case WM_TXCLOSE: {//2.99 970318 
  3447.             previewClose();
  3448.             break;
  3449.         }
  3450.     }
  3451.     return FALSE;
  3452. }
  3453.  
  3454. static void cmdline(mchar* szcmdline,BOOL fMultiOpen)
  3455. {
  3456. // fMultiOpen:ファイラーが起動されててvzuiOpenなどでファイラーを起動した場合、
  3457. // ファイラーを終了しない。
  3458.     // init
  3459.     _fOpenClose = FALSE;
  3460.     _fReadOnly = FALSE;
  3461.     // analyze
  3462.     mchar*p = szcmdline;
  3463.     while(1) {
  3464.         p = strGetWordTop(p);
  3465.         if (*p == 0) break;
  3466.         int len = strGetWordLen(p);
  3467.         mchar sw = 0;
  3468.         if (p[0] == '-' && (sw = p[1])) {
  3469.             p += 2;
  3470.             len -= 2;
  3471.             switch(sw) {
  3472.                 case 'c': {
  3473.                     if (!fMultiOpen) {
  3474.                         _fEscClose = TRUE;
  3475.                         _fOpenClose = TRUE;
  3476.                     }
  3477.                     break;
  3478.                 }
  3479.                 case 'e': {
  3480.                     if (!fMultiOpen) {
  3481.                         _fEscClose = TRUE;
  3482.                     }
  3483.                     break;
  3484.                 }
  3485.                 case 'f': {
  3486.                     mchar szfilename[CCHPATHNAME];
  3487.                     strcpylen(szfilename,p,len);
  3488.                     pathFormLong(szfilename);
  3489.                     if (szfilename[0] == 0) {
  3490.                         // ファイラー起動中にエディタからVZライクファイルオープンダイアログで
  3491.                         // リターンのみを入力してファイラーをアクティブにした際、
  3492.                         // ファイラーのディレクトリを移動しないようにした
  3493.                     } else {
  3494.                         filerSetPath(filerGetFocus(),szfilename);
  3495.                     }
  3496.                     break;
  3497.                 }
  3498.                 case 'O': {
  3499.                     // ウィンドウの親子関連付けはしない
  3500.                     // 関連付けを外すことができない様だ。
  3501.                     while(len) {
  3502.                         _hwndParent = (HWND)((UINT)_hwndParent * 10 + *p++ - '0');//1.00F
  3503.                         len--;
  3504.                     }
  3505.                     break;
  3506.                 }
  3507.                 case 'r': {
  3508.                     _fReadOnly = TRUE;
  3509.                     break;
  3510.                 }
  3511.             }
  3512.         }
  3513.         p += len;
  3514.     }
  3515. }
  3516.  
  3517. static void filerInit(FILER* filer)
  3518. {
  3519.     sstrcpy(filer->szPath,filer == filer1 ? p_szPath1 : p_szPath2);
  3520.     sstrcpy(filer->szMask,filer == filer1 ? p_szMask1 : p_szMask2);
  3521.     if (!filer->szPath[0]) {
  3522.         filerInitPath(filer);
  3523.     }
  3524.     if (!filer->szMask[0]) {
  3525.         sstrcpy(filer->szMask,"*.*");
  3526.     }
  3527. }
  3528.  
  3529. __txedelete
  3530. {
  3531.     if (_szClassInfo != "") {
  3532.         wndUnregisterClass(_szClassInfo);
  3533.         _szClassInfo = "";
  3534.     }
  3535.     macroHookWndBaseFree();
  3536.     macroHookWndTextFree();
  3537.     p_szPath1 = filer1->szPath;
  3538.     p_szMask1 = filer1->szMask;
  3539.     p_szPath2 = filer2->szPath;
  3540.     p_szMask2 = filer2->szMask;
  3541. }
  3542.  
  3543.  
  3544. static void sysmenuAdd(HMENU hmenu,int ipos,mchar* szcmd,mchar* szCaption)
  3545. {
  3546.     InsertMenu(
  3547.         hmenu,
  3548.         ipos,MF_BYPOSITION,
  3549.         IDM_WZCMDTOP + wzcmdRegister(szcmd),
  3550.         szCaption
  3551.     );
  3552. }
  3553.  
  3554. static void sysmenuCreate(void)
  3555. {
  3556.     HMENU hmenu = GetSystemMenu(_textFiler->hwndbase,FALSE);
  3557. //    RemoveMenu(hmenu, SC_ICON, MF_BYCOMMAND);
  3558. //    RemoveMenu(hmenu, SC_ZOOM, MF_BYCOMMAND);
  3559. //    RemoveMenu(hmenu, SC_SIZE, MF_BYCOMMAND);    //1.00E サイズ変更できなくなってしまう
  3560.     sysmenuAdd(hmenu,0,"txOpenNew","新規作成(&E)");
  3561.     sysmenuAdd(hmenu,1,"txuiOpen","ファイルを開く(&O)...");
  3562.     sysmenuAdd(hmenu,2,"file.uiPrjOpen","プロジェクトを開く(&P)...");
  3563.     sysmenuAdd(hmenu,3,"grep.txe","Grep検索(&G)");
  3564.     InsertMenu(hmenu,4,MF_BYPOSITION | MF_SEPARATOR,0,NULL);
  3565. }
  3566.  
  3567. __txenew
  3568. {
  3569.     _textFiler = text;
  3570.     text->modeImeSetFocus = ISF_OFF;//2.99D 970402 filerを開いたときIMEをOFFにした
  3571.     macroHookWndBase();
  3572.     macroHookWndText();
  3573.     wndRegisterClass("\m.wndprocInfo",_szClassInfo);
  3574.     sysmenuCreate();
  3575.     text->fTxeNoWindowPos = TRUE;
  3576.     text->fConfigInlineform = FALSE;//2.98 970310 
  3577.     //
  3578.     txSetFilerDisp(text);
  3579.     txSetFilerUI(text);
  3580.     //
  3581.     text->fNoWndText = TRUE;
  3582.     //3.00A3 970508 
  3583.     txSetFilerStatusbar(text);
  3584.     //
  3585.     fileratrInit();
  3586.     filerInit(filer1);
  3587.     filerInit(filer2);
  3588.     filerNewText(filer1);
  3589.     filerNewText(filer2);
  3590.     //2.99B 970322 
  3591.     filerSetModesort(filer1);
  3592.     filerSetModesort(filer2);
  3593.     //
  3594.     _hwndPartition = CreateWindow(
  3595.         TXPARTITION_SZCLASS,NULL,
  3596.         WS_CHILDWINDOW | WS_VISIBLE,
  3597.         CW_USEDEFAULT,CW_USEDEFAULT,
  3598.         CW_USEDEFAULT,CW_USEDEFAULT,
  3599.         _textFiler->hwndbase,
  3600.         NULL,
  3601.         _textFiler->hInstance,
  3602.         NULL
  3603.     );
  3604.     if (p_fSaveWindowPos) {
  3605.         wndtxMove(_textFiler->hwndbase,p_xWindow,p_yWindow,p_cxWindow,p_cyWindow,TRUE);
  3606.     }
  3607. }
  3608.  
  3609. BOOL __txeclosemulti(HWND hwndprev)
  3610. {
  3611.     // コマンドラインを解釈させる
  3612.     wndtxSendStr(hwndprev,WM_COMMAND,IDM_CMDLINE,text->szCmdLine);
  3613.     // hwndprevをアクティブにする
  3614.     PostMessage(hwndprev,WM_TXACTIVE,0,0);//3.00A2 970504 
  3615.     return TRUE;
  3616. }
  3617.  
  3618. main
  3619. {
  3620.     cmdline(_textFiler->szCmdLine,FALSE);
  3621.     filerLoadPath(filer1,FLP_JUMPFILETOP);
  3622.     if (p_fDouble) {
  3623.         filerLoadPath(filer2,FLP_JUMPFILETOP);
  3624.     }
  3625.     filerSetFocus(filer1);
  3626.     DoCaption();
  3627.     //
  3628.     if (p_fPreview) {//2.99 970318 
  3629.         preview();
  3630.         previewFlush();//3.00A3 970508 ファイラーを開いた時にプレビューをフラッシュ
  3631.     }
  3632. }
  3633.  
  3634. void test(void)
  3635. {
  3636. //dispinfo("abc");
  3637. //    information("%d",text->share->nOpen);
  3638. //information("%d",txKeyIsEdited(text));
  3639. //txQuit(_textFiler);
  3640. }
  3641.  
  3642. WORD at_cmdcheck(WZCMD wzcmd)
  3643. {
  3644.     mchar* szcmd = wzcmdToSzcmd(wzcmd);
  3645.     if (!szcmd) return 0;
  3646.     if (!stricmp(szcmd,"\m.preview")) {
  3647.         if (_hwndPreview) return MF_CHECKED;
  3648.     }
  3649.     return 0;
  3650. }
  3651.  
  3652.