home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1999 February / VPR9902A.BIN / APUPDATE / VC / Tx300d / TX300D.LZH / GREP.C < prev    next >
Text File  |  1997-10-17  |  37KB  |  1,382 lines

  1. // WZ Grep
  2. // Copyright 1995-97 TY
  3. // Thanks to: y.mikomeさん/M.Ishidaさん (古株順??)
  4.  
  5. //1.00D Grepでログファイルなど、
  6. // コントロールコード(例えば^H)が含まれるファイルが検索できなかったので、
  7. // "バイナリファイルも検索"オプションを追加した
  8. //1.00H2 ロングファイル名対応のため、マスク表示をやめるなど全面改良
  9. //2.92 全面改良
  10. //2.92 Grep置換機能を新設
  11. //2.94 970121 高速オープン対応
  12. //2.99F 970404 Grep置換機能は、UNIX/MACファイル確認動作が不安定だったのを修正したあおりで、動作しなくなり、やむなく削除。
  13. //3.00A 970428 Grep置換機能実装
  14.  
  15. //{###検索・置換}
  16.  
  17. #pragma TXE
  18.  
  19. #include <windows.h>
  20. #include <windowsx.h>
  21. #include "dialog.h"
  22. #include "search.txh"
  23. #include "_filer.h"
  24. #include "prof.h"
  25.  
  26. #define IDM_CMDLINE            100
  27. #define IDM_UIGREP            101
  28.  
  29. #define IDD_SZPATH            101
  30. #define IDD_SEARCHINFO        102
  31. #define IDD_TOREPLACE        103
  32.  
  33. // search.cと同じ
  34. #define IDD_SZFIND            3000
  35. #define IDD_SZREPLACE        3001
  36. #define IDD_REFERSEARCHLIST    3002
  37. extern "search" BOOL dlgprocSearch(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
  38.  
  39. // for cmdline指定を優先させる
  40. static txstr _cmdline_szpath(500);                //
  41. static txstr _cmdline_szsearch(CCHWORD);        //1.00F 文字列選択状態でWZ Grepを起動すると検索文字列に取り込みます。
  42. static BOOL _cmdline_fSearchDirectory;            //
  43. //
  44. static SEARCHOPT _searchopt;            //1.96 検索オプション
  45. static BOOL _fReplace = FALSE;            //2.92 置換?
  46. static TX* _textGrep;                    //2.94 970121 grep text
  47. // preview
  48. #define DEFAULT_PREVIEW_RATE    70
  49. static HWND _hwndPreview;                //2.99 970317 preview dialog
  50. static HWND _hwndPreviewPartition;        //2.99 970318 partition grep,preview
  51. permanent BOOL p_fPreview = TRUE;        //2.99 970318 
  52. permanent int p_ratePreview = DEFAULT_PREVIEW_RATE;//2.99 970318 プレビュー時のMainWindowの比率
  53.  
  54. typedef struct {
  55.     BOOL fEcho;        // 付属情報も出力?
  56.     int nfind;        // 見つけた数
  57.     BBOOL modeDisp;    // 見つけた内容の表示モード
  58. } GREPCONTEXT;
  59. static GREPCONTEXT _context;
  60.  
  61. static HWND _hdlg;            // Grep中ダイアログボックス
  62. static mchar *szworking = " Grep:検索中...";
  63. //3.00B1 970613 Grepの検索ボックスのフォントもテキストと同じにできるようにした
  64. static BOOL _fsetfontSearch;
  65. static BOOL _fsetfontReplace;
  66.  
  67. //##ユーザアボート
  68.  
  69. static BOOL _fUserAbort;
  70.  
  71. static BOOL AbortProc(void)
  72. {
  73.     MSG msg;
  74.     while(!_fUserAbort && _hdlg && PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
  75.         if (!IsDialogMessage(_hdlg,&msg)) {
  76.             TranslateMessage(&msg);
  77.             DispatchMessage(&msg);
  78.         }
  79.     }
  80.     return !_fUserAbort;
  81. }
  82.  
  83. //##grep main
  84.  
  85. static void grepafile(mchar *szfilename,mchar *szfind,DWORD searchmode,GREPCONTEXT* context,mchar* szReplace)
  86. {
  87.     TX* text = _textGrep;//2.96 970205 grep置換のバグ修正
  88.     //
  89.     if (!(searchmode & GREP_BACKUP)) {//2.92 
  90.         mchar* sz = pathGetFileName(szfilename);
  91.         if (sz[0] == '$' && sz[1] == '~') return;
  92.         sz = pathGetExt(szfilename);
  93.         if (sz[0] == '~') return;
  94.     }
  95.     TX _textBody2;//2.96 970205 
  96.     TX* text2 = &_textBody2;
  97.     txInitText(text2);
  98.     txSetFileName(text2,szfilename);
  99.     if (!(searchmode & GREP_BINARY) && txIsBinary(text2)) return;    // 開く前にファイル名でチェック
  100.     text2->fSilent = TRUE;    // 不要なattentionを出さない
  101.     //
  102.     text2->fLineD = FALSE;        // 論理行モード
  103.     text2->fViewMode = TRUE;
  104.     text2->fNoCursor = TRUE;    //3.00C 971013 マウスカーソルのちらつきを改善
  105.     searchmode |= SEARCH_CUR;    // 最初は、カーソル位置(ファイル先頭)から検索
  106.     //
  107.     BOOL fFirstFind = TRUE;
  108. #if 1//3.00B1 970612 Grepで漢字コードの自動判別効いてなかった
  109.     text2->fKcAuto = text->share->config.fKcAuto;//1.97 
  110. #else
  111.     text->fKcAuto = text->share->config.fKcAuto;//1.97 
  112. #endif
  113.     text2->fBinary = TRUE;    //3.00C 971013 バイナリファイルを検索しても無限ループにならないように
  114.     txOpenText(text2);
  115.     if ((searchmode & GREP_BINARY) || !txIsBinary(text2)) {
  116.         IFILE adr0 = -1;
  117.         txstr szfindstr(200);
  118.         txstr szpara(2048);//2.92 
  119.         SetDlgItemText(_hdlg,IDD_SEARCHINFO,pathGetFileName(szfilename));
  120.         //3.00A 970428 
  121.         REPLACECONTEXT rc;
  122.         if (szReplace) {
  123.             structClear(rc);
  124.             rc.text = text2;
  125.             sstrcpy(rc.szReplace,szReplace);
  126.             rc.lchReplace = strlen(rc.szReplace);
  127.             rc.fGrepReplace = TRUE;
  128.             text2->rc = &rc;
  129.         }
  130.         //
  131.         while(1) {
  132.             int retFind;
  133.             if (!AbortProc()) break;
  134.             if (retFind = txSearchEx(text2,szfind,searchmode)) {
  135.                 WORD sizex = txGetAddress(text2) - txGetParaTop(text2);
  136.                 
  137.                 {//1.00C 無限に同じ所にマッチすることがあった
  138.                     IFILE adr = txGetAddress(text2);
  139.                     if (adr == adr0) break;
  140.                     adr0 = adr;
  141.                 }
  142.                 {
  143.                     if (context->fEcho) {
  144.                         if (fFirstFind) {
  145.                             txInsertLine(text,"%s\"%s\"",text->tsztitle[0],szfilename);
  146.                         }
  147.                         if (szReplace) {
  148.                             mchar* szReplace1 = szReplace;
  149.                             if (rc.fGrepReplaceTag) {
  150.                                 szReplace1 = rc.rarg.szReplace;
  151.                             }
  152.                             szfindstr = "";
  153.                             if (retFind) txGetBuff(text2,retFind-1,szfindstr,cchtxstr(szfindstr));
  154.                             txInsertf(text,"・a%-10d: (%d,%d,%d)%s -> ",txGetAddress(text2),retFind,strlen(szfindstr),strlen(szReplace1),szfindstr);
  155.                             txInsert(text,szReplace1);
  156.                         } else {
  157.                             switch(context->modeDisp) {
  158.                                 case 0:txGetLine(text2,szfindstr);break;
  159.                                 case 1:txGetLineRear(text2,szfindstr);break;
  160.                                 case 2:szfindstr = "";break;
  161.                             }
  162.                             txInsertf(text,"・%5d,%-4d: %s",text2->npara,sizex,szfindstr);
  163.                             if (context->modeDisp == 2) {
  164.                                 txGetPara(text2,szpara);
  165.                                 txInsert(text,szpara);
  166.                             }
  167.                         }
  168.                         txInsertReturn(text);
  169.                     } else {
  170.                         // 古い形式を使う
  171.                         // ファイル名を""でくくってロングファイル対応はする
  172.                         txInsertLine(text,"\"%s\" %5d,%4d:",szfilename,text2->npara,sizex);
  173.                     }
  174.                     context->nfind++;
  175.                     fFirstFind = FALSE;
  176.                 }
  177.                 searchmode &= ~SEARCH_CUR;
  178.                 // 次からは、カーソル位置の次の文字から検索
  179.             } else {
  180.                 break;
  181.             }
  182.         }
  183.         //3.00A 970428 
  184.         text2->rc = NULL;
  185.     }
  186.     txClose(text2);
  187. }
  188.  
  189. static void greppath(mchar *szpath,mchar *szfind,DWORD searchmode,GREPCONTEXT* context,mchar* szReplace)
  190. {
  191.     #ifdef __FLAT__
  192.     WIN32_FIND_DATA ffd;
  193.     #else
  194.     FILEFIND filefind;
  195.     #endif
  196.     mchar szfilename[CCHPATHNAME];
  197.     
  198.     // 通常ファイル
  199.     strcpy(szfilename,szpath);
  200.     #ifdef __FLAT__
  201.     {
  202.         HANDLE hfind = FindFirstFile(szpath,&ffd);
  203.         if (hfind != INVALID_HANDLE_VALUE) {
  204.             do {
  205.                 if (!AbortProc()) break;
  206.                 if (context->fEcho) statprintf(szworking);
  207.                 if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
  208.                 pathSetFileName(szfilename,ffd.cFileName);
  209.                 grepafile(szfilename,szfind,searchmode,context,szReplace);
  210.             } while(FindNextFile(hfind,&ffd));
  211.             FindClose(hfind);
  212.         }
  213.     }
  214.     #else
  215.     if (!fileFindFirst(szpath,FA_NORMAL,&filefind)) {
  216.         do {
  217.             if (!AbortProc()) break;
  218.             if (context->fEcho) statprintf(szworking);
  219.             pathSetFileName(szfilename,filefind.name);
  220.             grepafile(szfilename,szfind,searchmode,context,szReplace);
  221.         } while (!fileFindNext(&filefind));
  222.     }
  223.     #endif
  224.     // サブディレクトリ
  225.     if (searchmode & GREP_DIRECTORY) {
  226.         strcpy(szfilename,szpath);
  227.         pathSetFileName(szfilename,"*.*");
  228.         #ifdef __FLAT__
  229.             {
  230.                 HANDLE hfind = FindFirstFile(szfilename,&ffd);
  231.                 if (hfind != INVALID_HANDLE_VALUE) {
  232.                     do {
  233.                         if (!AbortProc()) break;
  234.                         if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  235.                             if (ffd.cFileName[0] != '.') {
  236.                                 txstr szsubpath(CCHPATHNAME);
  237.                                 szsubpath = szpath;
  238.                                 pathSetFileName(szsubpath,ffd.cFileName + "\\" + pathGetFileName(szsubpath));
  239. //                                information("[%s]",szsubpath);
  240.                                 greppath(szsubpath,szfind,searchmode,context,szReplace);
  241.                             }
  242.                         }
  243.                     } while(FindNextFile(hfind,&ffd));
  244.                     FindClose(hfind);
  245.                 }
  246.             }
  247.         #else
  248.         if (!fileFindFirst(szfilename,FA_DIREC,&filefind)) {
  249.             do {
  250.                 if (!AbortProc()) break;
  251.                 if (filefind.attrib & FA_DIREC) {
  252.                     if (filefind.name[0] != '.') {
  253.                         txstr szsubpath(CCHPATHNAME);
  254.                         szsubpath = szpath;
  255.                         pathSetFileName(szsubpath,filefind.name + "\\" + pathGetFileName(szsubpath));
  256. //                        information("[%s]",szsubpath);
  257.                         greppath(szsubpath,szfind,searchmode,context,szReplace);
  258.                     }
  259.                 }
  260.             } while (!fileFindNext(&filefind));
  261.         }
  262.         #endif
  263.     }
  264. }
  265.  
  266. BOOL dlgprocGreping(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  267. {
  268.     switch(message) {
  269.         case WM_INITDIALOG: {
  270.             _fUserAbort = FALSE;
  271.             //2.92 "検索中"の表示位置改善
  272.             // 中途半端な位置に表示されていて、Grepの動作が重くなっていた
  273.             RECT r;
  274.             GetClientRect(hwnd,&r);
  275.             int cx = r.right;
  276.             GetWindowRect(_textGrep->hwndtext,&r);
  277.             SetWindowPos(hwnd,NULL,r.left+(rectCx(&r)-cx)/2,r.top,0,0,SWP_NOSIZE|SWP_NOZORDER);
  278.             break;
  279.         }
  280.         case WM_COMMAND: {
  281.             if (LOWORD(wParam) == IDCANCEL) {
  282.                 _fUserAbort = TRUE;
  283.                 return TRUE;
  284.             }
  285.             break;
  286.         }
  287.     }
  288.     return FALSE;
  289. }
  290.  
  291. permanent BOOL p_fNoGrepReplaceMsg;//3.00A3 970507 
  292.  
  293. static int _grep(TX *text,mchar *szpathBase,mchar *szfind,DWORD searchmode,GREPCONTEXT* context,mchar* szReplace)
  294. {
  295. //1.00H4 空白を含むパス内の検索ができなかったので修正
  296.     // textをクリア
  297.     text->fNomoveBase = TRUE;//2.94 970121 
  298.     context->nfind = 0;
  299.     txDeleteText(text);
  300.     txJumpFileTop(text);
  301.     if (context->fEcho) statprintf(szworking);
  302.     //1.00C grepを中止できるようにした
  303.     HDIALOG hd = dialog("検索中");
  304.     dialogSetHookEx(hd,"\m.dlgprocGreping");
  305.     //1.00H4 検索中のファイル名を表示するようにした。
  306.     dialogControlStyle(hd,WS_CHILD|WS_VISIBLE|SS_CENTER);
  307.     dialogControlID(hd,IDD_SEARCHINFO);
  308.     dialogCaptionDynamic(hd,"",30);
  309.     dialogControlStyle(hd,0);
  310.     //
  311.     dialogSetPosLX(hd,10);
  312.     dialogCancel(hd,10);
  313.     //
  314.     _hdlg = dialogCreate(hd);
  315.     EnableWindow(text->hwndbase,FALSE);
  316. //    text->txmode |= TXMODE_SCROLLHIGH;//1.00F スクロールを真面目にやってると遅い
  317.     //
  318.     {
  319.         mchar *p = szpathBase;
  320.         
  321.         while(*p) {
  322.             p = strGetWordTop(p);
  323.             int len = strGetWordLen(p);
  324.             mchar szitem[CCHPATHNAME];
  325.             
  326.             if (len == 0) break;//1.01A "*.* "の様に最後にスペースを開けると\から検索してしまっていた
  327.             strcpylen(szitem,p,len);
  328.             p += len;
  329.             // パスを正規化
  330.             pathFormLong(szitem);
  331.             pathSetFull(szitem);
  332.             if (!pathIsWild(szitem) && pathDirExist(szitem)) {
  333.                 // "a:\wz"のような指定がされた場合...
  334.                 strcat(szitem,\"\*.*");
  335.             }
  336.             {//1.00C 検索パスを"a:\wz\*.c;*.h"の様に指定することができるようにした
  337.                 mchar szpath[CCHPATHNAME];
  338.                 mchar *szfile = pathGetFileName(szitem);
  339.                 strcpy(szpath,szitem);
  340.                 while(1) {
  341.                     if (!AbortProc()) break;
  342.                     mchar *p;
  343.                     if (p = strchr(szfile,';')) {
  344.                         *p = 0;
  345.                     }
  346.                     pathSetFileName(szpath,szfile);
  347.                     greppath(szpath,szfind,searchmode,context,szReplace);
  348.                     if (p) {
  349.                         *p = ';';
  350.                         szfile = p + 1;
  351.                     } else {
  352.                         break;
  353.                     }
  354.                 }
  355.             }
  356.         }
  357.     }
  358.     //1.00C
  359.     EnableWindow(text->hwndbase,TRUE);
  360.     if (_hdlg) {
  361.         dialogFree(_hdlg);
  362.         _hdlg = NULL;
  363.     }
  364. //    text->txmode &= ~TXMODE_SCROLLHIGH;//1.00F
  365.     //
  366.     txSetUndispSilent(text);    //3.00C 971013 Silent
  367.     if (context->fEcho) {
  368.         txInsertReturn(text);
  369.         if (_fUserAbort) {
  370.             txInsertLine(text,"検索を中止しました。");
  371.         } else {
  372.             txInsertLine(text,"検索が終了しました。");
  373.         }
  374.         if (context->nfind) {
  375.             txInsertf(text," %d個 見つけました。",context->nfind);
  376.             if (szReplace) {//3.00A3 970507 
  377.                 if (!p_fNoGrepReplaceMsg) {
  378.                     HDIALOG hd = dialog("WZ Grep 置換");
  379.                     dialogCaption(hd,"置換を行うには、置換したい行にカーソルを合わせて、");
  380.                     dialogCaption(hd,"{Shift}+{Enter}します。");
  381.                     dialogCaption(hd,"置換すると直ちにファイルの内容を書き換えますので、");
  382.                     dialogCaption(hd,"注意してください。");
  383.                     dialogCheck(hd,"今後、このメッセージを表示しない",&p_fNoGrepReplaceMsg);
  384.                     dialogLFV(hd);
  385.                     //
  386.                     dialogControlID(hd,IDOK);
  387.                     dialogCmd(hd,"閉じる",12);
  388.                     dialogHelp(hd,12,"wz.chp 507");
  389.                     dialogOpen(hd);
  390.                 }
  391.             }
  392.         } else {
  393.             txInsert(text," 見つかりませんでした。");
  394.         }
  395.     }
  396.     txJumpFileTop(text);
  397.     txSetDispSilent(text);    //3.00C 971013 Silent
  398.     text->fEdit = FALSE;
  399.     text->fNomoveBase = FALSE;//2.94 970121 
  400.     return context->nfind;
  401. }
  402.  
  403. int TXAPI grep(TX *text,mchar *szpathBase,mchar *szfind,DWORD searchmode)
  404. {
  405. // 検索パス:szpath,検索文字列szfindで、grepします。
  406. // 見つかったタグ数を返します。
  407. // 結果は、textに次のように入ります。
  408. //        ファイル名(フルパス)  論理行番号,論理行頭からバイト数: 行内容[改行]
  409. // 元のtextの内容は全部削除されます
  410. //1.00H2 検索オプションは、searchmodeで指定するように仕様を変更しました。
  411.     GREPCONTEXT context;
  412.     structClear(context);
  413.     return _grep(text,szpathBase,szfind,searchmode,&context,NULL);
  414. }
  415.  
  416. static BOOL editboxIsEmpty(HWND hctrl)
  417. {
  418.     if (hctrl) {
  419.         mchar buff[CCHWORD];
  420.         GetWindowText(hctrl,buff,CCHWORD);
  421.         return !buff[0];
  422.     }
  423.     return TRUE;
  424. }
  425.  
  426. BOOL dlgprocGrep(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  427. {
  428.     switch(message) {
  429.         case WM_INITDIALOG: {//3.00B1 970613 
  430.             _fsetfontSearch = wndSetFontAsText(GetDlgItem(hwnd,IDD_SZFIND),textf);
  431.             _fsetfontReplace = wndSetFontAsText(GetDlgItem(hwnd,IDD_SZREPLACE),textf);
  432.             break;
  433.         }
  434.         case WM_DESTROY: {//3.00B1 970613 
  435.             if (_fsetfontSearch) {
  436.                 _fsetfontSearch = FALSE;
  437.                 wndSetFontAsTextDelete(GetDlgItem(hwnd,IDD_SZFIND));
  438.             }
  439.             if (_fsetfontReplace) {
  440.                 _fsetfontReplace = FALSE;
  441.                 wndSetFontAsTextDelete(GetDlgItem(hwnd,IDD_SZREPLACE));
  442.             }
  443.             break;
  444.         }
  445.         case WM_COMMAND: {
  446.             int id = WM_COMMAND_GetId(wParam);
  447.             int notify = WM_COMMAND_GetNotify(wParam,lParam);
  448.             
  449.             switch(id) {
  450.                 case IDOK: {
  451.                     if (editboxIsEmpty(GetDlgItem(hwnd,IDD_SZPATH))) {
  452.                         attention("検索パスを指定してください");
  453.                         return TRUE;
  454.                     }
  455.                     if (editboxIsEmpty(GetDlgItem(hwnd,IDD_SZFIND))) {
  456.                         attention("検索文字列を指定してください");
  457.                         return TRUE;
  458.                     }
  459.                     break;
  460.                 }
  461.             }
  462.             return dlgprocSearch(hwnd,message,wParam,lParam);
  463.             break;
  464.         }
  465.         case WM_TXUSER: {
  466.             return dlgprocSearch(hwnd,message,wParam,lParam);
  467.         }
  468.     }
  469.     return FALSE;
  470. }
  471.  
  472. typedef struct {
  473.     BOOL fSearchBinary;        // バイナリファイルも検索?
  474.     BOOL fSearchDirectory;    // サブディレクトリ内の検索?
  475.     BOOL fParaTop;            // 論理行頭のみの検索?
  476.     BOOL fSearchBackup;        //2.92 バックアップファイル、世代ファイルも検索?
  477. } GREPOPTION;
  478.  
  479. static int dialogaGrep(BOOL fReplace,txstr szPath,txstr szFind,txstr szReplace,GREPOPTION* option)
  480. {
  481.     TX* text = _textGrep;
  482.     //2.92 WZ Grep:検索パスは専用ヒストリに格納するようにした
  483.     static mchar _szhistid[] = "WZ Grep";
  484.     HSTRBLK sb = historyOpen(_szhistid,2048);
  485.     //
  486.     HDIALOG hd = dialogbig(fReplace ? "WZ Grep 置換" : "WZ Grep");
  487.     dialogSetHookEx(hd,"\m.dlgprocGrep");
  488.     dialogSetContexthelp(hd,TRUE);
  489.     
  490.     static mchar szinikey[] = "WZ Grep";
  491.     dialogSetIniEx(hd,"wz.ini",szinikey);    // wz.iniに保存
  492.     dialogSetGroupRight(hd,DTCX * 50);
  493.     //2.92 
  494.     static mchar szinikeyMode[] = "検索モード";
  495.     TxProfile prof;
  496.     profWzIniNew(&prof,szinikey);
  497.     _searchopt.category  = profReadInt(&prof,szinikeyMode,0);
  498.     static mchar szinikeyReplace[] = "置換";
  499.     profReadStr(&prof,szinikeyReplace,szReplace,cchtxstr(szReplace),"");
  500.     
  501.     if (fReplace) {//2.92 
  502.         dialogGroup(hd,"置換(&S)");
  503.             dialogControlIniKey(hd,"検索");
  504.             dialogControlHelp(hd,190);
  505.             dialogControlGuide(hd,"を",3);
  506.             dialogControlHistRead(hd,HIST_SEARCH);
  507.             dialogControlID(hd,IDD_SZFIND);
  508.             dialogStr(hd,NULL,szFind,0,42);
  509.             
  510.             dialogControlIniKey(hd,"置換");
  511.             dialogControlHelp(hd,191);
  512.             dialogControlGuide(hd,"へ",3);
  513.             dialogControlHistRead(hd,HIST_SEARCH);
  514.             dialogControlID(hd,IDD_SZREPLACE);//2.00B 
  515.             dialogStr(hd,NULL,szReplace,0,42);
  516.         dialogGroupEnd(hd);
  517.     } else {
  518.         dialogGroup(hd,"検索(&S)");
  519.             dialogControlIniKey(hd,"検索");
  520.             dialogControlHist(hd,HIST_SEARCH);
  521.             dialogControlHelp(hd,190);
  522.             dialogControlID(hd,IDD_SZFIND);
  523.             dialogStr(hd,NULL,szFind,0,46);
  524.             dialogSetFocus(hd,IDD_SZFIND);
  525.         dialogGroupEnd(hd);
  526.     }
  527.     dialogGroup(hd,"検索パス(&P)");
  528.         dialogControlHelp(hd,240);
  529.         dialogControlHist(hd,sb);
  530.         dialogControlRefer(hd,"-m *.*");
  531.         dialogControlID(hd,IDD_SZPATH);
  532.         dialogStr(hd,NULL,szPath,0,37);
  533.         #if 0//2.92 
  534.         dialogCaption(hd,\"<例1> c:\wz\*.txt");
  535.         dialogCaption(hd,\"<例2> c:\wz\*.txt;*.log");
  536.         #endif
  537.         //
  538.         dialogControlHelp(hd,241);
  539.         dialogCheck(hd,"サブディレクトリも検索(&U)",&option->fSearchDirectory);
  540.     dialogGroupEnd(hd);
  541.     
  542. #if 1//3.00A2 970505 
  543.     dialogSearchOption(hd,&_searchopt,fReplace ? SEARCH_REPLACE : 0);
  544. #else
  545.     dialogSearchOption(hd,&_searchopt,fReplace ? SEARCH_REPLACE|REPLACE_CONFIRM : 0);
  546. #endif
  547.     
  548.     dialogGroup(hd,"オプション");
  549.         dialogControlHelp(hd,242);
  550.         //2.92 論理行の全てをサポート
  551.         dialogSelectIDB(hd,"見つけた内容の表示(&D):",&_context.modeDisp,24,20,"表示行の全て","表示行末まで","論理行の全て");
  552.         dialogControlHelp(hd,243);
  553.         dialogCheck(hd,"論理行頭のみを検索(&T)",&option->fParaTop);
  554.         dialogControlHelp(hd,244);
  555.         dialogCheck(hd,"バイナリファイルも検索(&B)",&option->fSearchBinary);
  556.         dialogControlHelp(hd,244);
  557.         dialogCheck(hd,"バックアップファイルも検索(&G)",&option->fSearchBackup);
  558.     dialogGroupEnd(hd);
  559.     //
  560.     int cx = 14;
  561.     dialogLFV(hd);
  562.     dialogOK(hd,cx);
  563.     dialogCancel(hd,cx);
  564.     dialogControlID(hd,IDD_REFERSEARCHLIST);
  565.     dialogControlHelp(hd,203);
  566.     dialogCmd(hd,"検索リスト(&L)...",cx);
  567.     if (fReplace) {
  568.         dialogControlID(hd,IDD_TOREPLACE);
  569.         dialogCmd(hd,"検索(&R) >>",cx);
  570.     } else {
  571. #if 1//3.00A2 970505 Grep置換機能実装
  572.         dialogControlID(hd,IDD_TOREPLACE);
  573.         dialogCmd(hd,"置換(&R) >>",cx);
  574. #else
  575.     #if 0//2.99F 970404 Grep置換機能は動作していなかったので、外した
  576.         dialogControlID(hd,IDD_TOREPLACE);
  577.         dialogCmd(hd,"置換(&R) >>",cx);
  578.     #endif
  579. #endif
  580.     }
  581.     dialogSpaceV(hd);
  582. #if 1//3.00A2 970505 
  583.     if (fReplace) {
  584.         //3.00A3 970507 wz.chpヘルプ呼び出し簡素化
  585.         dialogHelp(hd,cx,"wz.chp 507");
  586.     } else {
  587.         dialogHelp(hd,cx,"wz 正規表現");
  588.     }
  589. #else
  590.     dialogHelp(hd,cx,"wz 正規表現");
  591. #endif
  592.     // load
  593.     dialogLoad(hd);
  594.     dialogSetLoad(hd,FALSE);
  595.     // cmdline
  596.     if (_cmdline_szpath != "") {
  597.         szPath = _cmdline_szpath;
  598.         _cmdline_szpath = "";//2.92 2回目以降は無効にする
  599.     }
  600.     if (_cmdline_szsearch != "") {
  601.         szFind = _cmdline_szsearch;
  602.         _cmdline_szsearch = "";//2.92 2回目以降は無効にする
  603.     }
  604.     if (_cmdline_fSearchDirectory) {
  605.         option->fSearchDirectory = TRUE;
  606.         _cmdline_fSearchDirectory = FALSE;//2.92 2回目以降は無効にする
  607.     }
  608.     // default
  609.     if (szPath == "") {
  610.         driveGetCurDir(0,szPath);
  611.         szPath += \"\*.*";
  612.     }
  613.     //2.99 970320 GrepダイアログではIMEの制御をしないようにした。
  614.     // つかいにくかった
  615.     text->fNoImeControl++;//2.99 970320 
  616.     int id = dialogOpen(hd);
  617.     text->fNoImeControl--;//2.99 970320 
  618.     //2.92 
  619.     historyClose(_szhistid,sb);
  620.     if (id) {
  621.         profWriteInt(&prof,szinikeyMode,_searchopt.category);
  622.         profWriteStr(&prof,szinikeyReplace,szReplace);
  623.     }
  624.     profDelete(&prof);
  625.     //
  626.     return id;
  627. }
  628.  
  629. //2.99C 970326 new
  630. permanent txstr _szFindColoring;
  631. permanent SEARCHMODE _searchmodeColoring;
  632.  
  633. mchar* gfc(SEARCHMODE* pSearchmode)
  634. {
  635. //2.99C 970326 new
  636.     *pSearchmode = _searchmodeColoring;
  637. //statprintf(_szFindColoring);wait(100);
  638.     return (mchar*)_szFindColoring;
  639. }
  640.  
  641. static BOOL _uiGrep(void)
  642. {
  643.     TX* text = _textGrep;
  644.     txstr szPath(500);
  645.     static txstr szFind;
  646.     static txstr szReplace;
  647.     GREPOPTION option;
  648.     structClear(option);
  649.     int id = 0;
  650.     while(1) {
  651.         id = dialogaGrep(_fReplace,szPath,szFind,szReplace,&option);
  652.         if (id == IDD_TOREPLACE) {
  653.             _fReplace ^= 1;
  654.         } else {
  655.             break;
  656.         }
  657.     }
  658.     if (id) {
  659.         DWORD searchmode = searchmodeFromSearchopt(&_searchopt);
  660.         if (option.fParaTop) searchmode |= SEARCH_PARATOP;
  661.         if (option.fSearchBinary) searchmode |= GREP_BINARY;
  662.         if (option.fSearchDirectory) searchmode |= GREP_DIRECTORY;
  663.         if (option.fSearchBackup) searchmode |= GREP_BACKUP;
  664.         searchmode &= ~SEARCH_ALLTEXT;//1.01A 
  665.         //
  666.         #ifdef __FLAT__
  667.         if (szPath[0] != '"') {
  668.             // ""で括る
  669.             szPath = "\"" + szPath + "\"";
  670.         }
  671.         #endif
  672.         //
  673.         text->fDispFindEnable = TRUE;//2.99C 970326 grepで検索文字色分けON
  674.         //2.99C 970326 grepの検索文字列色分けと、WZの検索文字列色分けを分離した
  675.         text->fDispFindGrep = TRUE;
  676.         _szFindColoring = szFind;
  677.         _searchmodeColoring = searchmode;
  678.         //
  679.         _context.fEcho = TRUE;
  680.         if (_fReplace) {
  681.             _grep(text,szPath,szFind,searchmode,&_context,szReplace);
  682.         } else {
  683.             _grep(text,szPath,szFind,searchmode,&_context,NULL);
  684.         }
  685.         txSave(text);//1.01A Grep:前回の結果を保存するようにした
  686.         //
  687.         return TRUE;
  688.     }
  689.     return FALSE;
  690. }
  691.  
  692. uiGrep
  693. {
  694.     BOOL ret = FALSE;
  695.     static BOOL _f = FALSE;    // 再入防止
  696.     if (!_f) {
  697.         _f = TRUE;
  698.         ret = _uiGrep();
  699.         _f = FALSE;
  700.     }
  701.     return ret;
  702. }
  703.  
  704. //##tag jump
  705.  
  706. static void getfilename(mchar szfilename[CCHPATHNAME],mchar* szline)
  707. {
  708.     mchar*p = szline;
  709.     p += strGetCharSize(p);
  710.     int len = strGetWordLen(p);
  711.     strcpylen(szfilename,p,len);
  712.     pathFormLong(szfilename);
  713. }
  714.  
  715. typedef struct {
  716.     mchar szfilename[CCHPATHNAME];
  717.     NPARA npara;
  718.     int lx;
  719.     //3.00A 970428 
  720.     BOOL fAddress;
  721.     IFILE address;
  722. } TAGANA;
  723.  
  724. static BOOL tagAnalyze(TAGANA* ana)
  725. {
  726. //2.99 970317 new
  727.     mchar szfilename[CCHPATHNAME] = {0};
  728.     txstr szline;
  729.     txGetLine(text,szline);
  730.     int npara = -1;
  731.     int lx = -1;
  732.     txstr szFind = text->tsztitle[0] + "\"";
  733.     structClear(*ana);//3.00A 970428 
  734.     
  735.     if (strmatch(szline,szFind)) {
  736.         //1.01A ●"ファイル名"の行にカーソルを置いてジャンプしたときは、そのファイルの1行目にジャンプするようにした
  737.         getfilename(szfilename,szline);
  738.         npara = 1;
  739.     } else if (strmatch(szline,"・")/*2.92*/) {
  740.         mchar* p = szline;
  741.         if (p[2] == 'a' && isdigit(p[3])) {
  742.             ana->fAddress = TRUE;
  743.             ana->address = atoi(&p[3]);
  744.             npara = 1;
  745.             lx = 0;
  746.         } else {
  747.             while(1) {
  748.                 mchar c = *p;
  749.                 if (c == 0) break;
  750.                 if (isdigit(c)) {
  751.                     if (npara == -1) {
  752.                         p += strNum(p,&npara);
  753.                     } else if (lx == -1) {
  754.                         p += strNum(p,&lx);
  755.                         break;
  756.                     } else {
  757.                         break;
  758.                     }
  759.                 } else {
  760.                     p++;
  761.                 }
  762.             }
  763.         }
  764.         txSetUndispExSilent(text);
  765.         if (txSearchEx(text,szFind,SEARCH_PREV|SEARCH_PARATOP)) {
  766.             txGetLine(text,szline);
  767.             getfilename(szfilename,szline);
  768.         }
  769.         txSetDispExSilent(text);
  770.     } else {//2.92 
  771.         return FALSE;
  772.     }
  773.     //
  774.     if (npara == -1) {
  775.         //2.92 
  776.         return FALSE;
  777.     }
  778.     //
  779.     if (lx == -1) lx = 0;
  780. //information("[%s] %ld %d",szfilename,npara,lx);
  781.     strcpy(ana->szfilename,szfilename);
  782.     ana->npara = npara;
  783.     ana->lx = lx;
  784.     return TRUE;
  785. }
  786.  
  787. //2.99 970317 renew
  788. Jump
  789. {
  790. // WZ Grep形式のタグジャンプ
  791.     TAGANA ana;
  792.     if (tagAnalyze(&ana)) {
  793.         if (ana.fAddress) {//3.00A 970428 
  794.             mchar sw[30];
  795.             sprintf(sw,"/k /Ja%ld /Yc",ana.address);
  796.             forkstd(ana.szfilename,sw);
  797.             return TRUE;
  798.         }
  799.         txJumpTagExec(text,ana.szfilename,ana.npara,ana.lx,NULL);
  800.         return TRUE;
  801.     }
  802.     return FALSE;
  803. }
  804.  
  805. //##preview
  806. //2.99 970317 
  807.  
  808. static void previewClose(void)
  809. {
  810.     if (_hwndPreview) {
  811.         DestroyWindow(_hwndPreview);
  812.         _hwndPreview = NULL;
  813.         if (_hwndPreviewPartition) {
  814.             DestroyWindow(_hwndPreviewPartition);
  815.             _hwndPreviewPartition = NULL;
  816.         }
  817.         //
  818.         _textGrep->txnMask = 0;
  819.         SendMessage(_textGrep->hwndbase,WM_TXFLUSHWINDOWSIZE,0,0);
  820.     }
  821. }
  822.  
  823. preview
  824. {
  825.     if (_hwndPreview) {
  826.         previewClose();
  827.         p_fPreview = FALSE;
  828.     } else {
  829.         _hwndPreview = CreateWindowEx(
  830.             #ifdef __FLAT__
  831.             (_fwin40 * WS_EX_CLIENTEDGE),
  832.             #else
  833.             0,
  834.             #endif
  835.             TXWS_SZCLASS,
  836.             NULL,
  837.             TXWS_TEXT|WS_VSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP,
  838.             CW_USEDEFAULT,CW_USEDEFAULT,
  839.             CW_USEDEFAULT,CW_USEDEFAULT,
  840.             _textGrep->hwndbase,
  841.             NULL,
  842.             _textGrep->hInstance,
  843.             NULL
  844.         );
  845.         if (_hwndPreview) {
  846.             _hwndPreviewPartition = CreateWindow(
  847.                 TXPARTITION_SZCLASS,NULL,
  848.                 WS_CHILDWINDOW | WS_VISIBLE,
  849.                 CW_USEDEFAULT,CW_USEDEFAULT,
  850.                 CW_USEDEFAULT,CW_USEDEFAULT,
  851.                 _textGrep->hwndbase,
  852.                 NULL,
  853.                 _textGrep->hInstance,
  854.                 NULL
  855.             );
  856.             //
  857.             TX* text = (LPVOID)SendMessage(_hwndPreview,TXWM_GETTX,0,0);
  858.             text->hwndbase = _textGrep->hwndbase;
  859.             text->txnMask = TXNM_CONTROLTAB|TXNM_CONTROLF4;
  860.             text->fKcAuto = text->share->config.fKcAuto;//3.00B1 970612 Grepプレビューでもconfig.fKcAutoを参照
  861.             text->fSpaceLeft = _textGrep->fSpaceLeft;//3.00B2 970616 
  862.             txOpenText(text);
  863.             //
  864.             _textGrep->txnMask = TXNM_CHANGENPARA|TXNM_CONTROLTAB;
  865.             SendMessage(_textGrep->hwndbase,WM_TXFLUSHWINDOWSIZE,0,0);
  866.             p_fPreview = TRUE;
  867.             text->fReadOnly = TRUE;//3.00B1 970612 Grepのプレビューウィンドウでfile.vzuiSaveするとGrep結果が上書きされたので、セーブできないようにした
  868.         }
  869.     }
  870. }
  871.  
  872. static void previewFlush(TAGANA* ana,BOOL fAnaOk,BOOL fForce)
  873. {
  874. //3.00A2 970505 new
  875.     if (_hwndPreview) {
  876.         TX* text = (LPVOID)SendMessage(_hwndPreview,TXWM_GETTX,0,0);
  877.         if (text) {
  878.             if (fAnaOk) {
  879.                 if (!fForce && !pathCmp(ana->szfilename,text->szfilename,NULL)) {
  880.                     // 現在開いている
  881.                 } else {
  882.                     txClose(text);
  883.                     txSetFileName(text,ana->szfilename);
  884.                     txOpenText(text);
  885.                     // read all for 排他制御
  886.                     txSetUndispSilent(text);
  887.                     txJumpFileEnd(text);
  888.                     txSetDispSilent(text);
  889.                 }
  890.                 txSetUndispSilent(text);
  891.                 if (ana->fAddress) {
  892.                     txJumpAddress(text,ana->address);
  893.                 } else {
  894.                     txJumpNpara(text,ana->npara);
  895.                     txRightBytes(text,ana->lx);
  896.                 }
  897.                 text->fDispFindEnable = TRUE;//2.99C 970326 プレビューで検索文字色分けON
  898.                 text->fDispFindGrep = TRUE;//2.99C 970326 
  899. #if 0    //2.99C 970326 選択すると使いにくい
  900.                 if (txRight(text)) {
  901.                     txSelectEx(text,CLIP_MOUSE);
  902.                     txLeft(text);
  903.                 }
  904. #endif
  905.                 txSetDispSilent(text);
  906.             } else {
  907.                 txClose(text);
  908.                 txOpenText(text);
  909.             }
  910.         }
  911.     }
  912. }
  913.  
  914. //##置換実行
  915. //3.00A2 970505 new
  916.  
  917. static int replaceCur(TX* text,BOOL fSilent)
  918. {
  919. // カーソル行の置換を実行
  920. // return IDYES:置換実行した IDNO:しなかった IDCANCEL:中止
  921.     BOOL ret = IDNO;
  922.     TAGANA ana;
  923.     if (tagAnalyze(&ana) && ana.fAddress) {
  924.         if (isopen(ana.szfilename)) {
  925.             information("%s はオープン中です。\n置換するには閉じてください",ana.szfilename);
  926.             return IDCANCEL;
  927.         }
  928.         txstr szline;
  929.         txGetPara(text,szline);
  930.         mchar* p = strchr(szline,'(');
  931.         if (p && toupper(p[-1]) == 'X') {
  932.             p = NULL;
  933.             if (!fSilent) information("既に置換したので、置換しません。");
  934.         }
  935.         if (p) {
  936.             p++;
  937.             int lchDelete1 = atoi(p);
  938.             p = strchr(p,',');
  939.             if (p) {
  940.                 p++;
  941.                 int lchFind = atoi(p);
  942.                 p = strchr(p,',');
  943.                 if (p) {
  944.                     p++;
  945.                     int lchReplace = atoi(p);
  946.                     p = strchr(p,')');
  947.                     if (p) {
  948.                         int lchSepa = 4;    // " -> "
  949.                         p++;
  950.                         if (strlen(p) == lchFind + lchSepa + lchReplace) {
  951.                             txstr szFind;
  952.                             txstr szReplace;
  953.                             txstrcpylen(szFind,p,lchFind);
  954.                             p += lchFind + lchSepa;
  955.                             txstrcpylen(szReplace,p,lchReplace);
  956. //information("%d %d %d %s %s",lchDelete1,lchFind,lchReplace,szFind,szReplace);
  957.                             int d = 0;
  958.                             BOOL fErr = FALSE;
  959.                             {
  960.                                 TX* text = textopen(ana.szfilename);
  961.                                 if (text) {
  962.                                     txJumpAddress(text,ana.address);
  963.                                     if (lchDelete1) {
  964.                                         if (txCmpCur(text,szFind)) {
  965.                                             int lch = lchDelete1 - 1;
  966.                                             txDeleteBytes(text,lch);d = -lch;
  967.                                         } else {
  968.                                             fErr = TRUE;
  969.                                             information("Grep検索置換を行ってから、内容が変更されています。置換しません。");
  970.                                         }
  971.                                     }
  972.                                     if (!fErr) {
  973.                                         ret = IDYES;
  974.                                         txInsert(text,szReplace);d += strlen(szReplace);
  975. //dialogaText(text,NULL);
  976.                                         txSave(text);
  977.                                     }
  978.                                     textclose(text);
  979.                                 }
  980.                             }
  981.                             if (!fErr) {
  982.                                 txSetUndisp(text);
  983.                                 NPARA npara = text->npara;
  984.                                 //
  985.                                 txJumpParaTop(text);
  986.                                 txSearchEx(text,"(",0);
  987.                                 txLeft(text);
  988.                                 txOverWriteChar(text,'x');
  989.                                 //
  990. //information("d = %d",d);
  991.                                 while(1) {
  992.                                     if (!txNextPara(text)) break;
  993.                                     TAGANA ana;
  994.                                     if (tagAnalyze(&ana) && ana.fAddress) {
  995.                                         txJumpParaTop(text);
  996.                                         txRight(text);
  997.                                         mchar buff[20];
  998.                                         sprintf(buff,"a%lu",(long)ana.address + d);
  999.                                         txOverWrite(text,buff);
  1000.                                     } else {
  1001.                                         break;
  1002.                                     }
  1003.                                 }
  1004.                                 //
  1005.                                 txJumpNpara(text,npara);
  1006.                                 // プレビューを更新
  1007.                                 if (!fSilent) {
  1008.                                     TAGANA ana;
  1009.                                     BOOL f = tagAnalyze(&ana);
  1010.                                     previewFlush(&ana,f,TRUE);
  1011.                                 }
  1012.                                 //
  1013.                                 txSetDisp(text);
  1014.                                 txSave(text);
  1015.                             }
  1016.                         }
  1017.                     }
  1018.                 }
  1019.             }
  1020.         }
  1021.     }
  1022.     return ret;
  1023. }
  1024.  
  1025. replace
  1026. {
  1027.     if (text->fClip) {
  1028.         int n = 0;
  1029.         txWalkStart(text);
  1030.         while(txIsWalking(text)) {
  1031.             int ret = replaceCur(text,TRUE);
  1032.             if (ret == IDCANCEL) break;
  1033.             if (ret == IDYES) n++;
  1034.             if (!txNextPara(text)) break;
  1035.         }
  1036.         txWalkEnd(text);
  1037.         //
  1038.         TAGANA ana;
  1039.         BOOL f = tagAnalyze(&ana);
  1040.         previewFlush(&ana,f,TRUE);
  1041.         //
  1042.         statprintf("%d個、置換しました",n);
  1043.     } else {
  1044.         if (replaceCur(text,FALSE)) {
  1045.             txNextPara(text);
  1046.         }
  1047.     }
  1048. }
  1049.  
  1050. //##cmdline
  1051.  
  1052. static void pathAdd(txstr szpath,mchar *szsubdir,mchar *szfilename)
  1053. {
  1054.     txstr szwk = text->szexedir;
  1055.     szwk += szsubdir;
  1056.     if (strlen(szsubdir)) szwk += "\\";
  1057.     szwk += szfilename;
  1058.     //
  1059.     szpath += szwk;
  1060.     szpath += " ";
  1061. }
  1062.  
  1063. static void cmdline(mchar *szCmdLine)
  1064. {
  1065.     UCHAR *p = szCmdLine;
  1066.     _cmdline_szpath = "";
  1067.     _cmdline_szsearch = "";//1.00F
  1068.     while(1) {
  1069.         p = strGetWordTop(p);
  1070.         if (*p == 0) break;
  1071.         int len = strGetWordLen(p);
  1072.         if (p[0] == '-' && p[1]) {
  1073.             p += 2;
  1074.             len -= 2;
  1075.             switch(p[-1]) {
  1076.                 case 'f'://2.00E "-p"はまずいので"-f"を追加
  1077.                 case 'p': {
  1078.                     if (len) {
  1079.                         //2.00E grep.txe -f"パス"の様なパス指定の対策
  1080.                         mchar sz[CCHPATHNAME];
  1081.                         strcpylenmax(sz,p,len,CCHPATHNAME);
  1082.                         pathFormLong(sz);
  1083.                         _cmdline_szpath += sz + " ";
  1084.                     }
  1085.                     break;
  1086.                 }
  1087.                 case 's': {//1.00F 検索文字列の指定
  1088.                     if (len) {
  1089.                         mchar* q = p;
  1090.                         if (len >= 2 && q[0] == 0x0C && q[len - 1] == 0x0C) {
  1091.                             q++;
  1092.                             len -= 2;
  1093.                         }
  1094.                         txstrcpylen(_cmdline_szsearch,q,len);
  1095.                     }
  1096.                     break;
  1097.                 }
  1098.                 case 't': {//2.99D 970401 空白を含むときは""で括って指定する検索文字列の指定
  1099.                     txstrcpylen(_cmdline_szsearch,p,len);
  1100.                     pathFormLong(_cmdline_szsearch);
  1101.                     break;
  1102.                 }
  1103.                 case 'u': {
  1104.                     _cmdline_fSearchDirectory = TRUE;
  1105.                     break;
  1106.                 }
  1107.                 case 'w': {
  1108.                     if (p[0] == 'z') {
  1109.                         _cmdline_fSearchDirectory = TRUE;
  1110.                         pathAdd(_cmdline_szpath,"","*.txc");
  1111.                         pathAdd(_cmdline_szpath,"","*.c");
  1112.                         pathAdd(_cmdline_szpath,"","*.ci");
  1113.                         pathAdd(_cmdline_szpath,"","*.h");
  1114.                     }
  1115.                     break;
  1116.                 }
  1117.             }
  1118.         }
  1119.         p += len;
  1120.     }
  1121. }
  1122.  
  1123. uiAbout
  1124. {
  1125.     ABOUTINFO info;
  1126.     memset(&info,0,sizeof(info));
  1127.     info.szicon = "iconWzGrep";
  1128.     info.szappname = "WZ Grep";
  1129.     info.szversion = "version " + VER_WZGREP;
  1130.     info.szcopyright = "Copyright(c)1995-97 TY";
  1131.     about(&info);
  1132. }
  1133.  
  1134. HOOKRESULT __wndprocbase(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  1135. {
  1136. //2.99 970317 edit
  1137.     if (textTarget != _textGrep) return FALSE;
  1138.     switch(message) {
  1139.         case WM_TXCOMMAND://3.00A2 970504 
  1140.         case WM_COMMAND: {
  1141.             if (
  1142.                 _hwndPreviewPartition &&
  1143.                 WM_COMMAND_GetHwndCtrl(wParam,lParam) == _hwndPreviewPartition
  1144.             ) {
  1145.                 SendMessage(hwnd,WM_TXFLUSHWINDOWSIZE,0,0);
  1146.                 return TRUE;
  1147.             }
  1148.             switch(LOWORD(wParam)) {
  1149.                 case IDM_CMDLINE: {
  1150.                     cmdline((mchar*)lParam);
  1151.                     break;
  1152.                 }
  1153.                 case IDM_UIGREP: {
  1154.                     uiGrep();
  1155.                     break;
  1156.                 }
  1157.                 default: {
  1158.                     return HOOK_CONTINUE;
  1159.                 }
  1160.             }
  1161.             return HOOK_CAPTURE;
  1162.         }
  1163.         case WM_TXNOTIFY: {//2.99 970317 
  1164.             if (lParam == TXN_CHANGENPARA) {
  1165. #if 1//3.00A2 970505 
  1166.                 TAGANA ana;
  1167.                 BOOL f = tagAnalyze(&ana);
  1168.                 previewFlush(&ana,f,FALSE);
  1169. #else
  1170.                 TAGANA ana;
  1171.                 BOOL f = tagAnalyze(&ana);
  1172.                 if (_hwndPreview) {
  1173.                     TX* text = (LPVOID)SendMessage(_hwndPreview,TXWM_GETTX,0,0);
  1174.                     if (text) {
  1175.                         if (f) {
  1176.                             if (!pathCmp(ana.szfilename,text->szfilename,NULL)) {
  1177.                                 // 現在開いている
  1178.                             } else {
  1179.                                 txClose(text);
  1180.                                 txSetFileName(text,ana.szfilename);
  1181.                                 txOpenText(text);
  1182.                                 // read all for 排他制御
  1183.                                 txSetUndispSilent(text);
  1184.                                 txJumpFileEnd(text);
  1185.                                 txSetDispSilent(text);
  1186.                             }
  1187.                             txSetUndispSilent(text);
  1188.                             if (ana.fAddress) {
  1189.                                 txJumpAddress(text,ana.address);
  1190.                             } else {
  1191.                                 txJumpNpara(text,ana.npara);
  1192.                                 txRightBytes(text,ana.lx);
  1193.                             }
  1194.                             text->fDispFindEnable = TRUE;//2.99C 970326 プレビューで検索文字色分けON
  1195.                             text->fDispFindGrep = TRUE;//2.99C 970326 
  1196.     #if 0    //2.99C 970326 選択すると使いにくい
  1197.                             if (txRight(text)) {
  1198.                                 txSelectEx(text,CLIP_MOUSE);
  1199.                                 txLeft(text);
  1200.                             }
  1201.     #endif
  1202.                             txSetDispSilent(text);
  1203.                         } else {
  1204.                             txClose(text);
  1205.                             txOpenText(text);
  1206.                         }
  1207.                     }
  1208.                 }
  1209. #endif
  1210.             } else if (lParam == TXN_CONTROLTAB) {
  1211.                 if (wParam == _hwndPreview) {
  1212.                     SetFocus(_textGrep->hwndtext);
  1213.                     macroHookWndBaseReturn(TRUE);
  1214.                     return HOOK_CAPTURE;
  1215.                 } else if (wParam == _textGrep->hwndtext) {
  1216.                     SetFocus(_hwndPreview);
  1217.                     macroHookWndBaseReturn(TRUE);
  1218.                     return HOOK_CAPTURE;
  1219.                 }
  1220.             } else if (lParam == TXN_CONTROLF4) {
  1221.                 if (wParam == _hwndPreview) {
  1222.                     previewClose();
  1223.                     macroHookWndBaseReturn(TRUE);
  1224.                     return HOOK_CAPTURE;
  1225.                 }
  1226.             }
  1227.             break;
  1228.         }
  1229.         case WM_TXWINDOWSIZE: {//2.99 970318 
  1230.             if (_hwndPreview) {
  1231.                 RECT* r = (RECT*)lParam;
  1232.                 int cx = rectCx(r);
  1233.                 int cy = rectCy(r);
  1234.                 //
  1235.                 int rate = p_ratePreview;
  1236.                 if (_hwndPreviewPartition) {
  1237.                     rate = SendMessage(_hwndPreviewPartition,WMPB_GETRATE,0,0);
  1238.                     if (rate < 0) {
  1239.                         SendMessage(_hwndPreviewPartition,WMPB_SETRATE,rate = p_ratePreview,0);
  1240.                     }
  1241.                     SendMessage(_hwndPreviewPartition,WMPB_SETRANGE,r->top,r->bottom);
  1242.                 }
  1243.                 if (rate < 10 || rate > 90) rate = DEFAULT_PREVIEW_RATE;
  1244.                 p_ratePreview = rate;
  1245.                 //
  1246.                 int cyPreview = (cy * (100-rate)) / 100;
  1247.                 r->bottom -= cyPreview;
  1248.                 int y = r->bottom;
  1249.                 MoveWindow(_hwndPreviewPartition,r->left,y,cx,5,TRUE);
  1250.                 y += 5;
  1251.                 cyPreview -= 5;
  1252.                 MoveWindow(_hwndPreview,r->left,y,cx,cyPreview,TRUE);
  1253.             }
  1254.             break;
  1255.         }
  1256.         case WM_TXCLOSE: {//2.99 970318 
  1257.             previewClose();
  1258.             break;
  1259.         }
  1260.     }
  1261.     return HOOK_CONTINUE;
  1262. }
  1263.  
  1264. BOOL __txeclosemulti(HWND hwndprev)
  1265. {
  1266. #if 1//3.00A2 970504 
  1267.     // コマンドラインを解釈させる for -fによるパス指定
  1268.     SendMessage(hwndprev,WM_TXCOMMAND,IDM_CMDLINE,(LPARAM)text->szCmdLine);
  1269.     // hwndprevをアクティブにする
  1270.     PostMessage(hwndprev,WM_TXACTIVE,0,0);//3.00A2 970504 
  1271.     // Grepダイアログを出す
  1272.     PostMessage(hwndprev,WM_TXCOMMAND,IDM_UIGREP,0);
  1273.     return TRUE;
  1274. #else
  1275.     // コマンドラインを解釈させる for -fによるパス指定
  1276.     SendMessage(hwndprev,WM_COMMAND,IDM_CMDLINE,(LPARAM)text->szCmdLine);
  1277.     // Grepダイアログを出す
  1278.     PostMessage(hwndprev,WM_COMMAND,IDM_UIGREP,0);
  1279.     return TRUE;
  1280. #endif
  1281. }
  1282.  
  1283. #if 1//2.99 970317 
  1284. __txedelete
  1285. {
  1286.     macroHookWndBaseFree();
  1287. }
  1288. #else
  1289. __new
  1290. {
  1291. //2.94 970121 
  1292.     macroHookWndBase();
  1293. }
  1294.  
  1295. __delete
  1296. {
  1297. //2.94 970121 
  1298.     macroHookWndBaseFree();
  1299. }
  1300. #endif
  1301.  
  1302. __txenew
  1303. {
  1304.     _textGrep = text;
  1305.     macroHookWndBase();//2.99 970317 
  1306.     SetWindowText(text->hwndbase,"WZ Grep");
  1307.     text->fTXE = TRUE;
  1308.     text->fNoFlushKey = TRUE;//2.00E WZ Grepで設定ダイアログを開いてOKすると{Enter}でタグジャンプができなくなった
  1309.     text->fTxeStdKeyCustmize = TRUE;//2.94 970121 
  1310.     text->fTxeOpenHigh = TRUE;//2.94 970122 
  1311.     //2.00E2 
  1312.     text->fConfigstdTextdata = TRUE;
  1313.     text->fConfigsavePrim = TRUE;
  1314.     // "grep"または"テキストデータファイル"の設定がロードされる
  1315.     mchar szfilename[CCHPATHNAME];
  1316.     pathFullConfig(szfilename,"grep");
  1317.     txSetFileName(text,szfilename);
  1318.     searchmodeToSearchopt(text->searchmode,&_searchopt);
  1319.     _searchopt.fCategory = (text->modeSearchDialog != 0);
  1320.     //
  1321.     text->width = MAXWIDTH;
  1322.     text->fDispUnder = TRUE;
  1323.     text->fSetWidthByWindow = FALSE;
  1324.     text->fConfirmNewFile = FALSE;
  1325.     text->modeWs = text->tmodeWs[0] = WS_DESTEXT;//2.98A 970311 Grepの幅が最大になった
  1326.     strcpy(text->tsztitle[0],".");    //2.00E2 
  1327.     textSetProcessMode(text->hwndbase,WZPROCESS_EDITORLIKE);//1.01A WZ Grep:txSwitchWindowで切り替えられるようにした
  1328.     text->fSaveWindowPos = TRUE;//3.00C1 971017 Grepでウィンドウの位置が保存されてなかった
  1329.     //3.00A 970502 WZ Grepで設定ダイアログを開くと折り返し幅が現在の設定値と違う値が表示された
  1330.     txConfigOp(text,TXCONFIGOP_EXTSETDISPSTYLE,0);
  1331.     text->tmodeWidth[text->dispstylemode] = MODEWIDTH_DESIGNATE;
  1332.     text->twidth[text->dispstylemode] = text->width;
  1333.     //2.99 970317 WZ Grep:メニューを専用にした
  1334.     strcpy(text->szMenu,"bartxe_GREP");
  1335.     strcpy(text->szMenuMouseR,"右クリック_GREP");
  1336.     //2.99C 970326 
  1337.     text->fDispFindEnable = TRUE;
  1338.     text->fDispFindGrep = TRUE;
  1339. }
  1340.  
  1341. main
  1342. {
  1343.     #key
  1344.     .Jump        [ENTER]    [MouseL2]
  1345.     .uiGrep        [ESC]
  1346.     .replace    +{Enter}
  1347.     #end
  1348.     // 新規ファイルの確認をしない
  1349.     text->fConfirmNewFile = FALSE;
  1350.     txJumpFileTop(text);//1.00C
  1351.     // command line
  1352.     cmdline(text->szCmdLine);
  1353.     PostMessage(text->hwndbase,WM_COMMAND,IDM_UIGREP,0);
  1354.     //
  1355.     if (p_fPreview) {//2.99 970318 
  1356.         preview();
  1357.     }
  1358. }
  1359.  
  1360. txe
  1361. {
  1362. #WZKEY
  1363.     // WZ Grepを起動します
  1364. #if 1//2.99D 970330 sw
  1365.     macroFork("grep /i-");
  1366. #else
  1367.     //2.94 970121 "/I"
  1368.     macroFork("grep /I");
  1369. #endif
  1370. }
  1371.  
  1372. WORD at_cmdcheck(WZCMD wzcmd)
  1373. {
  1374.     mchar* szcmd = wzcmdToSzcmd(wzcmd);
  1375.     if (!szcmd) return 0;
  1376.     if (!stricmp(szcmd,"\m.preview")) {
  1377.         if (_hwndPreview) return MF_CHECKED;
  1378.     }
  1379.     return 0;
  1380. }
  1381.  
  1382.