home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2002 January / VPR0201B.ISO / APUPDATE / VC / TXC0601S / TXC0601S.LZH / _IDMLIB.C < prev    next >
C/C++ Source or Header  |  2001-04-12  |  31KB  |  1,228 lines

  1. /*
  2.     TXAPI_()にする必要はないが、EXEと_idmXXX両方で使い、複数の_idmXXXで使われる関数群
  3.     99年11月28日 日曜 start
  4.         TXAPIにするもの: 統一管理する関数、大規模な関数、速度が必要な関数。
  5. */
  6.  
  7. #if __TXC__
  8.     #include <_wz.h>
  9.     #include <windows.h>
  10.     #include <windowsx.h>
  11.     #pragma multidef+
  12.         #include <commctrl.h>
  13.     #pragma multidef-
  14.     #include <_idm.h>
  15.     #define UNIX_TXC    UNIX    // UNIX&&__TXC__
  16. #else
  17.     #include "_sys.h"
  18.     #define UNIX_TXC    0
  19. #endif
  20. #include "_idmlib.h"
  21. #include "_list.h"
  22.  
  23. #if __TXC__
  24.     mchar _szuiwz[] = "uieditor";        // UI定義ファイルの名前
  25.     mchar szclassList[] = "txList";        // "list"コントロール名
  26.     wchar wszclassList[] = TWCHAR("txList");    // "list"コントロール名
  27.     mchar szclassListH[] = "txListH";    // ヘッダ付き"list"コントロール名
  28.     wchar wszclassListH[] = TWCHAR("txListH");    // ヘッダ付き"list"コントロール名
  29.     wchar wszclassText[] = TWCHAR("txText");// TXウィンドウコントロール名
  30.     wchar wszclassPartition[] = TWCHAR("txPartition");
  31. #endif
  32.  
  33. BOOL txJumpFileLink(TX* text);
  34.  
  35. //##比較
  36.  
  37. int txCmpIParatopLen(TX* text,mchar* szstr,int lch)
  38. {
  39. // カーソル段落の先頭が文字列szstr:lchと等しいか返す
  40. // 等しければlch、等しくなければ0を返す
  41. // 比較できない場合もある。この場合は0を返す
  42. // 英大/小を区別しないで調べる
  43. //WZ3.90I 981030 new
  44.     if (!strnicmp(text->buff + text->curpara,szstr,lch)) return lch;
  45.     return 0;
  46. }
  47.  
  48. int txCmpParaOffset(TX* text,mchar* szstr,IBUFF offset)
  49. {
  50. // カーソル段落+offset以降の段落が文字列szstrと等しいか返す
  51. // 等しければszstrの長さ、等しくなければ0を返す
  52. // 比較できない場合もある。この場合は0を返す
  53. // 英大/小を区別して調べる
  54. //WZ3.90I 981017 new
  55.     int lch = strlen(szstr);
  56.     mchar* p = text->buff + text->curpara + offset;
  57.     mchar c = p[lch];
  58.     if (
  59.         (c == CHAR_CR || c == CHAR_LF) &&
  60.         !strncmp(p,szstr,lch)
  61.     ) return lch;
  62.     return 0;
  63. }
  64.  
  65. int txCmpIParatop(TX* text,mchar* szstr)
  66. {
  67. // カーソル段落の先頭が文字列szstrと等しいか返す
  68. // 等しければszstrの長さ、等しくなければ0を返す
  69. // 比較できない場合もある。この場合は0を返す
  70. // 英大/小を区別しないで調べる
  71. //WZ3.90E 980805 new
  72.     int lch = strlen(szstr);
  73.     if (!strnicmp(text->buff + text->curpara,szstr,lch)) return lch;
  74.     return 0;
  75. }
  76.  
  77. BOOL txIbuffIsNspace(TX* text,IBUFF ibuff,int n)
  78. {
  79. // ibuffがn個以上の半角空白かどうか返す。
  80.     mchar* p = text->buff + ibuff;
  81.     BOOL f = TRUE;
  82.     for (;n--;p++) {
  83.         if (*p != ' ') {f = FALSE;break;}
  84.     }
  85.     return f;
  86. }
  87.  
  88. //##text操作
  89.  
  90. BOOL txSelectGetOverwrite(TX* text)
  91. {
  92.     return (text->fClip && text->fClipMouse);
  93. }
  94.  
  95. void txFlushMenuCheckAll(TX* text)
  96. {
  97. //WZ3.90J 981109 new
  98.     txFlushMenuCheck(text,FMC_ALL);
  99. }
  100.  
  101. #if !UNIX_TXC
  102. void txRulerFlushDisp(TX* text)
  103. {
  104.     if (text->hwndRuler) InvalidateRect(text->hwndRuler,NULL,TRUE);
  105. }
  106. #endif
  107.  
  108. //WZ4.00Ee 010411 textmsgopenWzapp(mchar* szName)廃止、txMbxOpenWzappに変更。
  109.  
  110. //##検索置換ダイアログ
  111.  
  112. #if SEARCHOPT_DIALOG_NEW    //WZ3.90J 981112 
  113. void searchoptSetupMode(SEARCHOPT* opt)
  114. {
  115. //WZ3.90L 981123 new
  116.     opt->mode = 0;
  117.     if (opt->fRe) {
  118.         opt->mode = 3;
  119.     } else if (opt->fFuzzy) {
  120.         opt->mode = 1;
  121.     } else if (opt->fWord) {
  122.         opt->mode = 2;
  123.     }
  124. }
  125. #endif
  126.  
  127. SEARCHMODE searchoptToSearchmode(SEARCHOPT* opt)
  128. {
  129. //WZ3.90H 980910 new
  130.     SEARCHMODE searchmode = SEARCH_NOSENSECASE;
  131. #if SEARCHOPT_DIALOG_NEW    //WZ3.90J 981112 
  132.     opt->fRe = (opt->mode == 3);
  133.     opt->fFuzzy = (opt->mode == 1);
  134.     opt->fWord = (opt->mode == 2);
  135. #endif
  136.     if (opt->fFuzzy) {
  137.         searchmode |= SEARCH_NOSENSEZENHAN|SEARCH_NOSENSECASE;
  138.     } else {
  139.         if (opt->fWord) searchmode |= SEARCH_WORD;
  140.         if (opt->fSenseCase) searchmode &= ~SEARCH_NOSENSECASE;
  141.     }
  142.     if (opt->fSearchNoSymbol) searchmode |= SEARCH_NOSYMBOL;
  143.     if (opt->fPrev) searchmode |= SEARCH_PREV;
  144.     if (opt->fReplaceConfirm) searchmode |= REPLACE_CONFIRM;
  145.     if (opt->fRe) searchmode |= SEARCH_RE;
  146.     if (opt->fNoEsc) searchmode |= SEARCH_NOESC;    //WZ4.00Bl 990908 
  147.     if (opt->fAllText) searchmode |= SEARCH_ALLTEXT;//WZ4.00Bl 990916 
  148.     return searchmode;
  149. }
  150.  
  151. void searchoptFromSearchmode(SEARCHOPT* opt,SEARCHMODE searchmode)
  152. {
  153.     opt->fWord = (searchmode & SEARCH_WORD);
  154.     opt->fSenseCase = !(searchmode & SEARCH_NOSENSECASE);
  155.     opt->fSearchNoSymbol = (searchmode & SEARCH_NOSYMBOL);
  156.     opt->fFuzzy = (searchmode & SEARCH_NOSENSEZENHAN);
  157.     opt->fPrev = (searchmode & SEARCH_PREV);
  158.     opt->fReplaceConfirm = (searchmode & REPLACE_CONFIRM);
  159.     opt->fRe = (searchmode & SEARCH_RE);            //WZ3.90G 980905 
  160.     opt->fNoEsc = !!(searchmode & SEARCH_NOESC);    //WZ4.00Bl 990908 
  161.     opt->fAllText = !!(searchmode & SEARCH_ALLTEXT);//WZ4.00Bl 990916 
  162. #if SEARCHOPT_DIALOG_NEW    //WZ3.90J 981112 
  163.     searchoptSetupMode(opt);    //WZ3.90L 981123 
  164. #endif
  165. }
  166.  
  167. void dialogAddSearchopt(HDIALOG hd,SEARCHOPT* opt,int mode)
  168. {
  169. //WZ3.90J 981112 モードとオプションに分離。
  170.     BOOL fGrep = (mode == 3);
  171.     BOOL fSearch = (mode == 0 || fGrep);
  172.     BOOL fReplace = (mode == 1);
  173.     BOOL fSearchlist = (mode == 2);
  174.     BOOL fMbfind = (mode == 4);    //WZ4.00Ea 001029 for WZFUNC_MAILBASE
  175.     //
  176. #if SEARCHOPT_DIALOG_NEW    //WZ3.90J 981112 
  177.     dialogControlID(hd,IDD_SEARCHMODE);
  178.     if (fMbfind) {
  179.         dialogSetPosLF(hd);
  180.         dialogControlHelp(hd,222);
  181.         dialogChoice(hd,"検索(&S):",8,&opt->mode,9,"基本","曖昧","単語","正規",NULL);
  182.     } else {
  183.         dialogControlRadioV(hd);
  184.         dialogControlHelp(hd,-222);
  185.         dialogChoiceRadio(hd,&opt->mode,"基本(&M)","曖昧(&X)","単語(&W)","正規(&E)",NULL);
  186.     }
  187. #else
  188.     dialogControlID(hd,IDD_WORD);
  189.     dialogCheck(hd,"単語を検索(&W)",&opt->fWord);
  190.     dialogControlID(hd,IDD_FUZZY);
  191.     dialogCheck(hd,"曖昧な検索(&X)",&opt->fFuzzy);
  192.     dialogControlID(hd,IDD_RE);
  193.     dialogCheck(hd,"正規表現を使用(&E)",&opt->fRe);    //WZ3.90G 980905 
  194. #endif
  195.         dialogLFV(hd);
  196.     dialogControlID(hd,IDD_SENSECASE);
  197.     dialogControlHelp(hd,226);
  198.     dialogCheck(hd,_pspc?"大小文字を区別":"大文字と小文字を区別(&C)",&opt->fSenseCase);
  199.     //WZ4.00Bl 990908 "\を通常文字として検索"オプションを追加。
  200.     dialogControlID(hd,IDD_NOESC);
  201.     dialogControlHelp(hd,433);    //WZ4.00Bq 991015 
  202.     dialogCheck(hd,"\\を通常文字として検索(&Y)",&opt->fNoEsc);
  203.     //
  204.     dialogControlID(hd,IDD_NOSYMBOL);    //WZ3.90H 980908 
  205.     dialogControlHelp(hd,227);
  206.     dialogCheck(hd,_pspc?"空白記号スキップ":"空白と記号をスキップ(&O)",&opt->fSearchNoSymbol);
  207.     if (fSearch) {
  208.         if (!fGrep) {
  209.             dialogControlHelp(hd,230);
  210.             dialogCheck(hd,"上方向へ検索(&P)",&opt->fPrev);
  211.             #if !WINDOWSCE && WZFUNC_EDITOR
  212.             if (!fSearchlist) {
  213.                 //WZ4.00Bl 990916 (!PWZ)オープン中の全WZを対象とする検索置換ができるようにした。強いユーザ要望。
  214.                 dialogSetH(hd);
  215.                 dialogControlHelp(hd,434);    //WZ4.00Bq 991015 
  216.                 dialogCheck(hd,UNIX?"全XZを対象(&T)":"全WZを対象(&T)",&opt->fAllText);
  217.                 #if !__TXC__
  218.                 dialogControlHelp(hd,231);
  219.                 dialogCheck(hd,"多重化(&I)",&opt->fOpenTempWindow);
  220.                 #endif
  221.                 dialogLFSetV(hd);
  222.             }
  223.             #endif
  224.         }
  225.     } else if (fMbfind) {
  226.         dialogLF(hd);
  227.     } else {
  228.         dialogControlID(hd,IDD_REPLACECONFIRM);
  229.         dialogControlHelp(hd,234);
  230.         dialogCheck(hd,"置換の確認(&K)",&opt->fReplaceConfirm);
  231.         if (fReplace) {
  232.             #if !WINDOWSCE && WZFUNC_EDITOR
  233.             dialogCheck(hd,UNIX?"全XZを対象(&T)":"全WZを対象(&T)",&opt->fAllText);    //WZ4.00Bl 990916 
  234.             #endif
  235.             dialogControlHelp(hd,235);
  236.             dialogCheck(hd,"すべて置換(&A)",&opt->fAll);
  237.             dialogControlEnable(hd,opt->fArea);
  238.             dialogControlHelp(hd,236);
  239.             dialogCheck(hd,"範囲内の置換(&B)",&opt->fArea);
  240.         }
  241.     }
  242. }
  243.  
  244. #if !UNIX_TXC
  245. void wndSetEnableSearchOption(HWND hwnd)
  246. {
  247.     BOOL fRE = FALSE;
  248.     BOOL fFuzzy = FALSE;
  249. #if SEARCHOPT_DIALOG_NEW
  250.     int id;
  251.     if (GetDlgItem(hwnd,IDD_SEARCHMODE+3)) {
  252.         for (id = IDD_SEARCHMODE;id < IDD_SEARCHMODE+4;id++) {
  253.             if (IsDlgButtonChecked(hwnd,id)) {
  254.                 break;
  255.             }
  256.         }
  257.         id -= IDD_SEARCHMODE;
  258.     } else {    //WZ4.00Ea 001029 fMbfind
  259.         id = ComboBox_GetCurSel(GetDlgItem(hwnd,IDD_SEARCHMODE));
  260.     }
  261.     fRE = (id == 3);
  262.     fFuzzy = (id == 1);
  263. #else
  264.     fRE = IsDlgButtonChecked(hwnd,IDD_RE);
  265.     fFuzzy = IsDlgButtonChecked(hwnd,IDD_FUZZY);
  266. #endif
  267.     EnableDlgItem(hwnd,IDD_WORD,!(fRE|fFuzzy));
  268.     EnableDlgItem(hwnd,IDD_SENSECASE,!fFuzzy);
  269.     EnableDlgItem(hwnd,IDD_NOSYMBOL,!fRE);
  270.     EnableDlgItem(hwnd,IDD_FUZZY,!fRE);
  271.     #if WZFUNC_MAILBASE
  272.     if (!GetDlgItem(hwnd,IDD_SEARCHMODE+3)) {    // fMbfind
  273.         EnableDlgItem(hwnd,IDD_NOESC,(fRE || fFuzzy || IsDlgButtonChecked(hwnd,IDD_NOSYMBOL) || uimbfindTargetIsText(hwnd)));
  274.     }
  275.     #endif
  276. }
  277. #endif
  278.  
  279. //##文字列
  280.  
  281. mchar* sepastrGetIndexStr(mchar* str,int i,int* pLch)
  282. {
  283. // '|'で区切られた文字列のi番目のポインタと長さを返す。
  284.     int n = i;
  285.     mchar* p = str;
  286.     while(n--) {
  287.         mchar* p1 = strchr(p,'|');
  288.         if (!p1) {p += strlen(p);break;}
  289.         p = p1 + 1;
  290.     }
  291.     {
  292.         mchar* p1 = strchr(p,'|');
  293.         if (!p1) p1 = p + strlen(p);
  294.         *pLch = (p1 - p);
  295.         return p;
  296.     }
  297. }
  298.  
  299. void strDeleteTailSpaceTab(mchar* sz)
  300. {
  301. // szの末尾の空白・全角空白・タブを削除
  302.     mchar* p = sz;
  303.     mchar* p0 = p;
  304.     while(*p) {
  305.         if (*p == ' ' || *p == CHAR_TAB) {
  306.             p++;
  307.     #if TB_EUC
  308.         } else if (*p == 0xA1 && p[1] == 0xA1) {
  309.     #else
  310.         } else if (*p == 0x81 && p[1] == 0x40) {
  311.     #endif
  312.             p += 2;
  313.         } else {
  314.             p += 1 + (tbiskanji(*p) && p[1]);
  315.             p0 = p;
  316.         }
  317.     }
  318.     *p0 = 0;
  319. }
  320.  
  321. #if defined(__TXC__) && defined(UNICODE)
  322. int sprintf_A(LPSTR szDst,LPCSTR szFormat,...)
  323. {
  324.     return vsprintf_A(szDst,szFormat,(void*)(&szFormat + 1));
  325. }
  326. #endif
  327.  
  328. #if !UNIX_TXC
  329. void sprintSizePrim(mchar* szbuff,UINT size)
  330. {
  331. //WZ4.00Ca 991215 new
  332.     BOOL f = FALSE;
  333.     UCHAR c;
  334.     mchar buff[20];
  335.     mchar* dst = buff + sizeof(buff);
  336.     *--dst = 0;
  337.     #define OUT_DIGIT    {c = size % 10;size /= 10;*--dst = c + '0';f = (!size);}
  338.     OUT_DIGIT;
  339.     if (!f) {
  340.         OUT_DIGIT;
  341.         if (!f) {
  342.             OUT_DIGIT;
  343.             if (!f) {
  344.                 *--dst = ',';
  345.                 OUT_DIGIT;
  346.                 if (!f) {
  347.                     OUT_DIGIT;
  348.                     if (!f) {
  349.                         OUT_DIGIT;
  350.                         if (!f) {
  351.                             *--dst = ',';
  352.                             OUT_DIGIT;
  353.                             if (!f) {
  354.                                 OUT_DIGIT;
  355.                                 if (!f) {
  356.                                     OUT_DIGIT;
  357.                                     if (!f) {
  358.                                         *--dst = ',';
  359.                                         OUT_DIGIT;
  360.                                     }
  361.                                 }
  362.                             }
  363.                         }
  364.                     }
  365.                 }
  366.             }
  367.         }
  368.     }
  369.     strcpy(szbuff,dst);
  370. }
  371. #endif
  372.  
  373. mchar* wpathExtractRejectMask(wchar* wszpath,mchar* szReject,int cch)
  374. {
  375. //WZ4.00Ca 991218 new
  376. // wszpathの^指定を取り出して削除してszRejectに入れる。
  377.     wchar* p = wpathGetFileName(wszpath);
  378.     mchar* dst = szReject;
  379.     mchar* dst0 = dst;
  380.     while(1) {
  381.         wchar* p1 = wstrchr(p,L';');
  382.         if (p[0] == '^') {
  383.             if (p[1] != '^') {    // szReject
  384.                 if (dst > dst0) *dst++ = ';';
  385.                 {
  386.                     mchar buff[40];
  387.                     int lchbuff = wstrtostr(p,p1?p1-p:wstrlen(p),buff,cchof(buff)-1);
  388.                     buff[lchbuff] = 0;
  389.                     if (dst - dst0 + cchof(buff) + 5 > cch) break;
  390.                     strcpy(dst,buff+1);dst += strlen(dst);
  391.                 }
  392.                 if (p1) {
  393.                     wstrcpy(p,p1 + 1);
  394.                 } else {
  395.                     *p = 0;
  396.                     break;
  397.                 }
  398.             } else {
  399.                 wstrcpy(p,p + 1);
  400.                 if (p1) {
  401.                     p = p1;
  402.                 } else {
  403.                     break;
  404.                 }
  405.             }
  406.         } else {
  407.             if (p1) {
  408.                 p = p1 + 1;
  409.             } else {
  410.                 break;
  411.             }
  412.         }
  413.     }
  414.     *dst = 0;
  415.     if (wpathGetFileName(wszpath)[0] == 0) {
  416.         //WZ4.00Cb 000117 "^*.c"等のNOT指定は、通常マスク指定に続けて"*.*;^*.c"と記述する必要があったのを、いきなり"^*.c"の指定もできるようにした。
  417.         wpathSetFileName(wszpath,L"*.*");
  418.     }
  419.     return szReject;
  420. }
  421.  
  422. static int patoi(mchar** pp)
  423. {
  424.     mchar* p = *pp;
  425.     int ret = atoi(p);
  426.     if (*p == '-') p++;
  427.     while(isdigit(*p)) p++;
  428.     if (*p == ',') p++;
  429.     *pp = p;
  430.     return ret;
  431. }
  432.  
  433. void strToRect(mchar* p,RECT* r)
  434. {
  435.     r->left = patoi(&p);
  436.     r->top = patoi(&p);
  437.     r->right = patoi(&p);
  438.     r->bottom = patoi(&p);
  439. //information("%d,%d,%d,%d",r->left,r->top,r->right,r->bottom);
  440. }
  441.  
  442. //##ファイル名
  443.  
  444. BOOL wpathIsCszFiletype(wchar* wszfilename,mchar* cszExt)
  445. {
  446. // wszfilenameの拡張子がcszExtに含まれるかどうかを返す。
  447. //WZ4.00Bl 990915 new
  448.     wchar* wszExt = wpathGetExt(wszfilename);
  449.     mchar szExt[CCHWORD];
  450.     wstrtostr(wszExt,-1,szExt,cchof(szExt));
  451.     {
  452.         mchar* p = cszExt;
  453.         while(1) {
  454.             mchar* p1 = strchr(p,';');
  455.             if (p1) {
  456.                 if (!strnicmp(szExt,p,p1-p)) return TRUE;
  457.                 p = p1 + 1;
  458.             } else {
  459.                 if (!stricmp(szExt,p)) return TRUE;
  460.                 break;
  461.             }
  462.         }
  463.     }
  464.     return FALSE;
  465. }
  466.  
  467. BOOL wpathIsBinaryFiletype(wchar* wszfilename)
  468. {
  469.     return wpathIsCszFiletype(wszfilename,sh->cszExtBinary);
  470. }
  471.  
  472. //##Windows API 拡張
  473.  
  474. #if defined(__TXC__) && defined(UNICODE)
  475. //WCE1.01 980508 CCHWORDを変換バッファに使っていたらログインスクリプトが切れた。wstrdupに変更。
  476. BOOL WINAPI SetWindowText_A(HWND hwnd,LPCSTR lpsz)
  477. {
  478.     wchar* wsz = wstrdupA(lpsz);
  479.     int ret = wsz ? SetWindowText(hwnd,wsz) : FALSE;
  480.     free(wsz);
  481.     return ret;
  482. }
  483. int WINAPI GetWindowText_A(HWND hwnd,LPSTR lpsz,int cchMax)
  484. {
  485.     wchar* wsz = malloc(cchMax * sizeof(wchar));
  486.     int ret = 0;
  487.     if (wsz) {
  488.         GetWindowText(hwnd,wsz,cchMax);
  489.         ret = wstrtostr(wsz,-1,lpsz,cchMax);
  490.     }
  491.     if (ret) return ret-1;
  492.     return 0;
  493. }
  494. BOOL SetDlgItemText_A(HWND hwndDlg,int idControl,LPCSTR lpsz)
  495. {
  496.     return SetWindowText_A(GetDlgItem(hwndDlg,idControl),lpsz);
  497. }
  498. BOOL GetDlgItemText_A(HWND hwndDlg,int idControl,LPSTR lpsz,int cchMax)
  499. {
  500.     return GetWindowText_A(GetDlgItem(hwndDlg,idControl),lpsz,cchMax);
  501. }
  502. int ListBox_AddString_A(HWND hctrl,mchar* sz)
  503. {
  504. //WCE1.01 980115 new
  505. //WZ4.00Ee 010412 return void->int
  506.     wchar* wsz = wstrdupA(sz);
  507.     int ret = ListBox_AddString(hctrl,wsz);
  508.     free(wsz);
  509.     return ret;
  510. }
  511. int ListBox_FindStringExact_A(HWND hctrl,int i,mchar* sz)
  512. {
  513. //WCE1.01 980118 new
  514.     wchar* wsz = wstrdupA(sz);
  515.     int ret = ListBox_FindStringExact(hctrl,i,wsz);
  516.     free(wsz);
  517.     return ret;
  518. }
  519. BOOL WinExecEx_W(wchar* wszfilenameExe,wchar* wszCmdline)
  520. {
  521.     PROCESS_INFORMATION procinfo;
  522.     BOOL ret = CreateProcess(
  523.         wszfilenameExe,
  524.         wszCmdline,
  525.         NULL,NULL,
  526.         FALSE,0,
  527.         NULL,NULL,
  528.         NULL,
  529.         &procinfo
  530.     );
  531.     if (ret) {    //WZ4.00Eb 010103 CreateProcessで返されたハンドルを閉じる様にした。
  532.         CloseHandle(procinfo.hThread);
  533.         CloseHandle(procinfo.hProcess);
  534.     }
  535.     return ret;
  536. }
  537. #endif
  538.  
  539. #if defined(__TXC__) && WINDOWSCE
  540. BOOL IsIconic(HWND hwnd)
  541. {
  542. // CEでは実現できない
  543.     return FALSE;
  544. }
  545. #endif
  546.  
  547. #if !UNIX_TXC
  548. mchar* GetWindowTextAlloc_A(HWND hwnd)
  549. {
  550.     int lch = GetWindowTextLength(hwnd);
  551.     #ifdef UNICODE
  552.     int cch = (lch + 1) * sizeof(wchar);
  553.     #else
  554.     int cch = (lch + 1);
  555.     #endif
  556.     mchar* ret = malloc(cch);
  557.     if (ret) {
  558.         GetWindowText_A(hwnd,ret,cch);
  559.     }
  560.     return ret;
  561. }
  562. #endif
  563.  
  564. #if defined(__TXC__) && !defined(UNICODE) && !UNIX_TXC
  565. BOOL CopyFile_W(LPCWSTR lpszSrc,LPCWSTR lpszDst,BOOL fFailIfExists)
  566. {
  567.     mchar* szsrc = strdupW(lpszSrc);
  568.     mchar* szdst = strdupW(lpszDst);
  569.     BOOL ret = CopyFile(szsrc,szdst,fFailIfExists);
  570.     free(szsrc);
  571.     free(szdst);
  572.     return ret;
  573. }
  574. BOOL MoveFile_W(LPCWSTR lpszSrc,LPCWSTR lpszDst)
  575. {
  576.     mchar* szsrc = strdupW(lpszSrc);
  577.     mchar* szdst = strdupW(lpszDst);
  578.     BOOL ret = MoveFile(szsrc,szdst);
  579.     free(szsrc);
  580.     free(szdst);
  581.     return ret;
  582. }
  583. BOOL DeleteFile_W(LPCWSTR lpszFileName)
  584. {
  585.     mchar* szfilename = strdupW(lpszFileName);
  586.     BOOL ret = DeleteFile(szfilename);
  587.     free(szfilename);
  588.     return ret;
  589. }
  590. BOOL CreateDirectory_W(LPCWSTR lpszPath,LPSECURITY_ATTRIBUTES lpsa)
  591. {
  592.     mchar* szpath = strdupW(lpszPath);
  593.     BOOL ret = CreateDirectory(szpath,lpsa);
  594.     free(szpath);
  595.     return ret;
  596. }
  597. #endif
  598.  
  599. #if !UNIX_TXC
  600. BOOL wndGetRect(HWND hwnd,RECT* r)
  601. {
  602. // アイコン化されていてもオリジナル位置を返すGetWindowRect
  603. // アイコン化されているFILERなどを閉じるとウィンドウ位置の復活ができなくなった。
  604. //WZ3.90N 981202 new
  605. #if WINDOWSMT
  606.     WINDOWPLACEMENT p;
  607.     structClear(p);
  608.     p.length = sizeof(p);
  609.     GetWindowPlacement(hwnd,&p);
  610.     *r = p.rcNormalPosition;
  611.     #if !__TXC__
  612.     {
  613.         //WZ4.00Ec 010201 タスクバーを上に表示していると、GetWindowPlacementでは正常な位置が取得できず、FILERの位置が開く度に繰り上がった。
  614.         RECT rWork;
  615.         hwndGetWorkRect(hwnd,&rWork);
  616.         r->top += rWork.top;
  617.         r->bottom += rWork.top;
  618.         r->left += rWork.left;
  619.         r->right += rWork.left;
  620.     }
  621.     #endif
  622.     return TRUE;    //WZ3.90P 981206 
  623. #else
  624.     GetWindowRect(hwnd,r);
  625.     return TRUE;
  626. #endif
  627. }
  628. #endif
  629.  
  630. #if __TXC__    //WZ4.00Ea 001105 TX-Cと分離
  631. void filetimeAdd(FILETIME* ft,FILETIME* ftAdd)
  632. {
  633. // ftにftAddを足す
  634.     DWORD dwLowDateTime0 = ft->dwLowDateTime;
  635.     ft->dwLowDateTime += ftAdd->dwLowDateTime;
  636.     if (ft->dwLowDateTime < dwLowDateTime0) ft->dwHighDateTime++;
  637.     ft->dwHighDateTime += ftAdd->dwHighDateTime;
  638. }
  639. #endif
  640.  
  641. //##最近ジャンプした位置
  642.  
  643. #ifdef _LIST_H
  644. void histjumpstrAnalyze(mchar* sz,JH_ITEM* item)
  645. {
  646.     item->npara = atoi(sz);
  647.     //
  648.     item->szfilename[0] = 0;
  649.     sz = strchr(sz,',');
  650.     if (sz) {
  651.         sz++;
  652.         sstrcpy(item->szfilename,sz);
  653.     }
  654. }
  655. void jumphistAdd(TX* text)
  656. {
  657.     if (text->fFrame && text->fOpen) {
  658.         JH_ITEM item;
  659.         HSTRBLK sb = sbFromHist(HIST_JUMP);
  660.         int n = sbGetCount(sb);
  661.         if (n) {
  662.             // 近い場所は追加しない。
  663.             histjumpstrAnalyze(sbRead(sb,n-1),&item);
  664.             if (!stricmp(item.szfilename,text->szfilename)) {
  665.                 if (myabs(text->npara - item.npara) < 10) return;
  666.             }
  667.         }
  668.         {
  669.             mchar buff[CCHPATHNAME + 20];
  670.             mchar* dst = buff;
  671.             itoa(text->npara,dst,10);dst += strlen(dst);
  672.             *dst++ = ',';
  673.             strcpy(dst,text->szfilename);
  674.             sbAddHist(sb,buff);
  675.         }
  676.     }
  677. }
  678. #endif
  679.  
  680. //##タグジャンプ
  681. // 行番号指定なし、検索文字列指定に対応
  682. #if WZFUNC_EDITOR
  683.  
  684. static mchar* tagjumpGetFilename(TX* text,mchar* p,mchar szfilename[CCHPATHNAME])
  685. {
  686. // テキストバッファポインタpから行末まで、存在するファイル名の記述があれば
  687. // szfilenameに取得してファイル名の末尾の次の文字へのテキストバッファポインタを返す
  688. // なければNULLを返す
  689.     mchar path[CCHPATHNAME];
  690.     
  691.     if (text->modeTagJump != TAGJUMP_VZ && !strncmp(p,"・",2)) {
  692.         // grep形式。高速化のため直ぐに判別
  693.         p += 2;
  694.         while(isspace(*p)) p++;
  695.         if (isdigit(*p)) return NULL;
  696.     }
  697.     while(1) {
  698.         BOOL fdq = FALSE;
  699.         mchar *top;
  700.         
  701.         // get top
  702.         while(1) {
  703.             mchar c = *p;
  704.             
  705.             if (c == 0x0A || c == 0x1A || c == 0) {
  706.                 return NULL;
  707.             } else if (c <= ' ' || c == '(' || c == ')' || c == ':') {
  708.                 p++;
  709.             } else {
  710.                 break;
  711.             }
  712.         }
  713.         top = p;
  714.         // get tail
  715.         while(1) {
  716.             mchar c = *p;
  717.             
  718.             if (c == 0x0A || c == 0x1A || c == 0) {
  719. #if 1//3.00A2 970504 「ファイル名+改行」でもタグジャンプするようにした(従来は「ファイル名+スペース+改行」でタグジャンプした)。
  720.                 break;
  721. #else
  722.                 return NULL;
  723. #endif
  724.             } else if (c == '"') {
  725.                 fdq ^= 1;
  726.                 p++;
  727.             } else if (c < ' ' || ((c == ' ' || c == '(' || c == ')') && !fdq)) {    //WZ4.00Bl 990925 タグジャンプ指定で""内の(と)はファイル名とみなすようにした。ユーザ要望。
  728.                 break;
  729.             } else if (c == ':' && isdigit(p[1])) {
  730.                 //2.00E "D:\WZ\TEST.C:256 void function()"の様な"ファイル名:行番号"形式のタグジャンプができなかった
  731.                 break;
  732.             } else {
  733.                 p++;
  734.             }
  735.         }
  736.         if (p > top && p[-1] == ':') p--;//1.00C タグジャンプを「ファイル名: 行番号」に対応させた
  737.         {
  738.             IBUFF len = p - top;
  739.             
  740.             if (len < CCHPATHNAME) {
  741.                 strcpylen(szfilename,top,len);
  742.                 if (text->modeTagJump != TAGJUMP_VZ && iskanji(szfilename[0])) {
  743.                     //2.92 標準では、漢字はファイル名としては認識しない
  744.                     break;
  745.                 }
  746.                 pathFormLong(szfilename);
  747. //information("%s",szfilename);
  748.                 // [1]フルパスならそれでジャンプ
  749.                 if (pathIsFull(szfilename) && fileIsExist(szfilename)) return p;
  750.                 // [1.5]サブフォルダ指定があれば、フルパスに変換してジャンプ    //WZ4.00Bl 990907 タグジャンプでサブフォルダ\ファイル名も使える様にした。ユーザ要望。
  751.                 if (pathGetFileName(szfilename) != szfilename) {
  752.                     mchar szbuff[CCHPATHNAME];
  753.                     wpathtopath(text->wszfilename,szbuff);
  754.                     pathSetFileName(szbuff,szfilename);
  755.                     if (fileIsExist(szbuff)) {
  756.                         strcpy(szfilename,szbuff);
  757.                         return p;
  758.                     }
  759.                 }
  760.                 //
  761.                 strcpy(szfilename,pathGetFileName(szfilename));
  762.                 // [2]現在の文書のフォルダでファイルを検索
  763.                 {
  764.                     mchar szbuff[CCHPATHNAME];
  765.                     wstrtostr(text->wszfilename,-1,szbuff,CCHPATHNAME);
  766.                     pathSetFileName(szbuff,szfilename);
  767.                     if (fileIsExist(szbuff)) {
  768.                         strcpy(szfilename,szbuff);
  769.                         return p;
  770.                     }
  771.                 }
  772.                 // [3]標準フォルダでファイルを検索
  773.                 if (sh->szFolderDefault[0]) {
  774.                     mchar szbuff[CCHPATHNAME];
  775.                     strcpy(szbuff,sh->szFolderDefault);
  776.                     pathSetDir(szbuff);
  777.                     pathSetFileName(szbuff,szfilename);
  778. //information(szbuff);
  779.                     if (fileIsExist(szbuff)) {
  780.                         strcpy(szfilename,szbuff);
  781.                         return p;
  782.                     }
  783.                 }
  784.                 // [4]文書パスのフォルダでファイルを検索
  785.                 {
  786.                     wchar wszfilename[CCHPATHNAME];
  787.                     strtowstr(szfilename,-1,wszfilename,CCHPATHNAME);
  788.                     if (wpathSearchPathtext(wszfilename)) {
  789.                         wstrtostr(wszfilename,-1,szfilename,CCHPATHNAME);
  790.                         return p;
  791.                     }
  792.                 }
  793.             }
  794.         }
  795.         if (text->modeTagJump != TAGJUMP_VZ) {
  796.             break;//2.92 
  797.         }
  798.     }
  799.     return NULL;
  800. }
  801.  
  802. static NPARA tagjumpGetNline(mchar* p,int* pLx,mchar szFind[CCHWORD],RECT* r)
  803. {
  804. //WZ3.90I 981030 rを追加
  805.     int a = 0;
  806.     r->left = INT_MAX;
  807.     szFind[0] = 0;
  808.     while(1) {
  809.         mchar c = *p;
  810.         int a0 = a;
  811.         a = 0;
  812.         
  813.         if (c == 0x0A || c == 0) {
  814.             return 0;
  815.         } else if (c == '"') {
  816.             strcpylenmax(szFind,p,strGetWordLen(p),CCHWORD);
  817.             pathFormLong(szFind);
  818.             {
  819.                 mchar* p = strchrs(szFind," \t");
  820.                 if (p) {
  821.                     // 空白やタブは検索できない
  822.                     *p = 0;
  823.                 }
  824.             }
  825.             return 0;
  826.         } else if (!a0 && isdigit(c)) {
  827.             IFILE line = 0;
  828.             IBUFF lch = 0;
  829.             
  830.             while(1) {
  831.                 mchar c = *p;
  832.                 
  833.                 if (isdigit(c)) {
  834.                     line *= 10;
  835.                     line += c - '0';
  836.                     p++;
  837.                 } else {
  838.                     break;
  839.                 }
  840.             }
  841.             if (*p == ',') {
  842.                 lch = atoi(p + 1);
  843.                 {    //WZ3.90I 981030 
  844.                     p++;
  845.                     while(isdigit(*p)) p++;
  846.                     if (*p == ',' && p[1] == '(') {
  847.                         p += 2;
  848.                         strToRect(p,r);
  849.                     }
  850.                 }
  851.             }
  852.             if (pLx) *pLx = lch;
  853.             return line;
  854.         } else if (iskanji(c)) {
  855.             p += 2;
  856.         } else {
  857.             if (isalpha(c)) {
  858.                 a = 1;
  859.             }
  860.             p++;
  861.         }
  862.     }
  863. }
  864.  
  865. static BOOL txJumpTagExec(TX* text,mchar* szfilename,NPARA npara,int lx,mchar* szFind,RECT* r)
  866. {
  867. // npara == 0            指定なし
  868. // lx < 0                指定なし
  869. // !szFind||!szFind[0]    指定なし
  870. // r:ウィンドウ位置 //WZ3.90I 981030 
  871.     wchar wsw[CCHWORD] = {0};
  872.     wchar wszfilename[CCHPATHNAME];
  873.     strtowstr(szfilename,-1,wszfilename,CCHPATHNAME);
  874.     if (szFind && szFind[0]) {
  875. #if 1//WCE0.95 970923 
  876.         if (strlen(szFind) < 5 + CCHWORD) {
  877.             mchar sw[CCHWORD];
  878.             #if UNIX
  879.             sprintf(sw,"-s%s",szFind);
  880.             #else
  881.             sprintf(sw,"/s%s",szFind);
  882.             #endif
  883.             strtowstr(sw,-1,wsw,wcchof(wsw));
  884.             forkstdW(wszfilename,wsw);
  885.         }
  886. #else
  887.         wsprintf(wsw,L"/s%hs",szFind);
  888.         forkstdW(wszfilename,wsw);
  889. #endif
  890.     } else {
  891.         //WZ4.00Bl 990912 プロジェクトのオープンでウィンドウ位置がTPJの内容に従ってなかったのを修正。
  892.         if (npara) {
  893.             //WZ4.00Bl 990922 /k -> /kpj for 「設定の切り替え」の記憶を読むように。
  894.             if (lx >= 0) {
  895.                 #if UNIX
  896.                 sprintf_W(wsw,L"-kpj -J%ld,%d -Yc",npara,lx);
  897.                 #else
  898.                 sprintf_W(wsw,L"/kpj /J%ld,%d /Yc",npara,lx);
  899.                 #endif
  900.             } else {
  901.                 #if UNIX
  902.                 sprintf_W(wsw,L"-kpj -J%ld -Yc",npara);
  903.                 #else
  904.                 sprintf_W(wsw,L"/kpj /J%ld /Yc",npara);
  905.                 #endif
  906.             }
  907.         }
  908.         if (r) {
  909.             #if UNIX
  910.             sprintf_W(wsw + wstrlen(wsw),L" -ow%d,%d,%d,%d",r->left,r->top,r->right,r->bottom);
  911.             #else
  912.             sprintf_W(wsw + wstrlen(wsw),L" /ow%d,%d,%d,%d",r->left,r->top,r->right,r->bottom);
  913.             #endif
  914.         }
  915. //winformation(wsw);
  916.         forkstdW(wszfilename,wsw);
  917.     }
  918.     return TRUE;
  919. }
  920.  
  921. BOOL txJumpTagPrim(TX* text,int mode)
  922. {
  923. // タグジャンプ
  924. // mode=1: PROJECTのオープン
  925.     mchar szfilename[CCHPATHNAME];
  926.     mchar szpara[CCHLINE*4];
  927.     if (mode == 0 && txfIbuffIsLink(text,text->cur)) {    //WZ4.00Ab 990125 TMLのリンクにカーソルを置いてタグジャンプしたときは、リンク先にジャンプするようにした。
  928.         txIbuffJumpLink(text,text->cur);
  929.         return TRUE;
  930.     }
  931.     if (mode == 0 && txIbuffIsUrl(text,text->cur)) {
  932.         //WZ4.00Bl 990908 (!PWZ)クリッカブルURL,E-Mailにカーソルを置いてタグジャンプできるようにした。ユーザ要望(音声化)。WZ3と同じ仕様。
  933.         //WZ4.00Ea 001114 WINDOWSCE対応
  934.         txIbuffJumpLink(text,text->cur);
  935.         return TRUE;
  936.     }
  937.     #if WZFUNC_MAILBASE
  938.     if (mode == 0 && txfIbuffIsHtmlLink(text,text->cur,NULL)) {
  939.         txIbuffJumpLink(text,text->cur);
  940.         return TRUE;
  941.     }
  942.     #endif
  943.     txGetParaEx(text,szpara,cchof(szpara));
  944.     if (!strnicmp(szpara,"shell",5)) {
  945. #if !UNIX && !__TXC__
  946.         mchar* p = szpara + 5;
  947.         if (*p == '(') {
  948.             p = strchr(p,')');
  949.             if (!p) return FALSE;
  950.             p++;
  951.         }
  952.         p = strGetWordTop(p);
  953.         {
  954.             SHELLEXECUTEINFOW info;
  955.             wchar wszfilename[CCHPATHNAME];
  956.             wchar* wszPara = NULL;
  957.             strtowstr(p,-1,wszfilename,CCHPATHNAME);
  958.             {
  959.                 int lch = wstrGetWordLen(wszfilename);
  960.                 wchar* p = wszfilename + lch;
  961.                 if (*p) {
  962.                     *p = 0;
  963.                     wszPara = p + 1;
  964.                 }
  965.             }
  966.             structClear(info);
  967.             info.cbSize = sizeof(info);
  968.             info.lpVerb = L"Open";
  969.             info.lpFile = wszfilename;
  970.             info.lpParameters = wszPara;
  971.             info.nShow = SW_SHOWNORMAL;    //WCE1.01 980226 
  972.             return ShellExecuteEx_W(&info);
  973.         }
  974. #endif    // !UNIX
  975.     } else {
  976.         mchar* p = szpara;
  977.         p = tagjumpGetFilename(text,p,szfilename);
  978.         if (!p) {
  979.             #if !__TXC__ && WZFUNC_EDITOR
  980.             if (txGrepTagJump(text)) {
  981.                 // grep結果のタグジャンプ及び"ファイル名"へのジャンプ
  982.                 return TRUE;
  983.             }
  984.             #endif // !__TXC__
  985.             // THP用参照
  986.             #if 0    //WZ4.00Ab 990118 THP参照用のコードがあったので廃止。
  987.             {
  988.                 mchar* p = strstr(szpara,"≪");
  989.                 if (p) {
  990.                     mchar* p1;
  991.                     p += 2;
  992.                     p1 = strstr(p,"≫");
  993.                     if (p1) {
  994.                         mchar szHeadline[CCHWORD];
  995.                         sstrcpylen(szHeadline,p,p1-p);
  996.                         return txJumpThp(text,szHeadline);
  997.                     }
  998.                 }
  999.             }
  1000.             #endif
  1001.             if (mode == 0 && txJumpFileLink(text)) return TRUE;    //WZ4.00Bk 990904 WZ3の簡易リンクを復活。IDM_JUMPTAGでタグがない場合、カーソル位置の"ファイル名"または段落先頭の"ファイル名"のファイルを開く。
  1002.             return FALSE;
  1003.         }
  1004.         {
  1005.             mchar szFind[CCHWORD];
  1006.             RECT r;
  1007.             int lx = -1;
  1008.             NPARA npara = tagjumpGetNline(p,&lx,szFind,&r);
  1009. //information("%d",npara);
  1010.             if (mode == 1) {
  1011.                 // プロジェクトオープンではカーソル位置の指定は無視して
  1012.                 // プロファイルのカーソル位置を優先。
  1013.                 lx = -1;
  1014.                 npara = 0;
  1015.             }
  1016. //information("%d %d %d %d",r.left,r.top,r.right,r.bottom);
  1017.             return txJumpTagExec(text,szfilename,npara,lx,szFind,r.left == INT_MAX ? NULL : &r);
  1018.         }
  1019.     }
  1020.     return FALSE;
  1021. }
  1022.  
  1023. BOOL txJumpFileLink(TX* text)
  1024. {
  1025. // カーソル段落が簡易リンクならジャンプする。
  1026. //WZ4.00Bk 990904 new
  1027.     mchar* ppara = text->buff + text->curpara;
  1028.     mchar* pend = ppara + txGetParaContentLen(text);
  1029.     mchar* p = text->buff + text->cur;
  1030.     mchar* p1;
  1031.     mchar* p2;
  1032.     if (p2 = memchr(p,'"',pend - p)) {
  1033.         p1 = p;
  1034.         for (;p1>=ppara;p1--) {
  1035.             if (*p1 == '"') {
  1036.                 int len = p2-p1-1;
  1037.                 if (len > 0) {
  1038.                     mchar szfilename[CCHPATHNAME];
  1039.                     sstrcpylen(szfilename,p1+1,len);
  1040. //information("[%s] %d",szfilename,len);
  1041.                     forkstd(szfilename,NULL);
  1042.                     return TRUE;
  1043.                 } else {
  1044.                     break;
  1045.                 }
  1046.             }
  1047.         }
  1048.     }
  1049.     if (p1 = memchr(ppara,'"',pend-ppara)) {
  1050.         if (p2 = memchr(p1+1,'"',pend-p1-1)) {
  1051.             int len = p2-p1-1;
  1052.             if (len > 0) {
  1053.                 mchar szfilename[CCHPATHNAME];
  1054.                 sstrcpylen(szfilename,p1+1,len);
  1055.                 forkstd(szfilename,NULL);
  1056. //information(szfilename);
  1057.                 return TRUE;
  1058.             }
  1059.         }
  1060.     }
  1061.     return FALSE;
  1062. }
  1063.  
  1064. void tagjumpreturnAdd(mchar* szfilename,IFILE adr);
  1065.  
  1066. #if !__TXC__ && WZFUNC_EDITOR
  1067. BOOL TXAPI txJumpTagEx(TX* text)
  1068. {
  1069. // タグジャンプ
  1070.     return txJumpTagPrim(text,0);
  1071. }
  1072. #endif // !__TXC__
  1073.  
  1074. #endif    // WZFUNC_EDITOR
  1075. //##ダイアログ
  1076.  
  1077. #if !UNIX_TXC
  1078. int questionOverwrite(wchar* wszfilename)
  1079. {
  1080. //WCE0.93 970920 
  1081.     HDIALOG hd = dialog("上書き確認");
  1082.     mchar szfilename[CCHPATHNAME];
  1083.     wstrtostr(wszfilename,-1,szfilename,CCHPATHNAME);
  1084.     dialogCaption(hd,szfilename);
  1085.     dialogCaption(hd,"は存在します。");
  1086.     dialogCaption(hd,"上書きしてもよろしいですか?");    //WZ4.00Db 000210 「移動」にも使われるので、「コピー」の語句を外した。
  1087.     dialogSetFocus(hd,IDNO);
  1088.     dialogSetH(hd);
  1089.     dialogControlID(hd,IDYES);
  1090.     dialogCmd(hd,"はい(&Y)",10);
  1091.     dialogControlID(hd,IDNO);
  1092.     dialogControlStyle(hd,WS_TABSTOP);    //XZ0.10 990623 方向キーでボタンを選べるようにした。
  1093.     dialogCmdDefault(hd,"いいえ(&N)",10);
  1094.     dialogControlID(hd,IDCANCEL);
  1095.     dialogCmd(hd,"キャンセル",10);
  1096.     dialogControlID(hd,IDIGNORE);
  1097.     dialogCmd(hd,"すべて上書き(&A)",15);
  1098.     {
  1099.         int ret = dialogOpen(hd);
  1100.         if (ret) return ret;
  1101.     }
  1102.     return IDCANCEL;    //WZ4.00Bj 990814 
  1103. }
  1104. #endif
  1105.  
  1106. //## sub dialog proc
  1107.  
  1108. #if !UNIX_TXC
  1109. BOOL subdlgprocSblist(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam,HSTRBLK sb)
  1110. {
  1111. // sbをListBoxで選択し、メンテナンス
  1112.     HDIALOG hd = dialogFromHwnd(hwnd);
  1113.     switch(message) {
  1114.         case WM_COMMAND: {
  1115.             int cmd = GET_WM_COMMAND_CMD(wParam,lParam);
  1116.             int id;
  1117.             switch(id = GET_WM_COMMAND_ID(wParam,lParam)) {
  1118.                 case IDD_SBLIST_ADD: {
  1119.                     HDIALOG hd = dialog("名前を付けて追加");
  1120.                     mchar szName[CCHNAME] = {0};
  1121.                     dialogString(hd,"名前(&N):",10,szName,CCHNAME,20);
  1122.                     if (dialogOpen(hd)) {
  1123.                         SendMessage(hwnd,SBLISTN_ADD,0,szName);
  1124.                     }
  1125.                     break;
  1126.                 }
  1127.                 case IDD_SBLIST_UP:
  1128.                 case IDD_SBLIST_DOWN: {
  1129.                     HWND hctrl = GetDlgItem(hwnd,IDD_SBLIST);
  1130.                     int isel = ListBox_GetCurSel(hctrl);
  1131.                     int i = isel;
  1132.                     mchar* sz = sbRead(sb,i);
  1133.                     if (id == IDD_SBLIST_UP && i == 0) break;
  1134.                     if (id == IDD_SBLIST_DOWN && i + 1 == sbGetCount(sb)) break;
  1135.                     if (sz) {
  1136.                         mchar* szInsert = strdup(sz);
  1137.                         if (szInsert) {
  1138.                             sbDelI(sb,i);
  1139.                             (id == IDD_SBLIST_UP) ? i-- : i++;
  1140.                             sbInsert(sb,i,szInsert);
  1141.                             SendMessage(hwnd,SBLISTN_FLUSHLIST,0,0);
  1142.                             ListBox_SetCurSel(hctrl,i);
  1143.                             free(szInsert);
  1144.                         }
  1145.                     }
  1146.                     break;
  1147.                 }
  1148.                 case IDD_SBLIST_DEL:
  1149.                 case IDD_SBLIST_SET: {
  1150.                     HWND hctrl = GetDlgItem(hwnd,IDD_SBLIST);
  1151.                     int isel = ListBox_GetCurSel(hctrl);
  1152.                     mchar szName[CCHNAME];
  1153.                     ListBox_GetItemText_A(hctrl,isel,szName,CCHNAME);
  1154.                     if (!szName[0]) break;
  1155.                     if (id == IDD_SBLIST_DEL) {
  1156.                         wchar wszName[CCHNAME];
  1157.                         strtowstr(szName,-1,wszName,CCHNAME);
  1158.                         if (wquestionYesNo(L"%sを削除しますか?",wszName) == IDYES) {
  1159.                             sbDelI(sb,isel);
  1160.                             SendMessage(hwnd,SBLISTN_FLUSHLIST,0,0);
  1161.                             ListBox_SetCurSel(hctrl,isel);
  1162.                             SendMessage(hwnd,SBLISTN_FLUSHCONTENT,0,0);
  1163.                         }
  1164.                     } else {
  1165.                         SendMessage(hwnd,SBLISTN_SET,0,szName);
  1166.                     }
  1167.                     break;
  1168.                 }
  1169.                 case IDD_SBLIST: {
  1170.                     if (cmd == LBN_SELCHANGE) {
  1171.                         SendMessage(hwnd,SBLISTN_FLUSHCONTENT,0,0);
  1172.                     }
  1173.                     break;
  1174.                 }
  1175.             }
  1176.             break;
  1177.         }
  1178.     }
  1179.     return FALSE;
  1180. }
  1181. #endif
  1182.  
  1183. //##インクリメンタル検索
  1184.  
  1185. void txIsearchStatprintf(TX* text,BOOL find,SEARCHMODE searchmode)
  1186. {
  1187.     mchar sz[CCHTXSTR] = {0};
  1188.     if (!find) strcat(sz,"Failing ");
  1189.     if (text->isearch->fIsearchWrapped) strcat(sz,"Wrapped ");
  1190.     if (searchmode & SEARCH_REWZ) strcat(sz,"Regexp ");
  1191.     strcat(sz,"I-search");
  1192.     if (searchmode & SEARCH_PREV) strcat(sz," backward");
  1193.     strcat(sz,": ");
  1194.     sstrcat(sz,text->isearch->szIsearch);
  1195.     txStatusbarPrintf(text,sz);
  1196. }
  1197.  
  1198. BOOL txIsearchIsContinueIdm(TX* text,int idm)
  1199. {
  1200. //WZ4.00Ab 990124 new
  1201.     if (idm == IDM_ISEARCHPREV) return TRUE;
  1202.     if (idm == IDM_ISEARCH) return TRUE;
  1203.     if (idm == IDM_ISEARCHRE) return TRUE;
  1204.     if (idm == IDM_DELETEPREV && text->isearch->szIsearch[0]) return TRUE;    //WZ4.00Bl 990909 
  1205.     return FALSE;
  1206. }
  1207.  
  1208. BOOL txIsearchQuit(TX* text)
  1209. {
  1210. //WZ4.00Ab 990124 new
  1211.     if (text->isearch && text->isearch->fIsearching) {
  1212.         text->isearch->fIsearching = FALSE;
  1213.         txStatusbarPrintf(text,NULL);
  1214.         return TRUE;
  1215.     }
  1216.     return FALSE;
  1217. }
  1218.  
  1219. void txIsearchQuitEm(TX* text)
  1220. {
  1221. // for emacs
  1222.     txIsearchQuit(text);
  1223.     if (txIsearchIsContinueIdm(text,text->idmPrev)) {
  1224.         txJumpAddress(text,text->isearch->adrIsearch0);
  1225.     }
  1226. }
  1227.  
  1228.