home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2002 January / VPR0201B.ISO / APUPDATE / VC / TXC0601S / TXC0601S.LZH / _IDMTOOL.C < prev    next >
C/C++ Source or Header  |  2001-05-23  |  167KB  |  6,066 lines

  1. /*
  2.     ツール関係のIDMコマンド処理群
  3.         Start 99年11月19日
  4. */
  5.  
  6. #if __TXC__
  7.     #include <_wz.h>
  8.     #include <windows.h>
  9.     #include <windowsx.h>
  10.     #pragma multidef+
  11.         #include <commctrl.h>
  12.     #pragma multidef-
  13.     #include <_idm.h>
  14. #else
  15.     #include "_sys.h"
  16. #endif
  17. #include "_idmlib.h"
  18. #include "_list.h"
  19. #include "_proof.h"
  20.  
  21. static BOOL txuiConvertTable(TX* text);
  22. static BOOL txuiConvertKeisen(TX* text);
  23. BOOL txCaseWord(TX* text,BOOL fToLower);
  24.  
  25. //##文字の変換
  26.  
  27. BOOL txIDM_ZENHANWORD(TX* text)
  28. {
  29. //WZ4.00Bl 990911 IDM_ZENHANWORD(カーソル位置の1語または範囲内の全角/半角変換)を追加
  30. // 選択時は、範囲の先頭文字を見てどちらの変換をするか判断します。
  31.     int fClip = text->fClip;
  32.     txSetUndisp(text);
  33.     if (text->fClip) {
  34.         txJumpSelectTop(text);
  35.     } else {
  36.         txSelect(text);
  37.         if (isspace(txGetChar(text))){
  38.             txRightWord(text);
  39.         } else {
  40.             TXCHAR ch = txGetChar(text);
  41.             if (txchIsKanji(ch) && IschWord(pch_zen2han(text->buff+text->cur))) {
  42.                 //WZ4.00Bn 991006 IDM_ZENHANWORDをIDM_ZENHANWORDしたとき1回で半角に変換するようにした。
  43.                 mchar* p = text->buff + text->cur;
  44.                 mchar* p0 = p;
  45.                 while(1) {
  46.                     if (!IschWord(pch_zen2han(p))) break;
  47.                     p += 2;
  48.                 }
  49.                 txRightBytes(text,p - p0);
  50.             } else {
  51.                 txJumpWordEnd(text);
  52.             }
  53.         }
  54.         txJumpSelectTop(text);
  55.     }
  56.     if (txchIsKanji(txGetChar(text))) {
  57.         txJankToAnk(text);
  58.         txJkataToKana(text);
  59.     } else {
  60.         txAnkToJank(text);
  61.         txKanaToJkata(text);
  62.     }
  63.     if (fClip) {
  64.         text->fClipMouse = TRUE;
  65.     } else {
  66.         // 範囲選択してないときは次の文字へ移動
  67.         txJumpSelectEnd(text);
  68.         txSelectQuit(text);
  69.     }
  70.     txSetDisp(text);
  71.     return TRUE;
  72. }
  73.  
  74. BOOL txIDM_CASEWORD(TX* text)
  75. {
  76. //WZ4.00Bl 990911 IDM_CASEWORD(カーソル位置の1語または範囲内の大文字/小文字変換)を追加。
  77. // 選択時は、範囲の先頭文字を見てどちらの変換をするか判断します。
  78.     int fClip = text->fClip;
  79.     txSetUndisp(text);
  80.     if (text->fClip) {
  81.         txJumpSelectTop(text);
  82.     } else {
  83.         txSelect(text);
  84.         txJumpWordEndMi(text);
  85.         txJumpSelectTop(text);
  86.     }
  87.     {
  88.         TXCHAR c = txGetChar(text);
  89.         BOOL fKanji = txchIsKanji(c);
  90.         if (fKanji) {
  91.             txJankToAnk(text);
  92.             c = txGetChar(text);
  93.         }
  94.         txCaseWord(text,!islower(c));
  95.         if (fKanji) {
  96.             txAnkToJank(text);
  97.         }
  98.     }
  99.     if (fClip) {
  100.         text->fClipMouse = TRUE;
  101.     } else {
  102.         txSelectQuit(text);
  103.     }
  104.     txSetDisp(text);
  105.     return TRUE;
  106. }
  107.  
  108. void txAdjustZenHanSpace(TX* text,BOOL fSet)
  109. {
  110. // fSet=TRUE : 全角文字と半角文字の間に空白を一つあけます。
  111. // fSet=FALSE: 全角文字と半角文字の間の空白を削除します。
  112. // 範囲選択されているときは範囲内、されていないときはテキスト全体で処理
  113.     if (!txGetEditable(text)) return;    //WZ4.00Ac 990206 
  114.     if (text->fClip) {
  115.         txWalkStart(text);
  116.     } else {
  117.         if (question("文書のすべての全角/半角文字間の空白を調整します。\nよろしいですか?") != IDYES) return;    //WZ3.90N 981130 変換の確認を付けた
  118.         txMarkCur(text);
  119.         txSetUndisp(text);
  120.         txJumpFileTop(text);
  121.     }
  122.     if (fSet) {
  123.         while(1) {
  124.             mchar* p = text->buff + text->cur;
  125.             mchar c = *p;
  126.             if (text->fClip && !txIsWalking(text)) break;
  127.             if (isalnum(c)) {
  128.                 // 次の文字が漢字なら空白を挿入
  129.                 if (!txRight(text)) break;
  130.                 p = text->buff + text->cur;
  131.                 if (tbisideo(*p)) {
  132.                     txInsertChar(text,' ');
  133.                 }
  134.             } else if (tbisideo(c)) {
  135.                 TXCHAR ch = txGetChar(text);
  136.                 if (strchr("。。.?・!」)…",ch)) {
  137.                     //3.00A4 970509 英数字と全角文字の間に空白を空ける: 句読点と半角文字の間にも空白が入った
  138.                     if (!txRight(text)) break;
  139.                 } else {
  140.                     // 次の文字がalnumなら空白を挿入
  141.                     if (!txRight(text)) break;
  142.                     p = text->buff + text->cur;
  143.                     if (isalnum(*p)) {
  144.                         txInsertChar(text,' ');
  145.                     }
  146.                 }
  147.             } else {
  148.                 if (!txRight(text)) break;
  149.             }
  150.         }
  151.     } else {
  152.         while(1) {
  153.             mchar* p = text->buff + text->cur;
  154.             mchar c = *p;
  155.             if (text->fClip && !txIsWalking(text)) break;
  156.             if (isalnum(c)) {
  157.                 // 次の文字が空白+漢字なら空白を削除
  158.                 if (!txRight(text)) break;
  159.                 p = text->buff + text->cur;
  160.                 if (*p == ' ' && tbisideo(p[1])) {
  161.                     txDeleteChar(text);
  162.                 }
  163.             } else if (tbisideo(c)) {
  164.                 // 次の文字が空白+alnumなら空白を削除
  165.                 if (!txRight(text)) break;
  166.                 p = text->buff + text->cur;
  167.                 if (*p == ' ' && isalnum(p[1])) {
  168.                     txDeleteChar(text);
  169.                 }
  170.             } else {
  171.                 if (!txRight(text)) break;
  172.             }
  173.         }
  174.     }
  175.     if (text->fClip) {
  176.         txWalkEnd(text);
  177.     } else {
  178.         txJumpMarkCur(text);
  179.         txSetDisp(text);
  180.     }
  181. }
  182.  
  183. BOOL txSetZenHanSpace(TX* text)
  184. {
  185. // 英数字と全角文字の間に空白を空ける
  186. // 範囲選択されているときは範囲内、されてないときはテキスト全体が対象
  187.     txAdjustZenHanSpace(text,TRUE);
  188.     return TRUE;
  189. }
  190.  
  191. BOOL txClearZenHanSpace(TX* text)
  192. {
  193. // 英数字と全角文字の間の空白を削除
  194. // 範囲選択されているときは範囲内、されてないときはテキスト全体が対象
  195.     txAdjustZenHanSpace(text,FALSE);
  196.     return TRUE;
  197. }
  198.  
  199. BOOL txCaseWord(TX* text,BOOL fToLower)
  200. {
  201. // !fToLower:大文字/fToLower:小文字変換
  202. // 半角文字のみ変換
  203. // カーソル位置から1語を変換
  204. // 範囲選択しているときは、その範囲を変換。
  205.     if (!txGetEditable(text)) return FALSE;    //WZ4.00Ac 990206 
  206.     if (!text->fClip) {
  207.         int c = text->buff[text->cur];
  208.         if (!(isalpha(c) || c=='_' || c == '$')) return FALSE;
  209.     }
  210.     {
  211.         IFILE cur0 = txGetAddress(text);
  212.         
  213.         if (text->fClip) {
  214.             txWalkStart(text);
  215.         } else {
  216.             txSetUndisp(text);
  217.         }
  218.         while(1) {
  219.             int c = text->buff[text->cur];
  220.             if (text->fClip) {
  221.                 if (!txIsWalking(text)) break;
  222.             } else {
  223.                 if (!(isalpha(c) || c=='_' || c == '$')) break;
  224.             }
  225.             if (fToLower) {
  226.                 if (isupper(c)) {
  227.                     txInsertChar(text,c | 0x20);    // tolower
  228.                     txDeleteChar(text);
  229.                 } else {
  230.                     if (!txRight(text)) break;
  231.                 }
  232.             } else {
  233.                 if (islower(c)) {
  234.                     // 先に文字を挿入する。文字装飾を保護するため
  235.                     txInsertChar(text,c & 0xDF);    // toupper
  236.                     txDeleteChar(text);
  237.                 } else {
  238.                     if (!txRight(text)) break;
  239.                 }
  240.             }
  241.         }
  242.         if (text->fClip) {
  243.             txWalkEnd(text);
  244.         } else {
  245.             IFILE left = txGetAddress(text) - cur0;
  246.             txLeftBytes(text,left);
  247.             txSetDisp(text);
  248.         }
  249.     }
  250.     return TRUE;
  251. }
  252.  
  253. #if !__TXC__
  254. BOOL TXAPI txuiConvertChar(TX* text)
  255. {
  256.     static int mode = 0;
  257.     HDIALOG hd = dialog("変換");
  258.     dialogSetCustdata(hd,text);
  259.     //
  260.     dialogControlRadioV(hd);
  261.     dialogSetDialoghelp(hd,3);    // "文字の変換"
  262.     dialogChoiceRadio(hd,&mode,
  263.         "半角文字と全角文字の変換(&C)...",
  264.         "大文字へ変換(&U)",
  265.         "小文字へ変換(&L)",
  266.         _pspc ? "[A]の間に空白を空ける(&A)" : "英数字と全角文字の間に空白を空ける(&A)",
  267.         _pspc ? "[A]の間の空白を詰める(&Z)" : "英数字と全角文字の間の空白を詰める(&Z)",
  268.         "タブを空白に変換(&T)",
  269.         "空白をタブに変換(&P)",    //WZ4.00Bl 990911 「編集|変換」に「空白をタブに変換」を追加。
  270. #if !WZFUNC_CONVERTTEXT
  271.         "改行付きテキストをプレーンテキストに変換(&M)",
  272.         "改行付きテキストに変換(&P)",
  273. #endif
  274. #if WINDOWSCE
  275.         "テキストの変換(&E)...",    //WZ4.00Ab 990118 PWZ:「編集|変換」の項目変更
  276. #endif
  277. #if !WINDOWSCE
  278.         "行末の空白を除去(&S)",    //WZ3.90L 981116 
  279.         "表の変換(&B)...",        //WZ3.90J 981110 
  280.     #if !UNIX
  281.         "罫線文字の変換(&K)...",    //WZ3.90J 981110 
  282.     #endif
  283. #endif
  284.         NULL
  285.     );
  286.     if (_pspc) {
  287.         dialogCaption(hd,"  [A] = 英数字と全角文字");
  288.         hd->cx = DTCX * 30;hd->cy = DTCY * 13;
  289.     }
  290. #if WINDOWSCE2
  291.     hd->dialog->y = 0;    //WCE1.01 980312 
  292. #endif
  293.     if (dialogOpen(hd)) {
  294.         switch(mode) {
  295.             case 0:return txuiConvertCharZenhan(text);
  296.             case 1: txCaseWord(text,FALSE);break;
  297.             case 2: txCaseWord(text,TRUE);break;
  298.             case 3: txSetZenHanSpace(text);break;
  299.             case 4: txClearZenHanSpace(text);break;
  300.             case 5: {
  301.                 if (!text->fClip && question("文書のすべてのタブを変換します。\nよろしいですか?") != IDYES) {
  302.                     //WZ3.90N 981130 変換の確認を付けた
  303.                 } else {
  304.                     txTabToSpace(text);
  305.                 }
  306.                 break;
  307.             }
  308.             case 6: {
  309.                 if (question("文書のすべて行を変換します。\nよろしいですか?") == IDYES) {
  310.                     txSpaceToTab(text);
  311.                 }
  312.                 break;
  313.             }
  314. #if WZFUNC_CONVERTTEXT
  315.     #if WINDOWSCE
  316.             case 7: txIDM_UICONVERTTEXT(text);break;
  317.     #else
  318.             case 7: {
  319.                 //WZ3.90L 981116 
  320.                 if (question("文書のすべての行末の余白を削除します。\nよろしいですか?") == IDYES) {
  321.                     NPARA npara = text->npara;
  322.                     int ich = txGetParaIch(text);
  323.                     int ly = text->ly;
  324.                     txSetUndisp(text);
  325.                     txDeleteTailSpace(text);
  326.                     txJumpNpara(text,npara);txJumpParaIchEx(text,ich);txSetLy(text,ly);
  327.                     txSetDisp(text);
  328.                 }
  329.                 break;
  330.             }
  331.             case 8: txuiConvertTable(text);break;    //WZ3.90J 981110 
  332.         #if !UNIX
  333.             case 9: txuiConvertKeisen(text);break;    //WZ3.90J 981110 
  334.         #endif
  335.     #endif
  336. #else
  337.             case 7: txMailtextToPlaintext(text);break;
  338. //            case 8:txPlaintextToWordtext(text);break;// for DEBUG
  339.             case 8: txPlaintextToMailtext(text);break;
  340.     #if !WINDOWSCE
  341.             case 9: txuiConvertTable(text);break;    //WZ3.90J 981110 
  342.         #if !UNIX
  343.             case 10: txuiConvertKeisen(text);break;    //WZ3.90J 981110 
  344.         #endif
  345.     #endif
  346. #endif
  347.         }
  348.         return TRUE;
  349.     }
  350.     return FALSE;
  351. }
  352. #endif // !__TXC__
  353.  
  354. //##関数定義を検索
  355. //WZ3.90H 980911 new
  356.  
  357. BOOL txIbuffIsFunctionDefine(TX* text,IBUFF ibuff,HEADLINE_INFO* res)
  358. {
  359. // ibuffから始まる段落が、C関数定義の行かどうかを返す。
  360. // ibuffから段落終わりまでにGAPが存在してはいけない
  361. // 関数定義の場合は、res->offset,res->lchをセットする。
  362. // 関数定義でなければ、res->offset = res->lch = 0にする。
  363. //WZ3.90H 980911 new
  364.     IBUFF paraend = txIbuffGetParaEnd(text,ibuff);
  365.     BOOL f = FALSE;
  366.     mchar* szstr = text->buff + ibuff;
  367.     mchar* p = szstr;
  368.     mchar* pEnd = text->buff + paraend;
  369.     mchar c0 = *pEnd;
  370.     *pEnd = 0;
  371.     if (p = strchr(p,'(')) {
  372.         mchar* q = szstr;
  373.         int nWord = 0;
  374.         while(1) {
  375.             int lch = 0;
  376.             while(isspace(*q)) q++;
  377.             if (*q == '(') break;
  378.             while(IschWord(*q) || *q == '*' || *q == ':') {lch++;q++;}    //WZ3.90G 980827 ':' C++関数に対応
  379.             if (lch == 0) {
  380.                 nWord = 0;
  381.                 break;
  382.             }
  383.             nWord++;
  384.             if (res) {
  385.                 res->lch = lch;
  386.                 res->offset = q - szstr - lch;
  387.             }
  388.         }
  389.         if (nWord >= 2) {
  390.             //WZ4.00A 981227 Cプログラムで"else if (a==0)"の行が見出しになったのを改良
  391.             //WZ4.00Bj 990824 Cプログラムで"else if (a)"の行が見出しになったのを改良
  392.             //WZ4.00Bj 990824 (...)にも対応のため、renew
  393.             mchar* top = strGetWordTop(szstr);
  394.             int lch = strGetWordLen(top);
  395.             if (lch == 4 && !memcmp(top,"else",4)) {
  396.             } else {
  397.                 if (p = strchr(p,')')) {
  398.                     p++;
  399.                     while(isspace(*p)) p++;
  400.                     if (*p == '{') {    //WZ4.00Aa 990108 "void func(void) {"形式もC関数定義と見なすようにした
  401.                         p++;
  402.                         while(isspace(*p)) p++;
  403.                     }
  404.                     if (*p == 0) f = TRUE;
  405.                 }
  406.             }
  407.         }
  408.     }
  409.     *pEnd = c0;
  410.     if (f) return TRUE;
  411.     if (res) structClear(*res);
  412.     return FALSE;
  413. }
  414.  
  415. #if !WINDOWSCE
  416.  
  417. typedef struct {
  418.     FOLDER_WALK walk;
  419.     TX* text;
  420.     TX* textCache;
  421.     HWND hwndTitle;
  422.     mchar szFind[CCHWORD];
  423.     int lchFind;
  424.     LIST* list;
  425.     BOOL fOnCache;
  426.     BOOL fFlushText;    //WZ3.90H 980927 textのキャッシュを更新?
  427. } SEARCHFUNC;
  428.  
  429. typedef struct {
  430.     LISTITEM head;    // 必ず先頭にこれを入れる
  431. // mydata
  432.     mchar szname[CCHWORD];
  433.     int npara;
  434.     mchar szfilename[CCHPATHNAME];
  435. } SF_ITEM;
  436.  
  437. #define IDD_SEARCHFUNC        101
  438. #define IDD_FLUSHCACHETEXT    102
  439.  
  440. static void cacheAdd(SEARCHFUNC* arg,mchar* pFind,int lchFind,mchar* szfilename,NPARA npara)
  441. {
  442. // キャッシュに追加
  443.     TX* text = arg->textCache;
  444.     txJumpFileTop(text);
  445.     txInsertChar(text,'"');txInsert(text,szfilename);txInsert(text,"\" ");
  446.     txInsertf(text,"%ld ",npara);
  447.     txInsertChar(text,'"');txInsertBuff(text,pFind,lchFind);txInsertChar(text,'"');
  448.     txInsertReturn(text);
  449. }
  450.  
  451. static void cacheDelFile(SEARCHFUNC* arg,mchar *szfilename)
  452. {
  453. // szfilenameと同じファイル名のエントリを除く
  454.     TX* text = arg->textCache;
  455.     mchar szFind[CCHPATHNAME];
  456.     SEARCHMODE searchmode = SEARCH_PARATOP|SEARCH_NOSENSECASE|SEARCH_NOESC|SEARCH_CUR;
  457.     //
  458.     txJumpFileTop(text);
  459.     strcpy(szFind,szfilename);
  460.     pathSetLong(szFind);
  461.     //
  462.     while(1) {
  463.         if (txSearchEx(text,szFind,searchmode)) {
  464.             txDeletePara(text);
  465.             txJumpParaTop(text);
  466.         } else {
  467.             break;
  468.         }
  469.     }
  470. }
  471.  
  472. static BOOL _SearchFunctionFile(SEARCHFUNC* arg,wchar* wszfilename,BOOL fCacheMatch);
  473.  
  474. static void cacheSearch(SEARCHFUNC* arg)
  475. {
  476. // キャッシュから検索
  477.     TX* text = arg->textCache;
  478.     mchar szFind[CCHPATHNAME];
  479.     //
  480.     listDelAll(arg->list);listDispAll(arg->list);
  481.     if (arg->lchFind == 0) return;    //WZ4.00Ea 001111 検索文字列が空の時は検索処理をしないで高速化
  482.     //
  483.     txJumpFileTop(text);
  484.     strcpy(szFind,arg->szFind);pathSetLong(szFind);
  485.     arg->fOnCache = TRUE;
  486. //dialogaText(text,NULL);
  487.     while(1) {
  488.         int cch;
  489.         if (cch = txSearchEx(text,szFind,0)) {
  490.             txRightBytes(text,cch-1);
  491.             if (txIsCurReturn(text)) {
  492.                 mchar buff[CCHPATHNAME + 40];
  493.                 txGetParaEx(text,buff,sizeof(buff));
  494. //information(buff);
  495.                 {
  496.                     mchar szfilename[CCHPATHNAME];
  497.                     wchar wsz[CCHPATHNAME];
  498.                     mchar* p = buff;
  499.                     NPARA npara;
  500.                     sstrcpylen(szfilename,p,strGetWordLen(p));
  501.                     pathFormLong(szfilename);
  502.                     p += strGetWordLen(p);
  503.                     npara = atoi(strGetWordTop(p));
  504.                     strtowstr(szfilename,-1,wsz,CCHPATHNAME);
  505. //// _mailer.cの関数へのジャンプで遅い。関数定義がずれてないか調べているため。もっと早くできないか。
  506.                     if (!fileIsExistW(wsz)) {
  507.                         //WZ4.00Bg 990719 存在しないファイルがキャッシュに書かれているときに無限ループした。
  508.                         mchar szfilename[CCHPATHNAME];
  509.                         wpathtopath(wsz,szfilename);
  510. //printf("%s %d\n",szfilename,npara);
  511.                         //WZ4.00Bg 990719 
  512.                         cacheDelFile(arg,szfilename);
  513.                         // retry
  514.                         listDelAll(arg->list);listDispAll(arg->list);
  515.                         txJumpFileTop(text);
  516.                     } else if (npara && _SearchFunctionFile(arg,wsz,npara)) {
  517.                         SF_ITEM* item = zmalloc(sizeof(SF_ITEM));
  518.                         strcpy(item->szfilename,szfilename);
  519.                         item->npara = npara;
  520.                         sstrcpy(item->szname,pathGetFileName(item->szfilename));
  521.                         listAdd(arg->list,item);
  522.                         listDispAll(arg->list);
  523.                     } else {
  524.                         _SearchFunctionFile(arg,wsz,0);
  525.                     }
  526.                 }
  527.             }
  528.         } else {
  529.             break;
  530.         }
  531.     }
  532.     arg->fOnCache = FALSE;
  533. }
  534.  
  535. static void sfAdd(SEARCHFUNC* arg,TX* text,NPARA npara)
  536. {
  537.     if (!arg->fOnCache && !arg->fFlushText) {
  538.         SF_ITEM* item = zmalloc(sizeof(SF_ITEM));
  539.         strcpy(item->szfilename,text->szfilename);
  540.         item->npara = npara;
  541.         sstrcpy(item->szname,pathGetFileName(item->szfilename));
  542.         listAdd(arg->list,item);
  543.         listDispAll(arg->list);
  544.     }
  545. }
  546.  
  547. static BOOL sfRe(SEARCHFUNC* arg,TX* text,mchar* szRe,int iTag,BOOL fCacheMatch)
  548. {
  549.     txJumpFileTop(text);
  550.     txSetHigh(text);
  551.     while(1) {
  552.         if (txSearchEx(text,szRe,SEARCH_REWZ|SEARCH_CUR)) {
  553.             int lch = retagGetLch(iTag);
  554.             if (lch == arg->lchFind) {
  555.                 mchar szbuff[CCHWORD];
  556.                 retagGetEx(iTag,szbuff,CCHWORD);
  557. //statprintf(szbuff);
  558.                 if (!memcmp(szbuff,arg->szFind,arg->lchFind)) {
  559.                     if (fCacheMatch) {
  560.                         if (fCacheMatch == text->npara) {
  561.                             textclose(text);
  562.                             return TRUE;
  563.                         }
  564.                     } else {
  565.                         sfAdd(arg,text,text->npara);
  566.                     }
  567.                 }
  568.             }
  569.             if (!fCacheMatch) {
  570.                 mchar szbuff[CCHWORD];
  571.                 retagGetEx(iTag,szbuff,CCHWORD);
  572.                 cacheAdd(arg,szbuff,lch,text->szfilename,text->npara);
  573.             }
  574.         } else {
  575.             break;
  576.         }
  577.         if (!txNextPara(text)) break;
  578.     }
  579.     txResetHigh(text);
  580.     return FALSE;
  581. }
  582.  
  583. static BOOL _SearchFunctionFile(SEARCHFUNC* arg,wchar* wszfilename,BOOL fCacheMatch)
  584. {
  585. // fCacheMatch != 0なら、arg->szFindがfCacheMatchと等しい段落にあればTRUE、
  586. // なければFALSEを返す
  587. // fCacheMatch == 0なら、wszfilenameについてarg->szFindにマッチするエントリを
  588. // arg->listおよびキャッシュに追加する。
  589.     TX* text;
  590.     IFILE adr0;
  591.     int ly0;
  592.     if (arg->fFlushText) {
  593.         text = arg->text;
  594.         adr0 = txGetAddress(text);
  595.         ly0 = text->ly;
  596.         txSetUndisp(text);
  597.     } else {
  598.         text = textopenW(wszfilename);
  599.     }
  600.     if (!text) return FALSE;    //WZ4.00Bl 990917 排他制御読み書き禁止で関数定義を検索するとアプリエラーになる場合があったのを修正。
  601.     if (!fCacheMatch) cacheDelFile(arg,text->szfilename);
  602.     {    // 関数定義
  603.         txJumpFileTop(text);
  604.         {
  605.             IBUFF ibuff = text->cur;
  606.             NPARA npara = 1;
  607.             while(1) {
  608.                 HEADLINE_INFO res;
  609.                 if (txIbuffIsFunctionDefine(text,ibuff,&res)) {
  610.                     mchar* p = text->buff + ibuff + res.offset;
  611.                     if (res.lch == arg->lchFind) {
  612.                         if (!memcmp(p,arg->szFind,arg->lchFind)) {
  613.                             if (fCacheMatch) {
  614.                                 if (fCacheMatch == npara) {textclose(text);return TRUE;}
  615.                             } else {
  616.                                 sfAdd(arg,text,npara);
  617.                             }
  618.                         }
  619.                     }
  620.                     if (!fCacheMatch) {
  621. //if (arg->fFlushText) {mchar* sz = strdupLen(p,text->lchHeadlineContent);information(sz);free(sz);}
  622.                         cacheAdd(arg,p,res.lch,text->szfilename,npara);
  623.                     }
  624.                 }
  625.                 ibuff = txIbuffGetNextPara(text,ibuff);
  626.                 if (ibuff == IBUFF_ERROR) break;
  627.                 npara++;
  628.             }
  629.         }
  630.     }
  631.     {    // #define
  632.         if (sfRe(arg,text,"^\\s*#define\\s+(\\w+)",0,fCacheMatch)) return TRUE;
  633.     }
  634.     {    // typedef FOLDER_WALK
  635.         if (sfRe(arg,text,"^\\s*}\\s+(\\w+)\\s*;",0,fCacheMatch)) return TRUE;
  636.         if (sfRe(arg,text,"^\\s*typedef.+(\\w+)\\s*;",0,fCacheMatch)) return TRUE;
  637.     }
  638.     //
  639.     if (arg->fFlushText) {
  640.         txJumpAddress(text,adr0);
  641.         txSetLy(text,ly0);
  642.         txSetDisp(text);
  643.     } else {
  644.         textclose(text);
  645.     }
  646.     if (fCacheMatch) return FALSE;
  647.     return TRUE;
  648. }
  649.  
  650. static BOOL SearchFunctionFile(SEARCHFUNC* arg,wchar* wszfilename)
  651. {
  652.     if (wpathIsBackupfile(wszfilename)) return FALSE;
  653.     {
  654.         wchar buff[CCHWORD];
  655.         wstrcpy(buff,L"関数定義を検索中(中止=Esc押し続け) - ");
  656.         wsstrcat(buff,wpathGetFileName(wszfilename));
  657.         SetWindowText_W(arg->hwndTitle,buff);
  658.         if (GetAsyncKeyState(VK_ESCAPE) < 0) {
  659.             arg->walk.fAborted = TRUE;
  660.             return FALSE;
  661.         }
  662.     }
  663.     return _SearchFunctionFile(arg,wszfilename,FALSE);
  664. }
  665.  
  666. static BOOL SearchFunction(SEARCHFUNC* arg,wchar* wszPath)
  667. {
  668.     int ret;
  669.     listDelAll(arg->list);
  670.     arg->walk.appContext = arg;
  671.     arg->walk.appProc = SearchFunctionFile;
  672. #if __TXC__
  673.     arg->walk.fTXC = TRUE;
  674. #endif
  675.     ret = folderWalk(&arg->walk,wszPath);
  676.     txDoCaption(arg->text);
  677.     return ret;
  678. }
  679.  
  680. typedef struct {
  681.     mchar szpath[CCHPATHNAME];
  682.     SEARCHFUNC arg;
  683.     BOOL fFirst;
  684.     BOOL fJump;
  685.     BOOL fTimer;
  686.     SF_ITEM item;
  687. } SF_DIALOG;
  688.  
  689. static BBOOL _fOpenMulti = FALSE;    //WZ3.90H 980915 
  690.  
  691. // 設定
  692. static mchar p_szmask[CCHWORD];
  693. static BBOOL p_fSearchSubDirectory = TRUE;
  694.  
  695. static void searchfuncConfigGetset(BOOL fSet)
  696. {
  697.     TX* text = txMbxOpenWzapp("uiSearchFunction");
  698.     if (text) {
  699.         txMsghdrGetsetIntInitB(text,"fSubDir:",TRUE,&p_fSearchSubDirectory,fSet);
  700.         txMsghdrGetsetStringInit(text,"mask:","*.c;*.cpp;*.h",p_szmask,cchof(p_szmask),fSet);
  701.     }
  702.     txMbxClose(text);
  703. }
  704.  
  705. static void searchfuncConfigLoad(void)
  706. {
  707.     searchfuncConfigGetset(FALSE);
  708. }
  709.  
  710. static void searchfuncConfigSave(void)
  711. {
  712.     searchfuncConfigGetset(TRUE);
  713. }
  714.  
  715. void buttonSetDefault(HWND hwnd,BOOL fSet)
  716. {
  717.     DWORD ws = GetWindowLong(hwnd,GWL_STYLE);
  718.     if (fSet) ws |= BS_DEFPUSHBUTTON; else ws &= ~BS_DEFPUSHBUTTON;
  719.     SetWindowLong(hwnd,GWL_STYLE,ws);
  720. }
  721.  
  722. static void hwndSearchFunctionFlushDefButton(HWND hwnd)
  723. {
  724. #if 0    //WZ3.90I 981102 使いにくいので廃止
  725.     HDIALOG hd = dialogFromHwnd(hwnd);
  726.     SF_DIALOG* context = (LPVOID)dialogGetCustdata(hd);
  727.     if (context->arg.szFind[0]) {
  728.         BOOL fSearch = (context->arg.list->n == 0);
  729.         if (fSearch) {
  730.             HWND hctrl = GetDlgItem(hwnd,IDD_SEARCH);
  731.             SetFocus(hctrl);
  732.             buttonSetDefault(hctrl,TRUE);
  733.             buttonSetDefault(GetDlgItem(hwnd,IDD_JUMP),FALSE);
  734.         } else {
  735.             HWND hctrl = GetDlgItem(hwnd,IDD_JUMP);
  736.             SetFocus(hctrl);
  737.             buttonSetDefault(hctrl,TRUE);
  738.             buttonSetDefault(GetDlgItem(hwnd,IDD_SEARCH),FALSE);
  739.         }
  740.     } else {
  741.         SetFocus(GetDlgItem(hwnd,IDD_SEARCHFUNC));
  742.     }
  743. #endif
  744. }
  745.  
  746. static void searchfuncOnTimer(HWND hwnd,BOOL fMove)
  747. {
  748.     HDIALOG hd = dialogFromHwnd(hwnd);
  749.     SF_DIALOG* context = (LPVOID)dialogGetCustdata(hd);
  750.     //
  751.     context->fTimer = FALSE;
  752.     wndSetTimer(hwnd,WM_TIMER_TXUSER,0);
  753.     dialogRead(hd);
  754.     {
  755.         SEARCHFUNC* arg = &context->arg;
  756.         arg->lchFind = strlen(arg->szFind);
  757.         cacheSearch(arg);
  758.         if (fMove) {
  759.             hwndSearchFunctionFlushDefButton(hwnd);
  760.             if (arg->list->n >= 2) SetFocus(arg->list->hwnd);
  761.         } else {
  762.             // 通常はフォーカスをボタンに移動しない。移動すると使いにくい
  763.         }
  764.     }
  765. }
  766.  
  767. BOOL CALLBACK dlgprocSearchFunction(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  768. {
  769.     HDIALOG hd = dialogFromHwnd(hwnd);
  770.     SF_DIALOG* context = (LPVOID)dialogGetCustdata(hd);
  771.     switch(message) {
  772.         case WM_INITDIALOG: {
  773.             LIST* list = listFromHwnd(GetDlgItem(hwnd,IDD_LIST));
  774.             SF_ITEM item;
  775.             SUBLISTITEMATR* atr = &list->tSubitem[0];
  776.             atr->type = LISTITEM_SZ;
  777.             atr->offset = (LPBYTE)item.szname - (LPBYTE)&item;
  778.             atr->cx = dtcx(DTCX * 20);
  779.                 atr++;
  780.             atr->type = LISTITEM_INT;
  781.             atr->offset = (LPBYTE)&item.npara - (LPBYTE)&item;
  782.             atr->cx = dtcx(DTCX * 6);
  783.                 atr++;
  784.             atr->type = LISTITEM_SZ;
  785.             atr->offset = (LPBYTE)item.szfilename - (LPBYTE)&item;
  786.             atr->cx = dtcx(DTCX * 40);
  787.                 atr++;
  788.             list->nSubitem = atr - &list->tSubitem[0];
  789.             //
  790.             context->fFirst = TRUE;
  791.             PostMessage(hwnd,WM_TXUSER,0,0);
  792.             //
  793.             {
  794.                 SEARCHFUNC* arg = &context->arg;
  795.                 arg->list = list;
  796.                 arg->lchFind = strlen(arg->szFind);
  797.                 cacheSearch(arg);
  798.                 hwndSearchFunctionFlushDefButton(hwnd);
  799.                 if (arg->list->n >= 2) SetFocus(arg->list->hwnd);
  800.                 return INITDIALOG_FALSE;
  801.             }
  802.             break;
  803.         }
  804.         case WM_COMMAND: {
  805.             int id = GET_WM_COMMAND_ID(wParam,lParam);
  806.             int cmd = GET_WM_COMMAND_CMD(wParam,lParam);
  807.             LIST* list = listFromHwnd(GetDlgItem(hwnd,IDD_LIST));
  808.             switch(id) {
  809.                 case IDD_SEARCHFUNC: {
  810.                     if (!context->fFirst) {
  811.                         if (cmd == CBN_EDITCHANGE || cmd == CBN_SELCHANGE) {
  812.                             context->fTimer = TRUE;
  813.                             wndSetTimer(hwnd,WM_TIMER_TXUSER,500);
  814.                         }
  815.                     }
  816.                     break;
  817.                 }
  818.                 case IDD_JUMP: {
  819.                     if (context->fTimer) {
  820.                         // まだ更新してなかったら、更新する
  821.                         SendMessage(hwnd,WM_TIMER,WM_TIMER_TXUSER,0);
  822.                     }
  823.                     {
  824.                         SF_ITEM* item = listReadCur(list);
  825.                         if (item) {
  826.                             context->item = *item;
  827.                             context->fJump = TRUE;
  828.                         }
  829.                     }
  830.                     break;
  831.                 }
  832.                 case IDD_FLUSHCACHETEXT: {
  833.                     // キャッシュ内の現在のテキストの関数一覧を更新する。
  834.                     SEARCHFUNC* arg = &context->arg;
  835.                     if (arg->text->fEdit) {
  836.                         information("テキストは編集されています。\n保存してから再度実行してください。");
  837.                     } else {
  838.                         arg->fFlushText = TRUE;
  839.                             arg->lchFind = 0;
  840.                             _SearchFunctionFile(arg,NULL,FALSE);
  841.                         arg->fFlushText = FALSE;
  842.                         //
  843.                         searchfuncOnTimer(hwnd,TRUE);
  844.                     }
  845.                     return TRUE;
  846.                 }
  847.                 case IDD_SEARCH: {
  848.                     mchar szpath[CCHPATHNAME];
  849.                     dialogRead(hd);
  850.                     strcpy(szpath,context->szpath);
  851.                     pathSetDir(szpath);
  852.                     pathSetFileName(szpath,p_szmask);
  853.                     //
  854.                     {
  855.                         wchar wsz[CCHPATHNAME];
  856.                         SEARCHFUNC* arg = &context->arg;
  857.                         strtowstr(szpath,-1,wsz,CCHPATHNAME);
  858. //winformation(wsz);
  859.                         arg->walk.fSearchSubFolder = p_fSearchSubDirectory;
  860.                         arg->hwndTitle = hwnd;
  861.                         arg->lchFind = strlen(arg->szFind);
  862. //information(arg.szFind);
  863.                         //
  864.                         SearchFunction(arg,wsz);
  865.                         SetWindowText_A(hwnd,"関数定義を検索");
  866.                         cacheSearch(arg);
  867.                         hwndSearchFunctionFlushDefButton(hwnd);
  868.                     }
  869.                     return TRUE;
  870.                 }
  871.             }
  872.             break;
  873.         }
  874.         case WM_TIMER: {
  875.             searchfuncOnTimer(hwnd,FALSE);
  876.             break;
  877.         }
  878.         case WM_TXUSER: {
  879.             context->fFirst = FALSE;
  880.             break;
  881.         }
  882.         case WM_NOTIFY: {    //WZ4.00Bl 990914 (!PWZ)「関数定義を検索」でリストをダブルクリックしてジャンプするようにした。ユーザ要望。
  883.             LISTNOTIFY* notify = (LPVOID)lParam;
  884.             LIST* list = listFromHwnd(GetDlgItem(hwnd,IDD_LIST));
  885.             if (list && notify->hdr.hwndFrom == list->hwnd) {
  886.                 if (notify->hdr.code == LISTN_FORWARD && notify->message == WM_LBUTTONDBLCLK) {
  887.                     PostMessage(hwnd,WM_COMMAND,IDD_JUMP,0);
  888.                 }
  889.             }
  890.             break;
  891.         }
  892.     }
  893.     return FALSE;
  894. }
  895.  
  896. static void pathForm(mchar* szpath)
  897. {
  898. // pathをDOSのパス形式に変換
  899. // "a:\wz\wz.exe" -> "a:\wz"
  900. // "a:\abc"       -> "a:\"
  901. //WZ3.90H 980911 new
  902.     pathSetFileName(szpath,NULL);
  903.     pathFormDirDos(szpath);
  904. }
  905.  
  906. BOOL txIDM_SEARCHFUNCTION(TX* text)
  907. {
  908.     HDIALOG hd = dialog("関数定義を検索");
  909.     static mchar szhist[] = "searchfunction";
  910.     HSTRBLK sb = historyOpen(szhist,4096);
  911.     DTRECT r;
  912.     SF_DIALOG context;
  913.     //
  914.     searchfuncConfigLoad();
  915.     //
  916.     structClear(context);
  917.     context.arg.text = text;
  918.     context.arg.walk.fNoSearchWindows = TRUE;
  919.     context.arg.walk.fNoSearchBinaryFiletype = TRUE;
  920.     context.arg.walk.fNoSearchBigFile = TRUE;
  921.     {
  922.         wchar wszdicname[CCHPATHNAME];
  923.         context.arg.textCache = textopenW(wpathFullConfig(wszdicname,L"dtgcache.dic"));
  924.         txSetHigh(context.arg.textCache);    //WZ3.90I 981005 高速化
  925.     }
  926.     //
  927.     dialogSetCustdata(hd,&context);
  928.     dialogSetDlgproc(hd,dlgprocSearchFunction);
  929.     //
  930.     strcpy(context.szpath,text->szfilename);
  931.     pathForm(context.szpath);
  932.     //
  933.     txGetWordAfterEx(text,context.arg.szFind,CCHWORD);
  934.     //
  935.     dialogControlID(hd,IDD_SEARCHFUNC);
  936.     dialogControlStrblkHist(hd,sb);hd->fHistRead = TRUE;
  937.     dialogString(hd,"検索する関数(&S):",16,context.arg.szFind,CCHWORD,20);
  938.     dialogString(hd,"検索マスク(&M):",16,p_szmask,cchof(p_szmask),20);
  939.     //
  940.     dialogControlRefer(hd,"-d *.*");
  941.     dialogString(hd,"検索フォルダ(&F):",16,context.szpath,CCHPATHNAME,37);
  942.     //
  943.     dialogSetH(hd);
  944.     dialogCheckB(hd,"サブフォルダも検索(&U)",&p_fSearchSubDirectory);
  945.     dialogCheckB(hd,"多重化(&I)",&_fOpenMulti);    //WZ3.90H 980915 
  946.     dialogLFSetV(hd);
  947.     //
  948.     dialogSpaceV(hd);
  949.     dialogCaption(hd,"一覧(&D):");
  950.     dialogGetPos(hd,&r);
  951.     r.cx = DTCX * 60;
  952.     r.cy = DTCY * 9;
  953. //    listRegister();
  954.     __dialogAddItem(hd,szclassList,NULL,IDD_LIST,&r,WS_GROUP|WS_TABSTOP|WS_BORDER|WS_CHILD|WS_VISIBLE|LIST_WS_DEFAULT);
  955.     //
  956.     dialogLFV(hd);
  957.     dialogControlID(hd,IDD_JUMP);
  958.     dialogCmdDefault(hd,"ジャンプ(&J)",13);
  959.     dialogCancel(hd,13);
  960.     dialogSpaceV(hd);
  961.     dialogControlID(hd,IDD_SEARCH);
  962.     dialogCmd(hd,"検索(&X)",13);
  963.     dialogControlID(hd,IDD_FLUSHCACHETEXT);
  964.     dialogCmd(hd,"テキストを更新(&L)",13);
  965.     //
  966.     dialogOpen(hd);
  967.     //
  968.     txSave(context.arg.textCache);
  969.     textclose(context.arg.textCache);
  970.     searchfuncConfigSave();
  971.     //
  972.     if (context.fJump) {    // ダイアログを閉じてからジャンプする for 他でダイアログオープン中が出ないように。
  973.         mchar sz[40];
  974.         jumphistAdd(text);
  975.         //WZ4.00Bl 990922 /k -> /kpj for 「設定の切り替え」の記憶を読むように。
  976.     #if UNIX
  977.         sprintf_A(sz,"-kpj -J%d -Yc %s",context.item.npara,_fOpenMulti ? "-mt" : "");
  978.     #else
  979.         sprintf_A(sz,"/kpj /J%d /Yc %s",context.item.npara,_fOpenMulti ? "/mt" : "");
  980.     #endif
  981.         forkstd(context.item.szfilename,sz);
  982.         histAdd(sb,context.arg.szFind);
  983.     }
  984.     historyClose(szhist,sb);
  985.     return TRUE;
  986. }
  987.  
  988. #endif    // !WINDOWSCE
  989.  
  990. //##文字列の補完
  991. // HIST_STRも補完辞書として活用
  992. // HIST_COMPLETEに学習する
  993.  
  994. static mchar _szCompleteHist[] = "HIST_COMPLETE";
  995. #define SIZE_COMPLETEHIST    1024
  996.  
  997. #define IFIND_HIST_LAST            24999
  998. #define IFIND_END_HISTCOMPLETE    24999
  999. #define IFIND_TOP_HISTCOMPLETE    20000
  1000. #define IFIND_END_HISTSTR        19999
  1001. #define IFIND_TOP_HISTSTR        15000
  1002. #define IFIND_END_HISTSEARCH    14999
  1003. #define IFIND_TOP_HISTSEARCH    10000
  1004. #define IFIND_HIST_TOP            10000
  1005. #define IFIND_NONE        -1
  1006.  
  1007. static int _completeSearchHist(HHIST h,int ifind,BOOL fPrev,mchar* szdst,mchar* szstr)
  1008. {
  1009.     int top;
  1010.     int end;
  1011.     HSTRBLK sb;
  1012.     
  1013.     if (h == HIST_SEARCH) {
  1014.         top = IFIND_TOP_HISTSEARCH;
  1015.         end = IFIND_END_HISTSEARCH;
  1016.         sb = sbFromHist(h);
  1017. #if 0//WCE0.91 970914 
  1018.     } else if (h == HIST_STR) {
  1019.         top = IFIND_TOP_HISTSTR;
  1020.         end = IFIND_END_HISTSTR;
  1021.         sb = sbFromHist(h);
  1022. #endif
  1023.     } else {
  1024.         top = IFIND_TOP_HISTCOMPLETE;
  1025.         end = IFIND_END_HISTCOMPLETE;
  1026.         sb = h;
  1027.     }
  1028.     //
  1029.     if (ifind == end) {
  1030.         ifind = sbGetCount(sb);
  1031.     } else {
  1032.         ifind -= top;
  1033.     }
  1034.     //
  1035.     if (fPrev) {
  1036.         ifind = sbiSearchNext(sb,szstr,ifind);
  1037.     } else {
  1038.         ifind = sbiSearchPrev(sb,szstr,ifind);
  1039.     }
  1040.     //
  1041.     if (ifind == -1) {
  1042.         if (fPrev) {
  1043.             ifind = IFIND_NONE;
  1044.         } else {
  1045.             ifind = 0;
  1046.         }
  1047.     } else {
  1048.         strcpymax(szdst,sbRead(sb,ifind),CCHWORD);
  1049.         ifind += top;
  1050.     }
  1051.     return ifind;
  1052. }
  1053.  
  1054. static int completeSearchHist(int ifind,BOOL fPrev,mchar* szdst,mchar* szstr,HSTRBLK sbComplete)
  1055. {
  1056. #if 1//WCE0.91 970914 
  1057.     if (IFIND_TOP_HISTCOMPLETE <= ifind && ifind <= IFIND_END_HISTCOMPLETE) {
  1058.         ifind = _completeSearchHist(sbComplete,ifind,fPrev,szdst,szstr);
  1059.         if (ifind != 0) return ifind;
  1060.         ifind = IFIND_END_HISTSEARCH;
  1061.     }
  1062.     return _completeSearchHist(HIST_SEARCH,ifind,fPrev,szdst,szstr);
  1063. #else
  1064.     if (IFIND_TOP_HISTCOMPLETE <= ifind && ifind <= IFIND_END_HISTCOMPLETE) {
  1065.         ifind = _completeSearchHist(sbComplete,ifind,fPrev,szdst,szstr);
  1066.         if (ifind != 0) return ifind;
  1067.         ifind = IFIND_END_HISTSTR;
  1068.     }
  1069.     if (IFIND_TOP_HISTSTR <= ifind && ifind <= IFIND_END_HISTSTR) {
  1070.         ifind = _completeSearchHist(HIST_STR,ifind,fPrev,szdst,szstr);
  1071.         if (ifind != 0) return ifind;
  1072.         ifind = IFIND_END_HISTSEARCH;
  1073.     }
  1074.     return _completeSearchHist(HIST_SEARCH,ifind,fPrev,szdst,szstr);
  1075. #endif
  1076. }
  1077.  
  1078. static int _completeSearch(mchar szdst[CCHWORD],mchar* szstr,int ifind,BOOL fPrev,HSTRBLK sbComplete)
  1079. {
  1080.     szdst[0] = 0;
  1081.     if (ifind == IFIND_NONE) {
  1082.     } else if (ifind >= IFIND_HIST_TOP) {
  1083.         ifind = completeSearchHist(ifind,fPrev,szdst,szstr,sbComplete);
  1084.     } else {
  1085.         wchar wszfilename[CCHPATHNAME];
  1086.         TX* text = textopenW(wpathFullConfig(wszfilename,L"complete.dic"));
  1087.         if (text) {
  1088.             text->fHeadlineStringStd = TRUE;//PWZ2BETA0.3 980509 
  1089.             if (fPrev) {
  1090.                 txJumpPara(text,ifind);
  1091.             } else {
  1092.                 txJumpPara(text,ifind + 1);
  1093.             }
  1094.             if (
  1095.                 szstr[0] && //2.99D 970402 新規作成で開いた直後、文字列の補完を行うとハングした
  1096.                 txSearchEx(text,szstr,(fPrev ? SEARCH_PREV : SEARCH_CUR)|SEARCH_NOSENSECASE|SEARCH_NOSENSEZENHAN|SEARCH_PARATOP)
  1097.             ) {
  1098.                 mchar sz[CCHLINE];
  1099.                 txGetParaEx(text,sz,cchof(sz));
  1100.                 ifind = text->npara;
  1101.                 strcpymax(szdst,sz,CCHWORD);
  1102.             } else {
  1103.                 if (fPrev) {
  1104.                     ifind = IFIND_HIST_TOP;
  1105.                 } else {
  1106.                     ifind = IFIND_NONE;
  1107.                 }
  1108.             }
  1109.         } else {
  1110.             if (fPrev) {
  1111.                 ifind = IFIND_HIST_TOP;
  1112.             } else {
  1113.                 ifind = IFIND_NONE;
  1114.             }
  1115.         }
  1116.         textclose(text);
  1117.     }
  1118.     return ifind;
  1119. }
  1120.  
  1121. static int completeSearch(mchar szdst[CCHWORD],mchar* szstr,int i,BOOL fPrev,HSTRBLK sbComplete)
  1122. {
  1123.     while(1) {
  1124.         i = _completeSearch(szdst,szstr,i,fPrev,sbComplete);
  1125.         if (i == IFIND_NONE) return i;
  1126.         if (szdst[0]) return i;
  1127.     }
  1128. }
  1129.  
  1130. static BOOL _complete(tx* text,BOOL fPrev,HSTRBLK sbComplete)
  1131. {
  1132.     static mchar _szstr[CCHWORD];    // 前回検索をかけた文字列
  1133.     static int _ifind;            // 前回検索をかけたインデックス
  1134.     static IFILE _adr = -1;        // 前回検索をかけたアドレス
  1135.     static int _lchInsert;        // 前回挿入したバイト数
  1136.     static BOOL _fPrev = -1;    // 前回の方向
  1137.     static mchar szbuff[CCHWORD];// 前回挿入した文字列
  1138.     BOOL ret = FALSE;
  1139.     mchar szstr[CCHWORD];
  1140.     IFILE adr = txGetAddress(text);
  1141.     
  1142.     if (adr == _adr) {
  1143.         if (_ifind == -1) {
  1144.             if (_fPrev == fPrev) {
  1145.                 return FALSE;
  1146.             } else {
  1147.                 if (fPrev) {
  1148.                     _ifind = IFIND_HIST_TOP - 1;
  1149.                 } else {
  1150.                     _ifind = IFIND_HIST_LAST;
  1151.                 }
  1152.             }
  1153.         }
  1154.     } else {
  1155.         if (szbuff[0]) sbAddHist(sbComplete,szbuff);    // 学習
  1156.         txSelectEx(text,CLIP_CHAR);
  1157.         txLeft(text);
  1158.         txJumpWordTopMi(text);
  1159.         txGetWordEx(text,szstr,cchof(szstr));
  1160.         txSelectQuit(text);
  1161.         //1.99A 補完できないときにカーソルが単語の先頭に飛んだ
  1162.         txRightBytes(text,strlen(szstr));
  1163.         //
  1164.         strcpy(_szstr,szstr);
  1165.         _ifind = IFIND_HIST_LAST;
  1166.         _lchInsert = 0;
  1167.     }
  1168.     {
  1169.         int i = completeSearch(szbuff,_szstr,_ifind,fPrev,sbComplete);
  1170.         if (i >= 0) {
  1171.             _ifind = i;
  1172.             if (_lchInsert) {
  1173.                 txLeftBytes(text,_lchInsert);
  1174.                 txDeleteBytes(text,_lchInsert);
  1175.             } else {
  1176.                 int lchOld = strlen(_szstr);
  1177.                 txLeftBytes(text,lchOld);//1.99A 
  1178.                 txDeleteBytes(text,lchOld);
  1179.             }
  1180.             _lchInsert = strlen(szbuff);
  1181.             txInsert(text,szbuff);
  1182.             ret = TRUE;
  1183.         } else {
  1184.             _ifind = -1;
  1185.         }
  1186.     }
  1187.     _adr = txGetAddress(text);
  1188.     _fPrev = fPrev;
  1189.     return ret;
  1190. }
  1191.  
  1192. static BOOL complete(tx* text,BOOL fPrev)
  1193. {
  1194. //WCE0.91 970914 文字列の補完追加
  1195.     HSTRBLK sb = historyOpen(_szCompleteHist,SIZE_COMPLETEHIST);
  1196.     BOOL ret;
  1197.     text->fUndispSelect++;
  1198.     text->fUndispCursor++;
  1199.     ret = _complete(text,fPrev,sb);
  1200.     text->fUndispSelect--;
  1201.     text->fUndispCursor--;
  1202.     txDispCursor(text);
  1203.     txDispLocate(text);
  1204.     historyClose(_szCompleteHist,sb);
  1205.     return ret;
  1206. }
  1207.  
  1208. BOOL txIDM_COMPLETEPREV(TX* text)
  1209. {
  1210.     return complete(text,TRUE);
  1211. }
  1212.  
  1213. BOOL txIDM_COMPLETENEXT(TX* text)
  1214. {
  1215.     return complete(text,FALSE);
  1216. }
  1217.  
  1218. static BOOL completeAddDic(mchar* szstr)
  1219. {
  1220. //WZ3.90H 980912 new
  1221.     if (szstr[0] == 0) {
  1222.         return FALSE;
  1223.     } else {
  1224.         BOOL ret = FALSE;
  1225.         mchar szfilename[CCHPATHNAME];
  1226.         TX* text = textopen(pathFullConfig(szfilename,"complete.dic"));
  1227.         {
  1228.             BOOL f = FALSE;
  1229.             while(1) {
  1230.                 if (txSearchEx(text,szstr,SEARCH_CUR|SEARCH_NOSENSECASE|SEARCH_NOSENSEZENHAN|SEARCH_PARATOP)) {
  1231.                     mchar sz[CCHWORD];
  1232.                     txGetParaEx(text,sz,CCHWORD);
  1233.                     if (!stricmp(sz,szstr)) {
  1234.                         f = TRUE;
  1235.                         statprintf("%sは既に登録されています",szstr);
  1236.                         break;
  1237.                     }
  1238.                     if (!txNextPara(text)) break;
  1239.                 } else {
  1240.                     break;
  1241.                 }
  1242.             }
  1243.             if (!f) {
  1244.                 txJumpFileTop(text);
  1245.                 txInsert(text,szstr);
  1246.                 txInsertReturn(text);
  1247.                 txSave(text);
  1248.                 statprintf("%sを登録しました",szstr);
  1249.                 ret = TRUE;
  1250.             }
  1251.         }
  1252.         textclose(text);
  1253.         return ret;
  1254.     }
  1255. }
  1256.  
  1257. static BOOL uiCompleteAddDic(mchar* szstr)
  1258. {
  1259. //WZ3.90H 980912 new
  1260.     HDIALOG hd = dialog("文字列補完辞書への登録");
  1261.     BOOL ret = FALSE;
  1262.     mchar sz[CCHWORD];
  1263.     strcpy(sz,szstr);
  1264.     dialogString(hd,"登録する文字列(&S):",20,sz,CCHWORD,30);
  1265.     if (dialogOpen(hd)) {
  1266.         ret = completeAddDic(sz);
  1267.     }
  1268.     return ret;
  1269. }
  1270.  
  1271. //##入力支援
  1272. // テキストファイルを指定して、そのファイルを辞書として使って入力支援できるようにした
  1273. //WZ3.90H 980912 new
  1274.  
  1275. #if !WINDOWSCE
  1276.  
  1277. #define IDD_TOP_PREV        200
  1278. #define IDD_TOP_NEXT        201
  1279. #define IDD_END_PREV        202
  1280. #define IDD_END_NEXT        203
  1281. #define IDD_TARGET            204
  1282. #define IDD_LISTCAPTION        206
  1283. #define IDD_TEXT            207
  1284. #define IDD_TEXTPARA        208    // 209も使用
  1285. #define IDD_HISTSEARCH        210
  1286. #define IDD_GUIDE            211
  1287. #define IDD_WRING            212
  1288. #define IDD_ADDDIC            213
  1289. #define IDD_LIST_PREVIEW    214
  1290. #define IDD_SELECT            215
  1291. #define IDD_REFERTEXTFILE    216
  1292.  
  1293. #define IDTIMER_COMPLETE    (WM_TIMER_TXUSER)
  1294.  
  1295. // 設定
  1296. static BOOL _fSearchText;
  1297. static BOOL _fSearchHistSearch;
  1298. static BOOL _fSearchTextPara;
  1299. static BOOL _fCompleteWring;
  1300. static mchar p_szCompleteFile[CCHPATHNAME];
  1301.  
  1302. static void uicompleteConfigGetset(BOOL fSet)
  1303. {
  1304. //WZ4.00Ab 990117 new
  1305.     TX* text = txMbxOpenWzapp("uiComplete");
  1306.     if (text) {
  1307.         txMsghdrGetsetIntInit(text,"fText:",TRUE,&_fSearchText,fSet);
  1308.         txMsghdrGetsetIntInit(text,"fHist:",TRUE,&_fSearchHistSearch,fSet);
  1309.         txMsghdrGetsetInt(text,"fPara:",&_fSearchTextPara,fSet);
  1310.         txMsghdrGetsetIntInit(text,"fWring:",TRUE,&_fCompleteWring,fSet);
  1311.         txMsghdrGetsetString(text,"file:",p_szCompleteFile,CCHPATHNAME,fSet);
  1312.     }
  1313.     txMbxClose(text);
  1314. }
  1315.  
  1316. static void uicompleteConfigLoad(void)
  1317. {
  1318.     uicompleteConfigGetset(FALSE);
  1319. }
  1320.  
  1321. static void uicompleteConfigSave(void)
  1322. {
  1323.     uicompleteConfigGetset(TRUE);
  1324. }
  1325.  
  1326. typedef struct {
  1327.     HSTRBLK sb;
  1328.     BOOL fEdit;
  1329.     BOOL fCanceled;//3.00B1 970522 
  1330.     TX* text;
  1331.     NPARA npara;
  1332.     mchar szTarget[CCHWORD];
  1333. //
  1334.     HWND hwnd;
  1335.     TX* textPreview;
  1336.     LIST* list;
  1337.     BOOL fFlushListing;
  1338.     BOOL fDialogWriting;    //WZ4.00Bl 990915 
  1339. } COMPLETECONTEXT;
  1340.  
  1341. typedef struct {
  1342.     LISTITEM listitem;    // 必ず先頭にこれを入れる
  1343. // mydata
  1344.     int npara;
  1345.     mchar szcontent[CCHWORD];
  1346.     BOOL fReferFile;
  1347. } IC_ITEM;
  1348.  
  1349. static void myPostMessage(HWND hwnd,int message,WPARAM wParam,LPARAM lParam)
  1350. {
  1351.     MSG msg;
  1352.     if (PeekMessage(&msg,hwnd,message,message,PM_NOREMOVE)) {
  1353.         // 既にポストされている場合は、ポストしない
  1354.     } else {
  1355.         PostMessage(hwnd,message,wParam,lParam);
  1356.     }
  1357. }
  1358.  
  1359. static void FlushSelect(TX* text,BOOL fLeft)
  1360. {
  1361.     if (txFlushSelectNow(text)) {
  1362.         if (text->clipendnow <= text->cliptopnow) {
  1363.             if (fLeft) return;
  1364.             txSelectJump(text);
  1365.         }
  1366.         if (!fLeft) return;
  1367.         txSelectJump(text);
  1368.     }
  1369. }
  1370.  
  1371. static BOOL mylistFind(LIST* list,mchar* sz)
  1372. {
  1373.     int i;
  1374.     for (i = 0;i < list->n;i++) {
  1375.         IC_ITEM* item = listRead(list,i);
  1376.         if (!strcmp(item->szcontent,sz)) return TRUE;
  1377.     }
  1378.     return FALSE;
  1379. }
  1380.  
  1381. static void mylistAdd(LIST* list,mchar* sz,NPARA npara,BOOL fReferFile)
  1382. {
  1383.     IC_ITEM* item = zmalloc(sizeof(IC_ITEM));
  1384.     sstrcpy(item->szcontent,sz);
  1385.     item->npara = npara;
  1386.     item->fReferFile = fReferFile;
  1387.     listAdd(list,item);listDispAll(list);
  1388. }
  1389.  
  1390. static int SearchTextDic(COMPLETECONTEXT* context,TX* text,SEARCHMODE mode,BOOL fReferFile)
  1391. {
  1392.     if (txSearchEx(text,context->szTarget,SEARCH_NOSENSECASE|mode)) {
  1393.         mchar szPara[CCHPATHNAME];
  1394.         if (_fSearchTextPara) {
  1395.             mchar*p = szPara;
  1396.             txGetParaEx(text,szPara,cchof(szPara));
  1397.             // 行頭のスペースを削除
  1398.             while(1) {
  1399.                 if (isspace(*p)) {
  1400.                     p++;
  1401.                 } else if (*p == '/' && p[1] == '/') {
  1402.                     p += 2;
  1403.                 } else {
  1404.                     break;
  1405.                 }
  1406.             }
  1407.             mylistAdd(context->list,p,text->npara,fReferFile);
  1408.             return TRUE;
  1409.         } else {
  1410.             int lch = strlen(context->szTarget);
  1411.             IFILE adr = txGetAddress(text);
  1412.             txJumpWordTopMi(text);
  1413.             txSelectEx(text,CLIP_CHAR);
  1414.             txJumpWordEndMi(text);
  1415.             txGetWordEx(text,szPara,cchof(szPara));
  1416.             txJumpAddress(text,adr);
  1417.             if (_fCompleteWring && strnicmp(szPara,context->szTarget,lch)) {
  1418.                 // 絞り込みの場合で、単語頭が一致しない場合
  1419.             } else {
  1420.                 if (!mylistFind(context->list,szPara)) {
  1421.                     mylistAdd(context->list,szPara,text->npara,fReferFile);
  1422.                     return TRUE;
  1423.                 }
  1424.             }
  1425.         }
  1426.         return FALSE;
  1427.     }
  1428.     return -1;
  1429. }
  1430.  
  1431.  
  1432. static void GetTextDic(COMPLETECONTEXT* context,TX* text,BOOL fReferFile)
  1433. {
  1434.     txFlushSelectNow(text);
  1435.     {
  1436.         BOOL fSelect = text->fClip;
  1437.         IFILE cliptopnow = text->cliptopnow;
  1438.         IFILE adr = txGetAddress(text);
  1439.         int n = 0;
  1440.         int ly = text->ly;
  1441.         txSetUndisp(text);
  1442.         text->fUndispSelect++;    //WZ4.00Aa 990108 
  1443.         if (!_fSearchTextPara) {
  1444.             // 単語取得の場合は、2つ、カーソル位置の近くで補完をする
  1445.             SearchTextDic(context,text,SEARCH_PREV,fReferFile);
  1446.             SearchTextDic(context,text,SEARCH_PREV,fReferFile);
  1447.             SearchTextDic(context,text,SEARCH_PREV,fReferFile);
  1448.         }
  1449.         txJumpFileTop(text);
  1450.         {
  1451.             while(1) {
  1452.                 int ret = SearchTextDic(context,text,0,fReferFile);
  1453.                 if (GetAsyncKeyState(VK_ESCAPE) < 0) {//3.00B1 970522 入力支援:検索に時間がかかるときは{Esc}で中止できるようにした
  1454.                     SetDlgItemText(context->hwnd,IDD_GUIDE,"(中止しました)");
  1455.                     context->fCanceled = TRUE;
  1456.                     break;
  1457.                 }
  1458.                 if (ret == TRUE) {
  1459.                     n++;
  1460.                     if (n > 20) {
  1461.                         //あまり多いときは途中でやめないと遅い
  1462.                         SetDlgItemText(context->hwnd,IDD_GUIDE,"(マッチ数が多いので省略しました)");
  1463.                         break;
  1464.                     }
  1465.                 } else if (ret == -1) {
  1466.                     break;
  1467.                 }
  1468.             }
  1469.         }
  1470.         text->fUndispSelect--;    //WZ4.00Aa 990108 
  1471.         if (fSelect) {
  1472.             txJumpAddress(text,cliptopnow);
  1473.             txSetLy(text,ly);
  1474.             txSelectEx(text,CLIP_CHAR);
  1475.             text->fClipMouse = TRUE;
  1476.         } else {
  1477.             txSelectQuit(text);
  1478.             txJumpAddress(text,adr);
  1479.             txSetLy(text,ly);
  1480.         }
  1481.         txSetDispEx(text);
  1482.     }
  1483. }
  1484.  
  1485. static void makeCompleteFormText(LIST* list,TX* text,mchar* szTarget)
  1486. {
  1487.     SEARCHMODE mode = _fCompleteWring ? SEARCH_PARATOP : 0;
  1488.     while(1) {
  1489.         if (txSearchEx(text,szTarget,mode|SEARCH_NOSENSECASE|SEARCH_CUR)) {
  1490.             mchar sz[CCHWORD];
  1491.             txGetParaEx(text,sz,CCHWORD);
  1492.             if (!mylistFind(list,sz)) {
  1493.                 mylistAdd(list,sz,0,FALSE);
  1494.             }
  1495.             txNextPara(text);
  1496.         } else {
  1497.             break;
  1498.         }
  1499.     }
  1500. }
  1501.  
  1502. static void makeCompleteFormStrblk(LIST* list,HSTRBLK sb,mchar* szTarget)
  1503. {
  1504.     int n = sbGetCount(sb);
  1505.     sbSetSenseCase(sb,FALSE);
  1506.     for (;n--;) {
  1507.         mchar* sz = sbRead(sb,n);
  1508.         mchar* p;
  1509.         if (p = stristr(sz,szTarget)) {
  1510.             if (_fCompleteWring && p != sz) {
  1511.             } else {
  1512.                 if (!mylistFind(list,sz)) {
  1513.                     mylistAdd(list,sz,0,FALSE);
  1514.                 }
  1515.             }
  1516.         }
  1517.     }
  1518. }
  1519.  
  1520. static void completeOnSelchange(COMPLETECONTEXT* context)
  1521. {
  1522.     LIST* list = context->list;
  1523.     IC_ITEM* item = listReadCur(list);
  1524.     TX* text = context->textPreview;
  1525.     if (item && text) {
  1526.         txSetUndisp(text);
  1527.         txDeleteText(text);
  1528.         if (_fSearchTextPara && item->npara) {
  1529.             TX* textSrc = context->text;
  1530.             mchar szpara[CCHPATHNAME];
  1531.             if (item->fReferFile) {
  1532.                 textSrc = textopen(p_szCompleteFile);
  1533.             }
  1534.             txSetUndispEx(textSrc);
  1535.             txJumpNpara(textSrc,item->npara);
  1536.             txGetParaEx(textSrc,szpara,cchof(szpara));
  1537.             txSetDispEx(textSrc);
  1538.             if (item->fReferFile) textclose(textSrc);
  1539.             //
  1540.             txInsert(text,szpara);
  1541.             txJumpFileTop(text);
  1542.             txSearchEx(text,context->szTarget,SEARCH_CUR|SEARCH_SELECT|SEARCH_NOSENSECASE);
  1543.             txJumpWordTop(text);
  1544.             txSelectEx(text,CLIP_CHAR);
  1545.             txJumpWordEnd(text);
  1546.         } else {
  1547.             txInsert(text,item->szcontent);
  1548.         }
  1549.         txSetDisp(text);
  1550.         EnableWindow(GetDlgItem(context->hwnd,IDD_JUMP),(item->npara && !item->fReferFile));
  1551.     }
  1552. }
  1553.  
  1554. static void completeFlush(HWND hwnd,int idd)
  1555. {
  1556.     HDIALOG hd = dialogFromHwnd(hwnd);
  1557.     COMPLETECONTEXT* context = dialogGetCustdata(hd);
  1558.     context->fFlushListing++;
  1559.     listDelAll(context->list);listDispAll(context->list);
  1560.     {// タブ等は除く
  1561.         mchar* dst = context->szTarget;
  1562.         mchar* src = context->szTarget;
  1563.         while(1) {
  1564.             mchar c = *src++;
  1565.             if (c == 0) break;
  1566.             if (tbiskanji(c) && *src) {
  1567.                 *dst++ = c;
  1568.                 *dst++ = *src++;
  1569.             } else if (c > ' ') {
  1570.                 *dst++ = c;
  1571.             }
  1572.         }
  1573.         *dst = 0;
  1574.     }
  1575.     if (context->szTarget[0]) {
  1576.         SetDlgItemText(hwnd,IDD_GUIDE,"");
  1577.         if (!_fSearchTextPara) {
  1578.             // [1]補完ヒストリから検索
  1579.             makeCompleteFormStrblk(context->list,context->sb,context->szTarget);
  1580.             // [2]キーワードから検索    //WZ4.00Aa 990108 renew
  1581.             if (context->text->keyword) {
  1582.                 TX* text = txGetKeywordText(context->text);
  1583.                 txJumpFileTop(text);
  1584.                 makeCompleteFormText(context->list,text,context->szTarget);
  1585.                 txJumpFileTop(text);
  1586.             }
  1587.             // [3]complete.dicから検索
  1588.             {
  1589.                 mchar szfilename[CCHPATHNAME];
  1590.                 TX* text = textopen(pathFullConfig(szfilename,"complete.dic"));
  1591.                 makeCompleteFormText(context->list,text,context->szTarget);
  1592.                 textclose(text);
  1593.             }
  1594.             // [4]検索ヒストリから検索
  1595.             if (_fSearchHistSearch) {
  1596.                 makeCompleteFormStrblk(context->list,sbFromHist(HIST_SEARCH),context->szTarget);
  1597.             }
  1598.         }
  1599.         // [5]テキストから検索
  1600.         if (_fSearchText) {
  1601.             GetTextDic(context,context->text,FALSE);
  1602.         }
  1603.         if (p_szCompleteFile[0]) {//3.00B1 970522 
  1604.             TX* text = textopen(p_szCompleteFile);
  1605.             GetTextDic(context,text,TRUE);
  1606.             textclose(text);
  1607.         }
  1608.     }
  1609.     context->fFlushListing--;
  1610.     //
  1611.     if (context->list) {
  1612.         LIST* list = context->list;
  1613.         completeOnSelchange(context);
  1614.         if (list->n && idd != IDD_TARGET) SetFocus(list->hwnd);
  1615.     }
  1616. }
  1617.  
  1618. BOOL CALLBACK dlgprocComplete(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  1619. {
  1620. //WZ4.00Bl 990915 補完対象文字を変更しなかったときは入力支援後削除する機能が働いていなかったので修正。
  1621.     HDIALOG hd = dialogFromHwnd(hwnd);
  1622.     COMPLETECONTEXT* context = dialogGetCustdata(hd);
  1623.     switch(message) {
  1624.         case WM_INITDIALOG: {
  1625.             context->hwnd = hwnd;
  1626.             context->list = listFromHwnd(GetDlgItem(hwnd,IDD_LIST));
  1627.             {
  1628.                 LIST* list = context->list;
  1629.                 IC_ITEM item;
  1630.                 SUBLISTITEMATR* atr = &list->tSubitem[0];
  1631.                 atr->type = LISTITEM_INT;
  1632.                 atr->offset = (LPBYTE)&item.npara - (LPBYTE)&item;
  1633.                 atr->cx = dtcx(DTCX * 6);
  1634.                     atr++;
  1635.                 atr->type = LISTITEM_SZ;
  1636.                 atr->offset = (LPBYTE)item.szcontent - (LPBYTE)&item;
  1637.                 atr->cx = -1;
  1638.                     atr++;
  1639.                 list->nSubitem = atr - &list->tSubitem[0];
  1640.             }
  1641.             //
  1642.             myPostMessage(hwnd,WM_TXUSER,0,0);
  1643.             // フォーカス順序をリストボックスをテキストボックスの直後にする
  1644.             SetWindowPos(GetDlgItem(hwnd,IDD_LISTCAPTION),GetDlgItem(hwnd,IDD_TARGET),0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
  1645.             SetWindowPos(GetDlgItem(hwnd,IDD_LIST),GetDlgItem(hwnd,IDD_LISTCAPTION),0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
  1646.             //
  1647.             context->textPreview = WzBox_GetTx(GetDlgItem(hwnd,IDD_LIST_PREVIEW));
  1648.             {
  1649.                 TX* text = context->textPreview;
  1650.                 if (text) {
  1651.                     text->fScrollBarH = TRUE;
  1652.                     text->fScrollBarV = TRUE;
  1653.                     text->fDispLine = FALSE;
  1654.                     text->dlgcode = DLGC_WANTARROWS;
  1655.                     text->fNoCursor = TRUE;
  1656.                     txFlush(text);
  1657.                 }
  1658.             }
  1659.             //WZ4.00Bl 990915 
  1660.             context->fDialogWriting++;
  1661.             dialogWriteItem(hd,-1);
  1662.             context->fDialogWriting--;
  1663.             SetTimer(hwnd,IDTIMER_COMPLETE,500,NULL);
  1664.             //WZ4.00Bl 990915 入力支援で「補完対象」に文字を追加できるように、選択しないようにした。ユーザ要望。
  1665.             {
  1666.                 HWND hctrl = GetDlgItem(hwnd,IDD_TARGET);
  1667.                 int lch = Edit_GetTextLength(hctrl);
  1668.                 Edit_SetSel(hctrl,lch,lch);
  1669.             }
  1670.             return INITDIALOG_SKIP_FALSE;
  1671.         }
  1672.         case WM_NOTIFY: {
  1673.             LISTNOTIFY* notify = lParam;
  1674.             LIST* list = context->list;
  1675.             if (list && notify->hdr.hwndFrom == list->hwnd) {
  1676.                 if (notify->hdr.code == LISTN_SELCHANGE && !context->fFlushListing) {
  1677.                     completeOnSelchange(context);
  1678.                 } else if (notify->hdr.code == LISTN_FORWARD && notify->message == WM_LBUTTONDBLCLK) {
  1679.                     PostMessage(hwnd,WM_COMMAND,IDOK,0);
  1680.                     return FALSE;
  1681.                 }
  1682.             }
  1683.             break;
  1684.         }
  1685.         case WM_COMMAND: {
  1686.             int id = GET_WM_COMMAND_ID(wParam,lParam);
  1687.             int notify = GET_WM_COMMAND_CMD(wParam,lParam);
  1688.             switch(id) {
  1689.                 case IDCANCEL: {//3.00B1 970522 
  1690.                     if (context->fCanceled) {
  1691.                         context->fCanceled = FALSE;
  1692.                         return TRUE;
  1693.                     }
  1694.                     break;
  1695.                 }
  1696.                 case IDOK: {
  1697.                     LIST* list = context->list;
  1698.                     IC_ITEM* item = listReadCur(list);
  1699.                     if (item) {
  1700.                         TX* text = context->text;
  1701.                         if (!context->fEdit) {
  1702.                             // 補完文字列が変化してなければ...
  1703.                             txSelectDelete(text);
  1704.                         }
  1705.                         if (_fSearchTextPara) {
  1706.                             TX* textSrc = context->textPreview;
  1707.                             if (textSrc) {
  1708.                                 if (textSrc->fClip) {
  1709.                                     txPrivatePush(textSrc);
  1710.                                     txPrivatePaste(text);
  1711.                                     txPrivateDeleteTop(textSrc);
  1712.                                 } else {
  1713.                                     txInsertText(text,textSrc);
  1714.                                 }
  1715.                             }
  1716.                         } else {
  1717.                             txInsert(text,item->szcontent);
  1718.                             sbAddHist(context->sb,item->szcontent);    // 補完ヒストリに追加
  1719.                         }
  1720.                     }
  1721.                     break;
  1722.                 }
  1723.                 case IDD_TARGET: {
  1724.                     if (notify == EN_UPDATE && !context->fDialogWriting) {
  1725.                         context->fEdit = TRUE;
  1726.                         SetTimer(hwnd,IDTIMER_COMPLETE,500,NULL);
  1727.                     }
  1728.                     break;
  1729.                 }
  1730.                 case IDD_TOP_PREV: {
  1731.                     TX* text = context->textPreview;
  1732.                     if (text) {
  1733.                         FlushSelect(text,TRUE);
  1734.                         txLeftWordMi(text);
  1735.                     }
  1736.                     break;
  1737.                 }
  1738.                 case IDD_TOP_NEXT: {
  1739.                     TX* text = context->textPreview;
  1740.                     if (text) {
  1741.                         FlushSelect(text,TRUE);
  1742.                         txRightWordMi(text);
  1743.                     }
  1744.                     break;
  1745.                 }
  1746.                 case IDD_END_PREV: {
  1747.                     TX* text = context->textPreview;
  1748.                     if (text) {
  1749.                         FlushSelect(text,FALSE);
  1750.                         txLeftWordMi(text);
  1751.                     }
  1752.                     break;
  1753.                 }
  1754.                 case IDD_END_NEXT: {
  1755.                     TX* text = context->textPreview;
  1756.                     if (text) {
  1757.                         FlushSelect(text,FALSE);
  1758.                         txRightWordMi(text);
  1759.                     }
  1760.                     break;
  1761.                 }
  1762.                 case IDD_ALL: {//3.00B1 970522 
  1763.                     TX* text = context->textPreview;
  1764.                     if (text) txSelectAll(text);
  1765.                     break;
  1766.                 }
  1767.                 case IDD_REFERTEXTFILE: {//3.00B1 970522 
  1768.                     if (notify == EN_CHANGE) {
  1769.                         myPostMessage(hwnd,WM_TXUSER,id,0);
  1770.                     }
  1771.                     break;
  1772.                 }
  1773.                 case IDD_WRING:
  1774.                 case IDD_TEXT:
  1775.                 case IDD_TEXTPARA:
  1776.                 case IDD_TEXTPARA+1:
  1777.                 case IDD_HISTSEARCH: {
  1778.                     myPostMessage(hwnd,WM_TXUSER,id,0);
  1779.                     break;
  1780.                 }
  1781.                 case IDD_JUMP: {
  1782.                     LIST* list = context->list;
  1783.                     IC_ITEM* item = listReadCur(list);
  1784.                     if (item && item->npara && !item->fReferFile) {
  1785.                         TX* text = context->text;
  1786.                         txSetUndisp(text);
  1787.                         txSelectQuit(text);
  1788.                         txJumpNpara(text,item->npara);
  1789.                         txSetDisp(text);
  1790.                         return FALSE;
  1791.                     }
  1792.                     return TRUE;
  1793.                 }
  1794.                 case IDD_ADDDIC: {
  1795.                     LIST* list = context->list;
  1796.                     IC_ITEM* item = listReadCur(list);
  1797.                     if (item) {
  1798.                         uiCompleteAddDic(item->szcontent);
  1799.                     } else {
  1800.                         mchar buff[CCHWORD];
  1801.                         GetDlgItemText(hwnd,IDD_TARGET,buff,cchof(buff));
  1802.                         uiCompleteAddDic(buff);
  1803.                     }
  1804.                     return TRUE;
  1805.                 }
  1806.             }
  1807.             return FALSE;
  1808.         }
  1809.         case WM_DESTROY: {
  1810.             KillTimer(hwnd,IDTIMER_COMPLETE);
  1811.             break;
  1812.         }
  1813.         case WM_TIMER: {
  1814.             KillTimer(hwnd,IDTIMER_COMPLETE);
  1815.             myPostMessage(hwnd,WM_TXUSER,IDD_TARGET,0);
  1816.             break;
  1817.         }
  1818.         case WM_TXUSER: {
  1819.             // WM_COMMANDが残っている場合は処理しない。高速化
  1820.             {
  1821.                 MSG msg;
  1822.                 if (PeekMessage(&msg,hwnd,WM_COMMAND,WM_COMMAND,PM_NOREMOVE)) {
  1823.                     myPostMessage(hwnd,WM_TXUSER,wParam,0);
  1824.                     return FALSE;
  1825.                 }
  1826.             }
  1827.             //
  1828.             dialogRead(hd);
  1829.             EnableWindow(GetDlgItem(hwnd,IDD_TEXTPARA),(_fSearchText||p_szCompleteFile[0]));
  1830.             EnableWindow(GetDlgItem(hwnd,IDD_HISTSEARCH),!_fSearchTextPara);
  1831.             EnableWindow(GetDlgItem(hwnd,IDD_WRING),!_fSearchTextPara);
  1832.             EnableWindow(GetDlgItem(hwnd,IDD_TOP_PREV),_fSearchTextPara);
  1833.             EnableWindow(GetDlgItem(hwnd,IDD_TOP_NEXT),_fSearchTextPara);
  1834.             EnableWindow(GetDlgItem(hwnd,IDD_END_PREV),_fSearchTextPara);
  1835.             EnableWindow(GetDlgItem(hwnd,IDD_END_NEXT),_fSearchTextPara);
  1836.             //
  1837.             switch(wParam) {
  1838.                 case IDD_LIST: break;
  1839.                 default: {
  1840.                     completeFlush(hwnd,wParam);
  1841.                     break;
  1842.                 }
  1843.             }
  1844.             break;
  1845.         }
  1846.     }
  1847.     return FALSE;
  1848. }
  1849.  
  1850. BOOL txIDM_UICOMPLETE(TX* text)
  1851. {
  1852. // 入力支援
  1853. //{#MS} {F4}
  1854.     HDIALOG hd = dialog("入力支援");
  1855.     static mchar _szCompleteFileHist[] = "completeRefer";
  1856.     HSTRBLK sbFile = historyOpen(_szCompleteFileHist,2048);
  1857.     HSTRBLK sb = historyOpen(_szCompleteHist,SIZE_COMPLETEHIST);
  1858.     COMPLETECONTEXT context;
  1859.     DTRECT rCmd;
  1860.     DTRECT r;
  1861.     int lxg = 16;
  1862.     int lx = 20;
  1863.     //
  1864.     uicompleteConfigLoad();
  1865.     //
  1866.     structClear(context);
  1867.     context.text = text;
  1868.     context.sb = sb;
  1869.     if (text->fClip) {
  1870.         txGetWordEx(text,context.szTarget,CCHWORD);
  1871.         text->fClipMouse = TRUE;
  1872.     } else {
  1873.         if (!txIsCurParaTop(text)) {
  1874.             txSelectEx(text,CLIP_CHAR);
  1875.             text->fClipMouse = TRUE;
  1876.             txLeftWordMi(text);
  1877.             txGetWordEx(text,context.szTarget,CCHWORD);
  1878.         }
  1879.     }
  1880.     if (context.szTarget[0] <= ' ') {
  1881.         // 空白や改行なら、補完対象文字列はなしとする
  1882.         context.szTarget[0] = 0;
  1883.         context.fEdit = TRUE;
  1884.         txSelectQuit(text);
  1885.     }
  1886.     //
  1887.     dialogSetDlgproc(hd,dlgprocComplete);
  1888.     dialogSetCustdata(hd,&context);
  1889.     dialogControlID(hd,IDD_TARGET);
  1890.     dialogString(hd,"補完対象(&S):",lxg,context.szTarget,CCHWORD,lx);
  1891.     dialogControlID(hd,IDD_LISTCAPTION);
  1892.     dialogCaptionDynamic(hd,"補完候補(&I):",20);
  1893.     //
  1894.     dialogGetPos(hd,&r);
  1895.     r.cx = DTCX * 60;
  1896.     r.cy = DTCY * 9;
  1897. //    listRegister();    //WZ4.00Ca 991128 
  1898.     __dialogAddItem(hd,szclassList,NULL,IDD_LIST,&r,WS_GROUP|WS_TABSTOP|WS_BORDER|WS_CHILD|WS_VISIBLE|LIST_WS_DEFAULT);
  1899.     dialogSetPosY(hd,r.y + r.cy);
  1900.     //
  1901.     dialogControlID(hd,IDD_GUIDE);
  1902.     dialogCaptionDynamic(hd,NULL,40);
  1903.     dialogLFV(hd);
  1904.     dialogGetPos(hd,&rCmd);
  1905.     dialogLF(hd);
  1906.     dialogGetPos(hd,&r);
  1907.     r.cx = DTCX * 60;
  1908.     r.cy = DTCY * 4;
  1909.     __dialogAddItem(hd,TXWS_SZCLASSA,"",IDD_LIST_PREVIEW,&r,TXWS_TEXT|TXWS_OPENTEXT|WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL|WS_HSCROLL);
  1910.     r.y += r.cy + DTCYINT;
  1911.     dialogSetPos(hd,&r);
  1912.     dialogSetH(hd);
  1913.     dialogControlID(hd,IDD_TOP_PREV);
  1914.     dialogPushbutton(hd,"&<",10);
  1915.     dialogControlID(hd,IDD_TOP_NEXT);
  1916.     dialogPushbutton(hd,"> &K",10);
  1917.     //3.00B1 970522 
  1918.     dialogIndent(hd,3);
  1919.     dialogControlID(hd,IDD_ALL);
  1920.     dialogPushbutton(hd,"全て(&A)",10);
  1921.     //
  1922.     dialogSetPosLX(hd,60 - 21);
  1923.     dialogControlID(hd,IDD_END_PREV);
  1924.     dialogPushbutton(hd,"< &L",10);
  1925.     dialogControlID(hd,IDD_END_NEXT);
  1926.     dialogPushbutton(hd,"&>",10);
  1927.     dialogSetV(hd);
  1928.     dialogLF(hd);
  1929.     dialogSpaceV(hd);
  1930.     dialogControlHist(hd,sbFile);
  1931.     dialogControlRefer(hd,"");
  1932.     dialogControlHelp(hd,511);
  1933.     dialogControlID(hd,IDD_REFERTEXTFILE);
  1934.     dialogString(hd,"参照ファイル(&F):",16,p_szCompleteFile,CCHPATHNAME,33);
  1935.     //
  1936.     dialogLFV(hd);
  1937.     dialogSetPos(hd,&rCmd);dialogIndent(hd,1);
  1938.     dialogOK(hd,21);
  1939.     dialogCancel(hd,21);
  1940.     dialogSpaceV(hd);
  1941.     //
  1942.     dialogControlID(hd,IDD_ADDDIC);
  1943.     dialogCmd(hd,"辞書に追加(&D)...",21);
  1944.     dialogControlID(hd,IDD_JUMP);
  1945.     dialogCmd(hd,"ジャンプ(&J)",21);
  1946.     dialogSpaceV(hd);
  1947.     dialogControlID(hd,IDD_TEXT);
  1948.     dialogCheck(hd,"テキストも検索(&T)",&_fSearchText);
  1949.     //2.98 970309 入力支援:「段落の取得」復活
  1950.     // 常用はしないけど、さっき入力したところをもう一度という無計画なとこが、
  1951.     // 元の入力支援のいいとこだったと思うんです(kitamakuraさん)。
  1952.         dialogIndent(hd,2);
  1953.         dialogControlRadioV(hd);
  1954.         dialogControlID(hd,IDD_TEXTPARA);
  1955.         dialogCheck(hd,"段落取得(&P)",&_fSearchTextPara);
  1956.         dialogIndent(hd,-2);
  1957.     dialogControlID(hd,IDD_HISTSEARCH);
  1958.     dialogCheck(hd,"検索ヒストリも検索(&H)",&_fSearchHistSearch);
  1959.     dialogControlID(hd,IDD_WRING);
  1960.     dialogCheck(hd,"絞り込み(&R)",&_fCompleteWring);
  1961.     //
  1962.     dialogOpen(hd);
  1963.     //
  1964.     historyClose(_szCompleteFileHist,sbFile);
  1965.     historyClose(_szCompleteHist,sb);
  1966.     uicompleteConfigSave();
  1967.     return TRUE;
  1968. }
  1969.  
  1970. #endif    // !WINDOWSCE
  1971.  
  1972. //##ソート
  1973.  
  1974. enum {
  1975.     IDD_SORTMODE=100,
  1976.     IDD_SORTCLM=110,
  1977. };
  1978.  
  1979. static BYTE _sortmode;
  1980. static BYTE _sortclm = 1;
  1981. static BBOOL _fSortPrev;
  1982. static BBOOL _fSortNoSenseCase;    //WZ4.00Bn 991006 
  1983.  
  1984. BOOL CALLBACK dlgprocSort(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  1985. {
  1986.     HDIALOG hd = dialogFromHwnd(hwnd);
  1987.     switch(message) {
  1988.         case WM_INITDIALOG: {
  1989.             PostMessage(hwnd,WM_TXUSER,0,0);
  1990.             break;
  1991.         }
  1992.         case WM_COMMAND: {
  1993.             int id = GET_WM_COMMAND_ID(wParam,lParam);
  1994.             int notify = GET_WM_COMMAND_CMD(wParam,lParam);
  1995.             switch(id) {
  1996.                 case IDD_SORTMODE:
  1997.                 case IDD_SORTMODE+1:
  1998.                 case IDD_SORTMODE+2: {
  1999.                     PostMessage(hwnd,WM_TXUSER,0,0);
  2000.                     break;
  2001.                 }
  2002.             }
  2003.             break;
  2004.         }
  2005.         case WM_TXUSER: {
  2006.             dialogRead(hd);
  2007.             EnableDlgItem(hwnd,IDD_SORTCLM,(_sortmode != 0));
  2008.             break;
  2009.         }
  2010.     }
  2011.     return FALSE;
  2012. }
  2013.  
  2014. BOOL txIDM_UISORT(TX* text)
  2015. {
  2016.     HDIALOG hd = dialog("ソート");
  2017.     BOOL fArea = (text->fClip && !txIsClipInPara(text));
  2018.     //
  2019.     dialogSetDlgproc(hd,dlgprocSort);
  2020.     //
  2021.     dialogControlRadioV(hd);
  2022.     dialogControlID(hd,IDD_SORTMODE);
  2023.     dialogChoiceRadioB(hd,&_sortmode,"行でソート(&L)","タブ区切り(&T)"/*,"カンマ区切り(&C)"*/,NULL);
  2024.     if (!_pspc) dialogLFV(hd);
  2025. //    dialogSetPosY(hd,dialogGetPosY(hd) + DTCY);
  2026.     dialogControlID(hd,IDD_SORTCLM);
  2027.     dialogControlGuide(hd,"番目の項目でソート",20);
  2028.     dialogControlUpdown(hd,1,20);    //WZ4.00Ea 001127 
  2029.     dialogIntegerB(hd,NULL,0,&_sortclm,6);
  2030.         dialogLF(hd);
  2031.         dialogSpaceV(hd);dialogSpaceV(hd);
  2032.     dialogCheckB(hd,"逆順(&P)",&_fSortPrev);
  2033.     dialogControlReverseBool(hd);
  2034.     dialogCheckB(hd,"大文字と小文字を区別(&C)",&_fSortNoSenseCase);    //WZ4.00Bn 991006 IDM_UISORTに「大文字と小文字を区別」するかどうかのオプションを追加。
  2035.     dialogControlEnable(hd,fArea);
  2036.     dialogCheck(hd,"範囲内をソート(&B)",&fArea);
  2037.     //
  2038.     if (dialogOpen(hd)) {
  2039.         SORTARG arg;
  2040.         structClear(arg);
  2041.         arg.sizeStruct = sizeof(arg);
  2042.         arg.fBack = _fSortPrev;
  2043.         arg.fNoSenseCase = _fSortNoSenseCase;
  2044.         if (_sortmode) {
  2045.             arg.iItem = (_sortclm > 0) ? _sortclm - 1 : 0;
  2046.             arg.fCsv = 1;
  2047.         }
  2048.         txSetUndisp(text);
  2049.         {
  2050.             int ly0 = text->ly;
  2051.             if (fArea) {
  2052.                 IFILE adrTop = txGetAddressSelectTop(text);
  2053.                 IFILE adrEnd = txGetAddressSelectEnd(text);
  2054.                 int lineEnd;
  2055.                 if (!txSelectGetPrev(text)) ly0 = text->lyClip;
  2056.                 txSelectQuit(text);
  2057.                 txJumpAddress(text,adrEnd);arg.lineEnd = lineEnd = text->npara;
  2058.                 if (txIsCurParaTop(text) && arg.lineEnd >= 2) arg.lineEnd--;    //WZ4.00Bn 991006 行単位で範囲選択し、範囲内のソートをすると1行余計にソートされたのを修正。
  2059.                 txJumpAddress(text,adrTop);arg.lineTop = text->npara;
  2060.                 txSort(text,&arg);
  2061.                 txJumpNpara(text,lineEnd);txSelectEx(text,CLIP_MOUSE);
  2062.                 txJumpNpara(text,arg.lineTop);
  2063.             } else {
  2064.                 NPARA npara = text->npara;
  2065.                 arg.nparaCur = npara;
  2066.                 txSort(text,&arg);
  2067.                 txJumpNpara(text,arg.nparaCur);
  2068.             }
  2069.             txSetLy(text,ly0);
  2070.         }
  2071.         txSetDisp(text);
  2072.     }
  2073.     return TRUE;
  2074. }
  2075.  
  2076. //##IME
  2077.  
  2078. #if !__TXC__
  2079. void TXAPI txSwitchIme(TX* text)
  2080. {
  2081. //WCE0.91 970908 IMEをON/OFFするコマンドを新設
  2082.     wndImeSetOpen(text->hwndtext,!wndImeGetOpen(text->hwndtext));
  2083. }
  2084. #endif
  2085.  
  2086. #if WINDOWSCE
  2087. //WCE1.01 980320 for 単語登録
  2088. #if !WINDOWSCE211    //WZ4.00Be 990405 
  2089. typedef struct {
  2090.     LPWSTR  lpReading;
  2091.     LPWSTR  lpWord;
  2092. } REGISTERWORD;
  2093. #endif
  2094. BOOL WINAPI ImmConfigureIMEW(LPVOID,HWND,DWORD,LPVOID);
  2095. // dialog mode of ImmConfigureIME
  2096. #define IME_CONFIG_GENERAL              1
  2097. #define IME_CONFIG_REGISTERWORD         2
  2098. #define IME_CONFIG_SELECTDICTIONARY     3
  2099. #endif
  2100.  
  2101. #if !__TXC__
  2102. BOOL _txIDM_UIIMEREGISTERWORD(TX* text,HWND hwndParent)
  2103. {
  2104. // 単語登録を行う。text=NULLも可能
  2105. #if UNIX
  2106.     return FALSE;
  2107. #else
  2108. #ifdef UNICODE
  2109.     if (_pspc) {
  2110.         information("PsPC/PocketPCでは利用できません");    //WZ4.00Ea 001126 
  2111.         return FALSE;
  2112.     } else {
  2113.         wchar wszbuff[CCHWORD] = {0};
  2114.         wchar wszReading[CCHWORD] = {0};
  2115.         REGISTERWORD regword;
  2116.         structClear(regword);
  2117.         if (text && txIsClipInPara(text)) {
  2118.             mchar szbuff[CCHWORD];
  2119.             txGetWordEx(text,szbuff,sizeof(szbuff));
  2120.             strtowstr(szbuff,-1,wszbuff,wcchof(wszbuff));
  2121.         }
  2122.         regword.lpReading = wszReading;
  2123.         regword.lpWord = wszbuff;
  2124.         ImmConfigureIMEW(NULL,hwndParent,IME_CONFIG_REGISTERWORD,®word);
  2125.         return TRUE;
  2126.     }
  2127. #else
  2128.     mchar szbuff[CCHWORD] = {0};
  2129.     mchar szReading[CCHWORD] = {0};
  2130.     REGISTERWORD regword;
  2131.     structClear(regword);
  2132.     if (text && txIsClipInPara(text)) {
  2133.         txGetWordEx(text,szbuff,sizeof(szbuff));
  2134.     }
  2135.     regword.lpReading = szReading;
  2136.     regword.lpWord = szbuff;
  2137.     ImmConfigureIME(GetKeyboardLayout(0),hwndParent,IME_CONFIG_REGISTERWORD,®word);
  2138.     return TRUE;
  2139. #endif
  2140. #endif
  2141. }
  2142. #endif // !__TXC__
  2143.  
  2144. #if !UNIX && !__TXC__
  2145. BOOL TXAPI txuiImeConvert(TX* text)
  2146. {
  2147. //WCE0.91 970908 「最近、IMEで確定した文字列の再変換」コマンドを新設
  2148. #if !WINDOWSCE
  2149.     if (text->fClip) {    //WZ3.90I 981028 IME98を使って再変換ができるようにした。
  2150.         TX* text2 = textopen(NULL);
  2151.         txInsertTextSelect(text2,text);
  2152.         txJumpFileTop(text2);
  2153.         {
  2154.             wchar* wsz = wstrdupLenA(text2->buff + text2->cur,txGetTextSize(text2));
  2155.             BSTR bstr = ime98GetPhonetic(wsz);
  2156.             if (bstr) {
  2157. //winformation((wchar*)bstr);
  2158.                 text->fClipMouse = TRUE;
  2159.                 wndImeSetOpen(text->hwndtext,TRUE);//WCE0.92 970919 IMEが閉じてるときダメだった
  2160.                 {
  2161.                     HIMC himc = ImmGetContext(text->hwndtext);
  2162.                     mchar* sz = strdupW(bstr);
  2163.                         ImmSetCompositionString(himc,SCS_SETSTR,sz,strlensize(sz),NULL,0);
  2164.                     free(sz);
  2165.                     ImmReleaseContext(text->hwndtext,himc);
  2166.                 }
  2167.                 SysFreeString(bstr);
  2168.             }
  2169.             free(wsz);
  2170.         }
  2171.         textclose(text2);
  2172.         return TRUE;
  2173.     }
  2174. #endif
  2175.     return (BOOL)dialogaSelHistEx("最近、IMEで確定した文字列の再変換",HIST_IME,SELHIST_IMECONVERT,text);
  2176. }
  2177. #endif
  2178.  
  2179. //##各種挿入
  2180.  
  2181. BOOL txIDM_UIINSERTCONTROL(TX* text)
  2182. {
  2183. // コントロールコードを挿入
  2184.     TX* textDst = text;
  2185.     BOOL ret = FALSE;
  2186.     {
  2187.         TX* text = textopen(NULL);
  2188.         if (text) {
  2189.             HDIALOG hd = dialog("制御文字の入力");
  2190.             int idList;
  2191.             {
  2192.                 int i;
  2193.                 for (i = 0;i <= 0x1B;i++) {
  2194.                     mchar szbuff[CCHWORD];
  2195.                     if (i == 0x0A) continue;//0x0Aは入力できない
  2196.                     sprintf(szbuff,"%c: Ctrl-%c",i+'@',i+'@');
  2197.                     txInsert(text,szbuff);
  2198.                     txInsertReturn(text);
  2199.                 }
  2200.                 txJumpFileTop(text);
  2201.             }
  2202.             idList = dialogList(hd,NULL,text,20,10);
  2203.             dialogSetNotifyAsOK(hd,idList,LBN_DBLCLK);//WCE0.95 970923 
  2204.             if (dialogOpen(hd)) {
  2205.                 int code = text->npara;
  2206.                 code--;
  2207.                 if (code >= 0x0A) code++;
  2208.                 txInsertChar(textDst,code);
  2209.                 ret = TRUE;
  2210.             }
  2211.         }
  2212.         textclose(text);
  2213.     }
  2214.     return ret;
  2215. }
  2216.  
  2217. static int strGetIch(mchar* sz,int offset)
  2218. {
  2219. // szのoffset目の文字が先頭から何文字目か返す
  2220.     mchar* pe = sz + offset;
  2221.     int ich = 0;
  2222.     while(sz < pe) {
  2223.         mchar c = *sz;
  2224.         if (tbiskanji(c)) {
  2225.             sz += tbkanjisize(sz);
  2226.             ich++;
  2227.         } else if (c) {
  2228.             sz++;
  2229.             ich++;
  2230.         } else break;
  2231.     }
  2232.     return ich;
  2233. }
  2234.  
  2235. static mchar* strGetIchStr(mchar* sz,int ich)
  2236. {
  2237. // szのich目の文字列のポインタを返す
  2238. // ichが大きすぎるときはszの\0へのポインタを返す
  2239.     while(ich) {
  2240.         mchar c = *sz;
  2241.         if (tbiskanji(c)) {
  2242.             sz += tbkanjisize(sz);
  2243.             ich--;
  2244.         } else if (c) {
  2245.             sz++;
  2246.             ich--;
  2247.         } else break;
  2248.     }
  2249.     return sz;
  2250. }
  2251.  
  2252. static UINT _txInsertBrace(TX* text,UINT index)
  2253. {
  2254. //WCE0.91 970909 半角括弧対応
  2255. //WZ3.90I 981023 “”と‘’を追加。
  2256.     static mchar szkakko[] = "()[]「」〔〕『』【】《》“”‘’()[]{}「」";
  2257.     TXCHAR ch = txGetChar(text);
  2258.     mchar *p = strchr(szkakko,ch);
  2259.     txSetUndispSilent(text);
  2260.     if (p) {
  2261.         index = strGetIch(szkakko,p - szkakko);
  2262.         if ((index & 1) == 1) {
  2263.             txDeletePrev(text);
  2264.             txDeleteChar(text);
  2265.             index++;
  2266.         }
  2267.     }
  2268.     //
  2269.     p = strGetIchStr(szkakko,index);
  2270.     if (*p == 0) {
  2271.         p = szkakko;
  2272.         index = 0;
  2273.     }
  2274.     {
  2275.         mchar* pe = strGetIchStr(szkakko,index + 2);
  2276.         txInsertBuff(text,p,pe-p);
  2277.         txLeft(text);
  2278.     }
  2279.     txSetDispSilent(text);
  2280.     return index;
  2281. }
  2282.  
  2283. #if !__TXC__
  2284. void TXAPI txInsertBrace(TX* text)
  2285. {
  2286. // 全角括弧挿入(学習つき)
  2287. // 全角括弧のペアを挿入後、カーソルを括弧の中にセット
  2288. // 連続して実行すると、いくつかの種類の括弧をトグル切り替え
  2289. // 最後に挿入したペアを覚えていて、次挿入するときは、そのペアを挿入します。
  2290. //{#MS} +^K
  2291. //{#MI} +^K
  2292. //{#VZ} ^]
  2293. //3.00A3 970507 new
  2294.     if (text->fClip && txIsClipInPara(text)) {
  2295.         //WCE0.91 970909 範囲選択対応
  2296.         mchar sz[CCHLINE];
  2297.         int lch = txGetWordEx(text,sz,cchof(sz));
  2298.         if (lch + 1 < cchof(sz)) {    // 文字列が失われる場合は実行しない
  2299.             txSetUndispSilent(text);
  2300.             txSelectDelete(text);
  2301.             sh->edit_iInsertBrace = _txInsertBrace(text,sh->edit_iInsertBrace);
  2302.             txCurInsertBuff(text,sz,lch);
  2303.             txSelectEx(text,CLIP_CHAR);
  2304.             text->fClipMouse = TRUE;
  2305.             txRightBytes(text,lch);
  2306.             txSetDispSilent(text);
  2307.         }
  2308.     } else {
  2309.         sh->edit_iInsertBrace = _txInsertBrace(text,sh->edit_iInsertBrace);
  2310.     }
  2311. }
  2312. #endif    // !__TXC__
  2313.  
  2314. BOOL txIDM_UIINSERTSEARCH(TX* text)
  2315. {
  2316.     mchar* sz = dialogaSelHist("最近、検索した文字列の挿入",HIST_SEARCH);
  2317.     if (sz) {
  2318.         txInsertAtKeisen(text,sz);    //WZ3.90E 980812 
  2319.         return TRUE;
  2320.     }
  2321.     return FALSE;
  2322. }
  2323.  
  2324. BOOL txIDM_UIINSERTCOPY(TX* text)
  2325. {
  2326.     mchar* sz = dialogaSelHist("最近、コピーした文字列の挿入",HIST_COPY);
  2327.     if (sz) {
  2328.         txInsertAtKeisen(text,sz);    //WZ3.90E 980812 
  2329.         return TRUE;
  2330.     }
  2331.     return FALSE;
  2332. }
  2333.  
  2334. BOOL txIDM_UIINSERTSTR(TX* text)
  2335. {
  2336.     mchar* sz = dialogaSelHist("最近、入力した文字列の挿入",HIST_STR);
  2337.     if (sz) {
  2338.         txInsertAtKeisen(text,sz);    //WZ3.90E 980812 
  2339.         return TRUE;
  2340.     }
  2341.     return FALSE;
  2342. }
  2343.  
  2344. #if WZFUNC_HTMLHIGH && !__TXC__
  2345. BOOL txIDM_UIINSERTFILENAME(TX* text)
  2346. {
  2347.     mchar szfilename[CCHPATHNAME] = {0};
  2348.     if (txuiGetOpenFileNameHtml(text,szfilename,"*.*")) {
  2349.         pathFlushSepa(szfilename,'\\');
  2350.         txInsertChar(text,'"');txInsert(text,szfilename);txInsertChar(text,'"');
  2351.         return TRUE;
  2352.     }
  2353.     return FALSE;
  2354. }
  2355. #endif
  2356.  
  2357. //##慣用句の挿入
  2358. //WZ3.90H 980910 汎用化
  2359.  
  2360. #if !__TXC__
  2361.  
  2362. typedef struct {
  2363.     TX* textTarget;
  2364.     TX* textContent;
  2365.     TX* textDest;
  2366.     mchar szHeadline[CCHWORD];
  2367.     WORD fSearchlist:1;    //WZ3.90H 980910 
  2368.     //WZ3.90H 980910 
  2369.     SEARCH_PACKET search;
  2370.     SEARCHOPT opt;
  2371.     LIST* list;
  2372. } INSERTTEMPLATE;
  2373.  
  2374. static void inserttemplateOnChange(HWND hwnd,INSERTTEMPLATE* context,BOOL fEnable)
  2375. {
  2376.     HDIALOG hd = dialogFromHwnd(hwnd);
  2377.     if (context->fSearchlist) {
  2378.         #if !WINDOWSCE
  2379.         SetDlgItemText_A(hwnd,IDD_SBLIST_SET,fEnable ? "<-名前の変更(&0)" : "<-変更(&0)");
  2380.         #endif
  2381.     } else {
  2382.         if (_pspc) {
  2383.             SetDlgItemText_A(hwnd,IDD_SBLIST_SET,fEnable ? "<-名前変更" : "<-変更");
  2384.         } else {
  2385.             SetDlgItemText_A(hwnd,IDD_SBLIST_SET,fEnable ? "<-名前の変更(&E)" : "<-変更(&E)");
  2386.         }
  2387.     }
  2388.     EnableDlgItem(hwnd,IDD_SBLIST_SET,!!context->list->n);    //WZ4.00Bn 991005 
  2389.     EnableDlgItem(hwnd,IDD_SBLIST_ADD,!fEnable);
  2390.     EnableDlgItem(hwnd,IDD_SBLIST_ADDCHILD,!fEnable);
  2391.     EnableWindow(context->textContent->hwndtext,!fEnable);
  2392.     #if !WINDOWSCE
  2393.     if (context->fSearchlist) {
  2394.         BOOL f = !fEnable;
  2395.         TX* text = context->textContent;
  2396.         dialogRead(hd);
  2397.         txMsghdrGetString(text,"Search:",NULL,context->search.szfind,cchof(context->search.szfind));
  2398.         txMsghdrGetString(text,"Replace:",NULL,context->search.szreplace,cchof(context->search.szreplace));
  2399.         {
  2400.             mchar sz[CCHWORD] = {0};
  2401.             txMsghdrGetString(text,"Searchmode:",NULL,sz,cchof(sz));
  2402.             context->opt.fRe = !!re(sz,"<RE>");
  2403.             context->opt.fWord = !!re(sz,"<WORD>");
  2404.             context->opt.fSenseCase = !!re(sz,"<SENSECASE>");
  2405.             context->opt.fSearchNoSymbol = !!re(sz,"<SEARCHNOSYMBOL>");
  2406.             context->opt.fNoEsc = !!re(sz,"<NOESC>");    //WZ4.00Bo 991011 検索スタイルで「\を通常文字として検索」も記憶するようにした。
  2407.             context->opt.fFuzzy = !!re(sz,"<FUZZY>");
  2408.             context->opt.fReplaceConfirm = !!re(sz,"<REPLACECONFIRM>");
  2409.             #if SEARCHOPT_DIALOG_NEW    //WZ3.90L 981123 
  2410.             searchoptSetupMode(&context->opt);
  2411.             #endif
  2412. //information("%s %d",sz,context->opt.fWord);
  2413.         }
  2414.         dialogWrite(hd);
  2415.         EnableDlgItem(hwnd,IDD_SEARCH,f);
  2416.         EnableDlgItem(hwnd,IDD_REPLACE,f);
  2417.         EnableDlgItem(hwnd,IDD_WORD,f);
  2418.         EnableDlgItem(hwnd,IDD_SENSECASE,f);
  2419.         EnableDlgItem(hwnd,IDD_NOSYMBOL,f);
  2420.         EnableDlgItem(hwnd,IDD_RE,f);
  2421.         EnableDlgItem(hwnd,IDD_FUZZY,f);
  2422.         EnableDlgItem(hwnd,IDD_REPLACECONFIRM,f);
  2423.         PostMessage(hwnd,WM_TXUSER+1,0,0);
  2424.     }
  2425.     #endif
  2426. }
  2427.  
  2428. #if !WINDOWSCE
  2429. static void inserttemplateOnSet(HWND hwnd,INSERTTEMPLATE* context)
  2430. {
  2431.     HDIALOG hd = dialogFromHwnd(hwnd);
  2432.     if (context->fSearchlist) {
  2433.         TX* text = context->textContent;
  2434.         dialogRead(hd);
  2435.         txMsghdrSet(text,"Search:",context->search.szfind);
  2436.         txMsghdrSet(text,"Replace:",context->search.szreplace);
  2437.         #if SEARCHOPT_DIALOG_NEW    //WZ3.90L 981123 
  2438.         searchoptToSearchmode(&context->opt);    // for set opt.fRe etc
  2439.         #endif
  2440.         {
  2441.             mchar sz[CCHWORD] = {0};
  2442.             if (context->opt.fRe) sstrcat(sz,"RE|");
  2443.             if (context->opt.fWord) sstrcat(sz,"WORD|");
  2444.             if (context->opt.fSenseCase) sstrcat(sz,"SENSECASE|");
  2445.             if (context->opt.fSearchNoSymbol) sstrcat(sz,"SEARCHNOSYMBOL|");
  2446.             if (context->opt.fNoEsc) sstrcat(sz,"NOESC|");//WZ4.00Bo 991011 
  2447.             if (context->opt.fFuzzy) sstrcat(sz,"FUZZY|");
  2448.             if (context->opt.fReplaceConfirm) sstrcat(sz,"REPLACECONFIRM|");
  2449.             txMsghdrSet(text,"Searchmode:",sz);
  2450. //information(sz);
  2451.         }
  2452.     }
  2453. }
  2454. #else
  2455.     #define inserttemplateOnSet(hwnd,context)
  2456. #endif
  2457.  
  2458. BOOL CALLBACK dlgprocInsertTemplate(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  2459. {
  2460.     HDIALOG hd = dialogFromHwnd(hwnd);
  2461.     INSERTTEMPLATE* context = dialogGetCustdata(hd);
  2462.     HWND hwndOutline = GetDlgItem(hwnd,IDD_OUTLINE_TREE);
  2463. //    OUTLINECONTROL* outline = outlineGetContext(hwndOutline);
  2464.     LIST* list = context->list;
  2465.     switch(message) {
  2466.         case WM_INITDIALOG: {
  2467.             context->list = list = listTvNew();
  2468.             list->hwnd = hwndOutline;
  2469.             list->text = context->textTarget;
  2470.             list->iHeadlineMin = 1;
  2471.             olFlush(list);
  2472.             listJump(list,sh->nparaTemplateTarget);
  2473.             listTvDispAll(list);
  2474.             if (list->n == 0) inserttemplateOnChange(hwnd,context,0);    //WZ4.00Bn 991005 
  2475.             //
  2476.             PostMessage(hwnd,WM_TXUSER+1,0,0);
  2477.             return INITDIALOG_SKIP_TRUE;
  2478.         }
  2479.         case WM_COMMAND: {
  2480.             int id = GET_WM_COMMAND_ID(wParam,lParam);
  2481.             switch(id) {
  2482.                 case IDOK: {
  2483.                     olSaveEdited(list,FALSE);
  2484.                     if (context->fSearchlist) {
  2485.                     } else {
  2486.                         TX* text = context->textContent;
  2487.                         TX* textDst = context->textDest;
  2488.                         if (txGetTextSize(text)) {
  2489.                             txSelectOverwriteModal(textDst);    //WZ3.90O 981203 
  2490.                             txJumpParaTop(textDst);
  2491.                             if (1) {    // "<>"に対応
  2492.                                 if (txSearchEx(text,"<>",0)) {
  2493.                                     IFILE adr = txGetAddress(textDst);
  2494.                                     txSetUndisp(textDst);
  2495.                                     txInsertText(textDst,text);
  2496.                                     txJumpAddressNear(textDst,adr);
  2497.                                     if (txSearchEx(textDst,"<>",0)) {
  2498.                                         txDeleteChar(textDst);
  2499.                                         txDeleteChar(textDst);
  2500.                                     }
  2501.                                     txSetDisp(textDst);
  2502.                                 } else {
  2503.                                     txInsertText(textDst,text);
  2504.                                 }
  2505.                             } else {
  2506.                                 txInsertText(textDst,text);
  2507.                             }
  2508.                         } else {
  2509.                             // 「内容」が空のときは「名前」を文字列として挿入
  2510.                             mchar* sz = GetWindowTextAlloc_A(GetDlgItem(hwnd,IDD_OUTLINE_NAME));
  2511.                             txInsert(textDst,sz);
  2512.                             free(sz);
  2513.                         }
  2514.                     }
  2515.                     break;
  2516.                 }
  2517.                 case IDCANCEL: {
  2518.                     olSaveEdited(list,TRUE);
  2519.                     break;
  2520.                 }
  2521.                 case IDD_SBLIST_SET: {
  2522.                     inserttemplateOnSet(hwnd,context);
  2523.                     olSetText(list,context->textContent,GetDlgItem(hwnd,IDD_OUTLINE_NAME));
  2524.                     break;
  2525.                 }
  2526.                 case IDD_SBLIST_ADD:
  2527.                 case IDD_SBLIST_ADDCHILD: {
  2528.                     HWND hwndEdit = GetDlgItem(hwnd,IDD_OUTLINE_NAME);
  2529.                     mchar* sz = GetWindowTextAlloc_A(hwndEdit);
  2530.                     OUTLINEITEM* now = listReadCur(list);
  2531.                     {    //WZ4.00Bn 991005 検索スタイルが空のときに追加ができなかったのを修正。
  2532.                         BOOL fChild = (id == IDD_SBLIST_ADDCHILD)||(now == NULL);
  2533.                         int iHeadline = now ? (now->head.iHeadline + fChild) : 1;
  2534.                         if (check_iHeadline(iHeadline)) {
  2535.                             inserttemplateOnSet(hwnd,context);    //WZ4.00Bj 990830 検索置換スタイルの「追加」で検索語などがセットされなかったのを修正。
  2536.                             olInsert(list,now,sz,iHeadline,(!fChild*OLI_INSERTPREV)|OLI_INSERTCONTENT,context->textContent);
  2537.                         }
  2538.                     }
  2539.                     free(sz);
  2540.                     break;
  2541.                 }
  2542.                 case IDD_OUTLINE_UP: olMoveUp(list);break;
  2543.                 case IDD_OUTLINE_DOWN: olMoveDown(list);break;
  2544.                 case IDD_OUTLINE_CUT: {
  2545.                     olCut(list);
  2546.                     if (list->n == 0) inserttemplateOnChange(hwnd,context,0);    //WZ4.00Bn 991005 
  2547.                     break;
  2548.                 }
  2549.                 case IDD_OUTLINE_PASTE: olPaste(list);break;
  2550.                 #if !WINDOWSCE    //WZ4.00Bj 990830 検索置換スタイルで検索オプションボックスのEnable状態をセットするようにした。
  2551.                 case IDD_SEARCHMODE:
  2552.                 case IDD_SEARCHMODE+1:
  2553.                 case IDD_SEARCHMODE+2:
  2554.                 case IDD_SEARCHMODE+3:
  2555.                 case IDD_FUZZY:
  2556.                 case IDD_RE: PostMessage(hwnd,WM_TXUSER+1,0,0);break;
  2557.                 #endif
  2558.             }
  2559.             break;
  2560.         }
  2561.         case WM_DESTROY: {
  2562.             sh->nparaTemplateTarget = list->iCur;
  2563.             listDelete(list);
  2564.             context->list = NULL;    //WZ4.00Bl 990915 
  2565.             break;
  2566.         }
  2567.         case WM_NOTIFY: {
  2568.             TV_DISPINFO* nm = (LPVOID)lParam;
  2569.             if (list && nm->hdr.hwndFrom == list->hwnd) {
  2570.                 if (list->fRemaking) return 0;
  2571.                 switch(nm->hdr.code) {
  2572.                     case TVN_SELCHANGED: {
  2573.                         listTvGetCur(list);
  2574.                         olGetText(list,context->textContent,GetDlgItem(hwnd,IDD_OUTLINE_NAME));
  2575.                         inserttemplateOnChange(hwnd,context,listGetCurNestChilds(list));
  2576.                         break;
  2577.                     }
  2578.                 }
  2579.             }
  2580.             break;
  2581.         }
  2582.         case WM_TXUSER+1: {
  2583.             wndSetEnableSearchOption(hwnd);
  2584.             break;
  2585.         }
  2586.     }
  2587.     return FALSE;
  2588. }
  2589.  
  2590. static BOOL dialogaSelectOutline(TX* text,int mode,SEARCH_PACKET* pSearch)
  2591. {
  2592. // 慣用句の挿入、検索リストなど。
  2593. //WZ3.90H 980910 renew
  2594.     BOOL fSearchlist = (mode == 1);
  2595.     HDIALOG hd = dialog(fSearchlist ? "検索のスタイル" : "慣用句の挿入");    //WZ3.90L 981115 "検索リスト"はWZ3の同一名称別機能とまぎらわしいので名前を変更。
  2596.     wchar wszdicname[CCHPATHNAME];
  2597.     TX* textTarget = textopenW(wpathFullConfig(wszdicname,fSearchlist ? L"search.dic" : L"template.dic"));
  2598.     TX* textContent = textopen(NULL);    // 内容
  2599.     INSERTTEMPLATE context;
  2600.     BOOL ret;
  2601.     //
  2602. #if UNIX
  2603.     kcToTBEx(textTarget,KC_SJIS);////
  2604. #endif
  2605.     textTarget->fHeadlineStringStd = TRUE;//PWZ2BETA0.3 980509 
  2606.     structClear(context);
  2607.     context.textTarget = textTarget;
  2608.     context.textContent = textContent;
  2609.     context.textDest = text;
  2610.     context.fSearchlist = fSearchlist;
  2611.     //WCE0.94 970922 慣用句のテキストウィンドウでアンドゥできるようにした
  2612.     txClose(textContent);
  2613.     textContent->fEnableUndo = TRUE;
  2614.     txOpenText(textContent);
  2615.     //
  2616.     dialogSetCustdata(hd,&context);
  2617.     dialogSetDlgproc(hd,dlgprocInsertTemplate);
  2618.     //
  2619.     dialogCaption(hd,"一覧(&L):");
  2620.     {
  2621.         DTRECT r;
  2622.         dialogGetPos(hd,&r);
  2623.         r.cx = DTCX * 20;
  2624.         r.cy = DTCY * (fSearchlist ? 13 : 9-_pspc);
  2625.         __dialogAddItem(hd,WC_TREEVIEWA,NULL,IDD_OUTLINE_TREE,&r,TVS_TREELIST);
  2626.         dialogSetPosY(hd,r.y + r.cy);
  2627.         dialogSpaceV(hd);
  2628.     }
  2629.     //
  2630.     dialogLFV(hd);
  2631.     dialogSetPosLF(hd);
  2632.     if (!_pspc) dialogSetPosY(hd,DTCY * 2);
  2633.     dialogControlID(hd,IDD_SBLIST_SET);
  2634.     dialogPushbutton(hd,NULL,14-_pspc*3);
  2635.     #if !WINDOWSCE
  2636.     if (fSearchlist) {hd->fAutoAccessKey = TRUE;hd->chAutoAccessKey = '1';}
  2637.     #endif
  2638.     dialogControlID(hd,IDD_SBLIST_ADD);
  2639.     dialogPushbutton(hd,"<-追加(&A)",14);
  2640.     dialogControlID(hd,IDD_SBLIST_ADDCHILD);
  2641.     dialogPushbutton(hd,"<-子の追加(&C)",14);
  2642.     dialogSpaceV(hd);
  2643.     dialogSetH(hd);
  2644.     dialogControlID(hd,IDD_OUTLINE_UP);
  2645.     dialogPushbutton(hd,"↑(&B)",5+SFF);
  2646.     dialogControlID(hd,IDD_OUTLINE_DOWN);
  2647.     dialogPushbutton(hd,"↓(&N)",5+SFF);
  2648.     dialogLFSetV(hd);
  2649.     dialogControlID(hd,IDD_OUTLINE_CUT);
  2650.     dialogPushbutton(hd,"切り取り(&T)",11+SFF*2);
  2651.     dialogControlID(hd,IDD_OUTLINE_PASTE);
  2652.     dialogPushbutton(hd,"貼り付け(&P)",11+SFF*2);
  2653.     if (fSearchlist) hd->fAutoAccessKey = FALSE;
  2654.     //
  2655.     if (_pspc) {
  2656.         dialogLF(hd);
  2657.         dialogSetPosX(hd,DTCX);
  2658.     } else {
  2659.         dialogLFV(hd);
  2660.     }
  2661.     dialogControlID(hd,IDD_OUTLINE_NAME);
  2662.     dialogString(hd,fSearchlist?"名前(&N):":"名前(&M):",7+_pspc+SFF*2,context.szHeadline,cchof(context.szHeadline),20);
  2663.     dialogControlID(hd,IDD_OUTLINE_CONTENT);
  2664.     if (fSearchlist) {
  2665.         #if !WINDOWSCE
  2666.         context.search = sh->search;
  2667.         context.opt.text = text;
  2668.         searchoptFromSearchmode(&context.opt,context.search.searchmode);
  2669.         //
  2670.         dialogSpaceV(hd);
  2671.         dialogControlID(hd,IDD_SEARCH);
  2672.         dialogControlHist(hd,HIST_SEARCH);
  2673.         dialogString(hd,"検索(&S):",7+SFF*2,context.search.szfind,CCHWORD,20);
  2674.         dialogControlID(hd,IDD_REPLACE);
  2675.         dialogControlHist(hd,HIST_SEARCH);
  2676.         dialogString(hd,"置換(&R):",7+SFF*2,context.search.szreplace,CCHWORD,20);
  2677.         //
  2678.         dialogSetPosLF(hd);    //WZ3.90L 981115 
  2679.         dialogAddSearchopt(hd,&context.opt,2);
  2680.         //
  2681.         dialogEditWz(hd,NULL,textContent,0,0,0);
  2682.         //WZ3.90L 981115 
  2683.         dialogLFV(hd);dialogSetPosY(hd,DTCY/2);dialogIndent(hd,-9);
  2684.         dialogOK(hd,10);
  2685.         dialogCancel(hd,10);
  2686.         #endif
  2687.     } else {
  2688.         #if WINDOWSCE2
  2689.         dialogEditWz(hd,"内容(&O):",textContent,28+_pspc*2,9-_pspc*5+_pocketpc,WS_HSCROLL|WS_VSCROLL);//WCE1.01 980312 10->9
  2690.         #else
  2691.         dialogEditWz(hd,"内容(&O):",textContent,28,10,WS_HSCROLL|WS_VSCROLL);
  2692.         #endif
  2693.     }
  2694.     {//WCE0.91 970911 
  2695.         TX* text = textContent;
  2696.         text->dlgcode = DLGC_WANTALLKEYS;
  2697.         txKeyLoadFrame(text);//WCE0.91 970910 慣用句でもWZのキー定義で使いたい。使えるようにした
  2698.     }
  2699.     //
  2700.     ret = dialogOpen(hd);
  2701.     if (ret == IDOK && fSearchlist) {
  2702.         #if !WINDOWSCE
  2703.         *pSearch = context.search;
  2704.         pSearch->searchmode = searchoptToSearchmode(&context.opt);
  2705.         #endif
  2706.     }
  2707.     //
  2708. //    sh->nparaTemplateTarget = context.nparaTarget;
  2709.     textclose(textTarget);
  2710.     textclose(textContent);
  2711. #if 1//XZ0.10 990625 CancelされてもTRUEが返っていた。
  2712.     return !!ret;
  2713. #else
  2714.     return TRUE;
  2715. #endif
  2716. }
  2717.  
  2718. BOOL txIDM_UIINSERTTEMPLATE(TX* text)
  2719. {
  2720.     return dialogaSelectOutline(text,0,NULL);
  2721. }
  2722.  
  2723. #if !WINDOWSCE
  2724. BOOL txuiSearchlist(TX* text,SEARCH_PACKET* search)
  2725. {
  2726.     return dialogaSelectOutline(text,1,search);
  2727. }
  2728. #endif
  2729.  
  2730. #endif // !__TXC__
  2731.  
  2732.  
  2733. //##日付の挿入
  2734.  
  2735. #define IDD_DATEINSERT    100
  2736. #define IDD_DATEFORMAT    110    // 110-119
  2737.  
  2738. mchar* tszYoubi[] = {"日","月","火","水","木","金","土"};
  2739.  
  2740. void sprintfDate(mchar szdst[CCHWORD],mchar* szDateFormat,TX* text)
  2741. {
  2742. // text:NULLでも可
  2743.     static mchar* tszYoubiE[] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
  2744.     static mchar* tszYoubiEs[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
  2745.     static mchar* tszMonthE[] = {
  2746.         "January","February","March","April","May","June",
  2747.         "July","August","September","October","November","December"
  2748.     };
  2749.     SYSTEMTIME st;
  2750.     GetLocalTime(&st);
  2751.     {
  2752.         mchar szbuff[CCHWORD] = {0};    // 出力先
  2753.         mchar* p = szDateFormat;
  2754.         mchar* p0 = p;
  2755.         while(1) {
  2756.             mchar c = *p;
  2757.             if (c == 0) break;
  2758.             if (c == '%') {
  2759.                 // 大文字はtxVar、小文字は日時
  2760.                 BOOL f02d = FALSE;
  2761.                 mchar* szf = "%d";
  2762.                 mchar buff[CCHWORD] = {0};
  2763.                 mchar c = p[1];
  2764.                 int nc = 1;
  2765.                 if (p > p0) {
  2766.                     sstrcatlen(szbuff,p0,p - p0);
  2767.                 }
  2768.                 //
  2769.                 p++;
  2770.                 p0 = p;
  2771.                 if (c == 0) break;
  2772.                 //
  2773.                 if (c == '2') {
  2774.                     szf = "%2d";
  2775.                     p++;
  2776.                     c = *p;
  2777.                     p0 = p;
  2778.                     if (c == 0) break;
  2779.                 } else {
  2780.                     mchar* q = p + 1;
  2781.                     while(c == *q) {
  2782.                         q++;
  2783.                         nc++;
  2784.                     }
  2785.                     if (nc == 2) {
  2786.                         f02d = TRUE;
  2787.                         szf = "%02d";
  2788.                     }
  2789.                 }
  2790.                 //
  2791.                 switch(c) {
  2792.                     case 'y': {    // 年
  2793.                         if (nc == 4) {
  2794.                             sprintf(buff,"%4d",st.wYear);
  2795.                             p += 4;
  2796.                         } else if (nc == 1) {
  2797.                             sprintf(buff,"平成%d",st.wYear-1988);
  2798.                             p++;
  2799.                         } else {
  2800.                             sprintf(buff,szf,st.wYear % 100);
  2801.                             p += 1 + f02d;
  2802.                         }
  2803.                         break;
  2804.                     }
  2805.                     case 'm': {    // 月
  2806.                         if (nc == 4) {
  2807.                             strcpy(buff,tszMonthE[st.wMonth-1]);
  2808.                             p += 4;
  2809.                         } else if (nc == 3) {
  2810.                             strcpylen(buff,tszMonthE[st.wMonth-1],3);
  2811.                             p += 3;
  2812.                         } else {
  2813.                             sprintf(buff,szf,st.wMonth);
  2814.                             p += 1 + f02d;
  2815.                         }
  2816.                         break;
  2817.                     }
  2818.                     case 'd': {    // 日にち dd d
  2819.                         sprintf(buff,szf,st.wDay);
  2820.                         p += 1 + f02d;
  2821.                         break;
  2822.                     }
  2823.                     case 'w': {    // 曜日
  2824.                         if (nc == 4) {
  2825.                             strcpy(buff,tszYoubiE[st.wDayOfWeek]);
  2826.                             p += 4;
  2827.                         } else if (nc == 3) {
  2828.                             strcpy(buff,tszYoubiEs[st.wDayOfWeek]);
  2829.                             p += 3;
  2830.                         } else {
  2831.                             strcpy(buff,tszYoubi[st.wDayOfWeek]);
  2832.                             p++;
  2833.                         }
  2834.                         break;
  2835.                     }
  2836.                     case 'h': {    // 時
  2837.                         sprintf(buff,szf,st.wHour);
  2838.                         p += 1 + f02d;
  2839.                         break;
  2840.                     }
  2841.                     case 't': {    // 分
  2842.                         sprintf(buff,szf,st.wMinute);
  2843.                         p += 1 + f02d;
  2844.                         break;
  2845.                     }
  2846.                     case 's': {    // 秒
  2847.                         sprintf(buff,szf,st.wSecond);
  2848.                         p += 1 + f02d;
  2849.                         break;
  2850.                     }
  2851.                     default: {
  2852.                         // %NAME(NAME:英大文字列+数字列)なら、txVarReadString(SF_NAME)を出力
  2853.                         if (isupper(c)) {
  2854.                             #if !__TXC__
  2855.                             mchar* p0 = p;
  2856.                             mchar szKey[CCHWORD];
  2857.                             while(isupper(*p)) p++;
  2858.                             while(isdigit(*p)) p++;
  2859.                             if (text) {
  2860.                                 strcpy(szKey,"SF_");
  2861.                                 sstrcatlen(szKey,p0,p - p0);
  2862.                                 sstrcpy(buff,txVarReadString(text,szKey,NULL));
  2863.                                 if (text->fTxfVarConfig && buff[0] == 0) {
  2864.                                     strcpy(buff,"%");
  2865.                                     sstrcat(buff,szKey + 3);
  2866.                                 }
  2867.                             }
  2868.                             #endif // !__TXC__
  2869.                         } else {
  2870.                             // "%x" ->"x"
  2871.                             if (!tbiskanji(c)) {
  2872.                                 szbuff[0] = c;
  2873.                                 szbuff[1] = 0;
  2874.                                 p++;
  2875.                             }
  2876.                         }
  2877.                         break;
  2878.                     }
  2879.                 }
  2880.                 sstrcat(szbuff,buff);
  2881.                 p0 = p;
  2882.             } else {
  2883.                 p++;
  2884.             }
  2885.         }
  2886.         if (p > p0) {
  2887.             sstrcatlen(szbuff,p0,p - p0);
  2888.         }
  2889.         //
  2890.         strcpy(szdst,szbuff);
  2891.     }
  2892. }
  2893.  
  2894. //PWZ2BETA0.3 980524 ////ファイル名の自動決定と、似たような関数は統合できる?
  2895.  
  2896. typedef struct {
  2897.     HSTRBLK sb;
  2898.     mchar szDate[CCHWORD];            // 日付フォーマット
  2899.     mchar szResult[CCHPATHNAME];    // 解釈結果
  2900.     BOOL fMente;                    // メンテナンスモード?
  2901. } INSERTDATE;
  2902.  
  2903. static void FlushDispInsertDate(HWND hwnd)
  2904. {
  2905.     HDIALOG hd = dialogFromHwnd(hwnd);
  2906.     INSERTDATE* context = dialogGetCustdata(hd);
  2907.     dialogRead(hd);
  2908.     sprintfDate(context->szResult,context->szDate,NULL);
  2909.     SetDlgItemText_A(hwnd,IDD_DATEINSERT,context->szResult);
  2910. }
  2911.  
  2912. static void FlushDispItems(HWND hwnd)
  2913. {
  2914.     HDIALOG hd = dialogFromHwnd(hwnd);
  2915.     INSERTDATE* context = dialogGetCustdata(hd);
  2916.     HWND hctrl = GetDlgItem(hwnd,IDD_SBLIST);
  2917.     int isel = ListBox_GetCurSel(hctrl);
  2918.     if (isel >= 0) {
  2919.         mchar* szClms = sbRead(context->sb,isel);
  2920.         mchar* p = strchr(szClms,CHAR_TAB);
  2921.         sstrcpy(context->szDate,p ? p + 1 : "");
  2922.         if (context->fMente) {
  2923.             dialogWrite(hd);
  2924.         }
  2925.     }
  2926. }
  2927.  
  2928. static void ItemsToList(HWND hwnd,mchar* szName,BOOL fAdd)
  2929. {
  2930.     HDIALOG hd = dialogFromHwnd(hwnd);
  2931.     INSERTDATE* context = dialogGetCustdata(hd);
  2932.     HWND hctrl = GetDlgItem(hwnd,IDD_SBLIST);
  2933.     int isel = ListBox_GetCurSel(hctrl);
  2934.     dialogRead(hd);
  2935.     {
  2936.         mchar szData[CCHNAME + CCHWORD];
  2937.         sstrcpy(szData,szName);
  2938.         sstrcat(szData,"\t");
  2939.         sstrcat(szData,context->szDate);
  2940.         {
  2941.             int i = isel;
  2942.             if (fAdd) {
  2943.                 if (!sbInsert(context->sb,0,szData)) {
  2944.                     winformation(rcStringW(74));
  2945.                 }
  2946.                 isel = 0;
  2947.             } else {
  2948.                 sbDelI(context->sb,i);
  2949.                 if (!sbInsert(context->sb,i,szData)) {
  2950.                     winformation(rcStringW(74));
  2951.                 }
  2952.             }
  2953.             ListBox_SetStrblkFirstclm(hctrl,context->sb);
  2954.             ListBox_SetCurSel(hctrl,isel);
  2955.         }
  2956.     }
  2957. }
  2958.  
  2959. BOOL CALLBACK dlgprocInsertDate(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  2960. {
  2961.     HDIALOG hd = dialogFromHwnd(hwnd);
  2962.     INSERTDATE* context = dialogGetCustdata(hd);
  2963.     if (subdlgprocSblist(hwnd,message,wParam,lParam,context->sb)) return TRUE;
  2964.     switch(message) {
  2965.         case WM_INITDIALOG: {
  2966.             // ドロップダウンリストで選択してもWM_COMMANDが来ないので、
  2967.             // タイマを使う
  2968.             SetTimer(hwnd,WM_TIMER_TXUSER,500,NULL);
  2969.             {
  2970.                 HWND hctrl = GetDlgItem(hwnd,IDD_SBLIST);
  2971.                 ListBox_SetStrblkFirstclm(hctrl,context->sb);
  2972.                 ListBox_SetCurSel(hctrl,sh->edit_iInsertDate);//WCE0.91 970911 
  2973.                 FlushDispItems(hwnd);
  2974.             }
  2975.             FlushDispInsertDate(hwnd);
  2976.             break;
  2977.         }
  2978.         case SBLISTN_ADD: {
  2979.             ItemsToList(hwnd,(mchar*)lParam,TRUE);
  2980.             break;
  2981.         }
  2982.         case SBLISTN_SET: {
  2983.             ItemsToList(hwnd,(mchar*)lParam,FALSE);
  2984.             break;
  2985.         }
  2986.         case SBLISTN_FLUSHLIST: {
  2987.             HWND hctrl = GetDlgItem(hwnd,IDD_SBLIST);
  2988.             ListBox_SetStrblkFirstclm(hctrl,context->sb);
  2989.             break;
  2990.         }
  2991.         case SBLISTN_FLUSHCONTENT: {
  2992.             FlushDispItems(hwnd);
  2993.             break;
  2994.         }
  2995.         case WM_COMMAND: {
  2996.             int cmd = GET_WM_COMMAND_CMD(wParam,lParam);
  2997.             int id;
  2998.             switch(id = GET_WM_COMMAND_ID(wParam,lParam)) {
  2999.                 case IDD_DATEFORMAT: {
  3000.                     FlushDispInsertDate(hwnd);
  3001.                     break;
  3002.                 }
  3003.                 case IDOK: {//WCE0.91 970911 
  3004.                     HWND hctrl = GetDlgItem(hwnd,IDD_SBLIST);
  3005.                     sh->edit_iInsertDate = ListBox_GetCurSel(hctrl);
  3006.                     FlushDispInsertDate(hwnd);//WCE0.91 970911 
  3007.                     break;
  3008.                 }
  3009.             }
  3010.             break;
  3011.         }
  3012.         case WM_TIMER: {
  3013.             switch(wParam) {
  3014.                 case WM_TIMER_TXUSER: {
  3015.                     FlushDispInsertDate(hwnd);
  3016.                     break;
  3017.                 }
  3018.             }
  3019.             break;
  3020.         }
  3021.     }
  3022.     return FALSE;
  3023. }
  3024.  
  3025. static BOOL _txuiInsertDate(TX* text,BOOL fMente)
  3026. {
  3027. //PWZ2BETA0.3 980519 「日付・時刻の挿入」全面改良
  3028.     HDIALOG hd = dialog(fMente ? "日付・時刻の挿入の詳細" : "日付・時刻の挿入");
  3029.     static mchar szHist[] = "pwzDateEx";    //PWZ2BETA0.3 980519 旧"pwzDate"
  3030.     HSTRBLK sb = historyOpen(szHist,4096);
  3031.     int ret;
  3032.     int idEdit = 0;
  3033.     int y;    // for _pspc
  3034.     DTRECT r;
  3035.     INSERTDATE context;
  3036.     structClear(context);
  3037.     context.sb = sb;
  3038.     context.fMente = fMente;
  3039.     dialogSetCustdata(hd,&context);
  3040.     #if !__TXC__
  3041.     dialogSetDialoghelp(hd,8);    // "日付・時刻の挿入"
  3042.     #endif // !__TXC__
  3043. //sbDelAll(sb);    // debug
  3044.     if (sbGetCount(sb) == 0) {
  3045.         sbAdd(sb,"xx年xx月xx日xx曜\t%yy年%2m月%2d日 %w曜");
  3046.         sbAdd(sb,"年/月/日 曜日\t%yy/%2m/%2d %www");
  3047.         sbAdd(sb,"年月日\t%yy%mm%dd");
  3048.         sbAdd(sb,"xx時xx分\t%hh時%tt分");
  3049.         sbAdd(sb,"時:分\t%hh:%tt");
  3050.         sbAdd(sb,"年/月/日 時:分\t%yy/%mm/%dd %hh:%tt");
  3051.     }
  3052.     dialogSetDlgproc(hd,dlgprocInsertDate);
  3053.     if (context.fMente) {
  3054.         dialogCaption(hd,"書式(&F):");
  3055.         dialogString(hd,NULL,0,context.szDate,cchof(context.szDate),30);
  3056.     }
  3057.     if (context.fMente) {
  3058.         //
  3059.         dialogLF(hd);
  3060.         dialogSpaceV(hd);
  3061.         dialogCaption(hd,"プレビュー:");
  3062.         dialogControlID(hd,IDD_DATEINSERT);
  3063.         dialogCaptionDynamic(hd,NULL,30);
  3064.         //
  3065.         if (_pspc) {
  3066.             y = dialogGetPosY(hd);
  3067.         } else {
  3068.             dialogLFV(hd);
  3069.             dialogSetPosLX(hd,36);
  3070.             dialogSetPosY(hd,DTCY * 3);
  3071.         }
  3072.         dialogControlID(hd,IDD_SBLIST_ADD);
  3073.         dialogPushbutton(hd,"追加(&A)->",14);
  3074.         dialogControlID(hd,IDD_SBLIST_SET);
  3075.         dialogPushbutton(hd,"変更(&E)->",14);
  3076.         dialogSpaceV(hd);
  3077.         dialogIndent(hd,3);
  3078.         dialogControlID(hd,IDD_SBLIST_DEL);
  3079.         dialogPushbutton(hd,"削除(&D)...",11);
  3080.         dialogControlID(hd,IDD_SBLIST_UP);
  3081.         dialogPushbutton(hd,"↑(&B)",11);
  3082.         dialogControlID(hd,IDD_SBLIST_DOWN);
  3083.         dialogPushbutton(hd,"↓(&N)",11);
  3084. //        dialogPushbutton(hd,"<-読み込み(&L)",14);
  3085.     }
  3086.     //
  3087.     if (_pspc) {
  3088.         #if WINDOWSCE
  3089.         if (context.fMente) {
  3090.             dialogSetPosY(hd,y);
  3091.             dialogSetPosLX(hd,15);
  3092.         } else {
  3093.             dialogLFV(hd);
  3094.         }
  3095.         #endif
  3096.     } else {
  3097.         dialogLFV(hd);
  3098.     }
  3099.     dialogControlID(hd,IDD_SBLIST);
  3100.     if (context.fMente) {
  3101.         #if WINDOWSCE2
  3102.         dialogAddListbox(hd,"一覧(&L):",14,7-_pspc*2);    //WCE1.01 980312 8->7
  3103.         #else
  3104.         dialogAddListbox(hd,"一覧(&L):",14,8);
  3105.         #endif
  3106.     } else {
  3107.         dialogSetNotifyAsOK(hd,IDD_SBLIST,LBN_DBLCLK);//WCE0.91 970911 
  3108.         dialogAddListbox(hd,"一覧(&L):",WINDOWSCE ? 20 : 24,5);
  3109.     }
  3110.     //
  3111.     if (!context.fMente) {
  3112.         #if WINDOWSCE
  3113.         dialogLFV(hd);
  3114.         #else
  3115.         //WZ4.00Ab 990204 「日付・時刻の挿入」に[OK],[キャンセル]ボタンを付けた
  3116.         dialogCmdLFV(hd);
  3117.         dialogOK(hd,14);
  3118.         dialogCancel(hd,14);
  3119.         dialogSpaceV(hd);
  3120.         #endif
  3121.         idEdit = dialogCmd(hd,"詳細(&E) >>",14);
  3122.         dialogLF(hd);
  3123.         dialogCaption(hd,"プレビュー:");
  3124.         dialogControlID(hd,IDD_DATEINSERT);
  3125.         dialogCaptionDynamic(hd,NULL,38);
  3126.     }
  3127.     //
  3128.     {
  3129.         if (ret = dialogOpen(hd)) {
  3130. //winformation(L"%d %d",ret,idEdit);
  3131.             if (ret == idEdit) {
  3132.                 ret = 2;
  3133.             } else {
  3134.                 ret = TRUE;
  3135.                 txSelectOverwriteModal(text);    //WZ3.90O 981203 
  3136.                 txInsert(text,context.szResult);
  3137.             }
  3138.         }
  3139.     }
  3140.     historyClose(szHist,sb);
  3141.     return ret;
  3142. }
  3143.  
  3144. BOOL txIDM_UIINSERTDATE(TX* text)
  3145. {
  3146.     int ret = _txuiInsertDate(text,FALSE);
  3147.     if (ret == 2) {
  3148.         return _txuiInsertDate(text,TRUE);
  3149.     }
  3150.     return ret;
  3151. }
  3152.  
  3153. //##最近削除した文字列の挿入
  3154.  
  3155. #if !__TXC__
  3156.  
  3157. #define IDD_DELEDSTRLIST    100
  3158.  
  3159. BOOL CALLBACK dlgprocInsertDelete(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  3160. {
  3161.     HDIALOG hd = dialogFromHwnd(hwnd);
  3162.     TX* text = dialogGetCustdata(hd);
  3163.     HWND hctrl = GetDlgItem(hwnd,IDD_DELEDSTRLIST);
  3164.     switch(message) {
  3165.         case WM_INITDIALOG: {
  3166.             ListBox_SetDeletedFromUndo(hctrl,text);
  3167.             ListBox_SetCurSel(hctrl,0);
  3168.             break;
  3169.         }
  3170.         case WM_COMMAND: {
  3171.             switch(GET_WM_COMMAND_ID(wParam,lParam)) {
  3172.                 case IDOK: {
  3173.                     int isel = ListBox_GetCurSel(hctrl);
  3174.                     if (isel >= 0) {
  3175.                         mchar* sz = ListBox_GetItemTextAlloc_A(hctrl,isel);
  3176.                         if (sz) {
  3177.                             txInsertAtKeisen(text,sz);
  3178.                         }
  3179.                         free(sz);
  3180.                     }
  3181.                     break;
  3182.                 }
  3183.             }
  3184.             break;
  3185.         }
  3186.     }
  3187.     return FALSE;
  3188. }
  3189.  
  3190. BOOL txIDM_UIINSERTDELETE(TX* text)
  3191. {
  3192.     HDIALOG hd = dialog("最近、削除した文字列の挿入");
  3193.     dialogSetCustdata(hd,text);
  3194.     dialogSetDlgproc(hd,dlgprocInsertDelete);
  3195.     //
  3196.     dialogSetNotifyAsOK(hd,IDD_DELEDSTRLIST,LBN_DBLCLK);
  3197.     dialogControlID(hd,IDD_DELEDSTRLIST);
  3198.     dialogAddListbox(hd,NULL,30,5);
  3199.     if (dialogOpen(hd)) {
  3200.         return TRUE;
  3201.     }
  3202.     return FALSE;
  3203. }
  3204.  
  3205. #endif // !__TXC__
  3206.  
  3207. //##外部ヘルプ
  3208. //WCE1.01 980205 new
  3209.  
  3210. #if !WINDOWSCE && !UNIX
  3211.  
  3212. #ifdef UNICODE
  3213.     BOOL WinHelp_A(HWND hwnd,mchar* lpszHelp,UINT uCommand,DWORD dwData)
  3214.     {
  3215.         wchar* wszHelp = wstrdupA(lpszHelp);
  3216.         wchar* wData = wstrdupA(dwData);
  3217.         BOOL ret = WinHelp(hwnd,wszHelp,uCommand,wData);
  3218.         free(wszHelp);
  3219.         free(wData);
  3220.         return ret;
  3221.     }
  3222. #else
  3223.     #define WinHelp_A    WinHelp
  3224. #endif
  3225.  
  3226. #if !__TXC__
  3227. void txHelpOpenW(TX* text,wchar* _wszfilename)
  3228. {
  3229. // カーソル位置の単語で_wszfilenameのWindowsHELPを引く
  3230.     if (!wstricmp(_wszfilename,L"TX")) {
  3231.         txIdmExec(text,IDM_MACRO_HELPAPI);
  3232.     } else {
  3233.         mchar szWord[CCHWORD];
  3234.         txGetWordAfterEx(text,szWord,CCHWORD);
  3235.         {
  3236.             wchar wszfilename[CCHPATHNAME] = {0};
  3237.             mchar szfilename[CCHPATHNAME];
  3238.             wpathSetFileName(wszfilename,_wszfilename);
  3239.             wpathtopath(wszfilename,szfilename);
  3240.             if (szWord[0]) {
  3241.                 WinHelp_A(text->hwndbase,szfilename,HELP_PARTIALKEY,(LPARAM)(mchar*)szWord);
  3242.             } else {
  3243.                 WinHelp_A(text->hwndbase,szfilename,HELP_CONTENTS,0);
  3244.             }
  3245.         }
  3246.     }
  3247. }
  3248.  
  3249. void txHelpOpen(TX* text,mchar* szfilename)
  3250. {
  3251.     if (szfilename[0]) {    //WZ4.00A 981230 NULLチェックを追加
  3252.         wchar* wsz = wstrdupA(szfilename);
  3253.         txHelpOpenW(text,wsz);
  3254.         free(wsz);
  3255.     }
  3256. }
  3257. #endif // !__TXC__
  3258.  
  3259. void txHelpOpenExtend(TX* text,int iHelp)
  3260. {
  3261. //WZ4.00A 981230 外部ヘルプの設定がされていないときに、外部ヘルプを参照すると、メモリが足りないというエラーメッセージが出ることがあったのを改良。
  3262. //WZ4.00A 981230 new
  3263. //WZ4.00Ee 010411 renew
  3264.     if (iHelp == 0 && text->aszHelp1 && text->aszHelp1[0]) {
  3265.         txHelpOpen(text,text->aszHelp1);
  3266.     } else if (iHelp == 1 && text->aszHelp2 && text->aszHelp2[0]) {
  3267.         txHelpOpen(text,text->aszHelp2);
  3268.     } else {
  3269.         information("外部ヘルプを参照するには、「文書の設定|ヘルプ」で設定してください");
  3270.     }
  3271. }
  3272.  
  3273. #endif    // !WINDOWSCE
  3274.  
  3275. //##辞書の参照
  3276. #if WINDOWSCE && !WINDOWSCE1
  3277.  
  3278. #include "_pwzreg.h"
  3279.  
  3280. static BOOL wordicGetFilenameExe(wchar* wszfilename)
  3281. {
  3282. #if __TXC__
  3283.     // DTonic.exeのフルパスをwszfilenameにセットしてください。
  3284.     wstrcpy(wszfilename,L"\\Windows\\DTonic.exe");
  3285.     return TRUE;
  3286. #else
  3287.     HKEY hkey;
  3288.     BOOL ret = FALSE;
  3289.     if (regOpenKey_W(HKEY_CURRENT_USER,L"Software\\EAST\\DTONIC\\Settings",&hkey) == ERROR_SUCCESS) {
  3290.         if (regQueryValue_W(hkey,L"ExePath",wszfilename,CCHPATHNAME) == ERROR_SUCCESS) {
  3291.             wpathSetDir(wszfilename);
  3292.             wpathSetFileName(wszfilename,L"DTonic.exe");
  3293. //winformation(wszfilename);
  3294.             ret = TRUE;
  3295.         }
  3296.         regCloseKey(hkey);
  3297.     }
  3298.     return ret;
  3299. #endif
  3300. }
  3301.  
  3302. BOOL wordicGetExist(void)
  3303. {
  3304. // 辞書があるかどうか調べる
  3305.     wchar wsz[CCHPATHNAME];
  3306.     return wordicGetFilenameExe(wsz);
  3307. }
  3308.  
  3309. static BOOL wordicGetExecute(void)
  3310. {
  3311. // 辞書ソフトが起動されているかどうか調べる
  3312. //WZ4.00Ba 990228 new
  3313.     HANDLE hMutex = CreateMutex(NULL,TRUE,L"DTONICBROWSER");
  3314.     BOOL ret = FALSE;
  3315.     if (hMutex) {
  3316.         if (GetLastError() == ERROR_ALREADY_EXISTS) {
  3317.             ret = TRUE;
  3318.             CloseHandle(hMutex);
  3319.         } else {
  3320.             CloseHandle(hMutex);
  3321.             ReleaseMutex(hMutex);
  3322.         }
  3323.     }
  3324.     return ret;
  3325. }
  3326.  
  3327. static void wordicRefer(void)
  3328. {
  3329. // 辞書ソフトが起動されている場合に、クリップボードの単語を検索するように指示
  3330. //WZ4.00Ba 990228 new
  3331.     UINT msg = RegisterWindowMessage(L"EAST DTONICCLASS");
  3332.     PostMessage(HWND_BROADCAST,msg,0,0);
  3333. }
  3334.  
  3335. static BOOL wordicExecRefer(void)
  3336. {
  3337. // 辞書ソフトを起動し、クリップボードの単語を検索するように指示
  3338. //WZ4.00Ba 990228 new
  3339.     wchar wsz[CCHPATHNAME];
  3340.     if (wordicGetFilenameExe(wsz)) {
  3341.         return WinExecEx_W(wsz,L"-SRCH");
  3342.     }
  3343.     return FALSE;
  3344. }
  3345.  
  3346. static void wordicSetWord(TX* text)
  3347. {
  3348. // 検索する単語をクリップボードにコピー
  3349. //WZ4.00Ba 990228 new
  3350.     if (txIsClipInPara(text)) {
  3351.         txSelectCopy(text);
  3352.     } else {
  3353.         mchar sz[CCHWORD];
  3354.         txGetWordAfterEx(text,sz,CCHWORD);
  3355.         {
  3356.             TX* text2 = textopen(NULL);
  3357.             txInsert(text2,sz);
  3358.             txSelectEx(text2,CLIP_ALL);
  3359.             txSelectCopy(text2);
  3360.             textclose(text2);
  3361.         }
  3362.     }
  3363. }
  3364.  
  3365. BOOL txDicWord(TX* text)
  3366. {
  3367. // カーソル位置の単語で辞書を検索する。
  3368. //WZ4.00Ba 990228 new
  3369.     wordicSetWord(text);
  3370.     if (wordicGetExecute()) {
  3371.         wordicRefer();
  3372.     } else {
  3373.         wordicExecRefer();
  3374.     }
  3375.     return TRUE;
  3376. }
  3377.  
  3378. #endif    // WINDOWSCE
  3379.  
  3380. //##文書の情報
  3381.  
  3382. enum {
  3383.     IDD_FILETYPE_CHANGE = 1000,
  3384.     IDD_RELOAD,
  3385.     IDD_CHARCODE,
  3386.     IDD_CRCODE,
  3387.     IDD_DATE,            //WZ4.00Bl 990915 
  3388.     IDD_DATE_CHANGE,    //WZ4.00Bl 990915 
  3389. };
  3390.  
  3391. void sprintFiletime(mchar* szbuff,FILETIME* filetime)
  3392. {
  3393.     FILETIME ft;
  3394.     SYSTEMTIME st;
  3395.     FileTimeToLocalFileTime(filetime,&ft);
  3396.     FileTimeToSystemTime(&ft,&st);
  3397.     sprintf(szbuff,"%2d/%2d/%2d %02d:%02d:%02d",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
  3398. }
  3399.  
  3400. void sprintFiletimeDate(mchar* szbuff,FILETIME* filetime)
  3401. {
  3402.     FILETIME ft;
  3403.     SYSTEMTIME st;
  3404.     FileTimeToLocalFileTime(filetime,&ft);
  3405.     FileTimeToSystemTime(&ft,&st);
  3406.     sprintf(szbuff,"%2d/%2d/%2d",st.wYear,st.wMonth,st.wDay);
  3407. }
  3408.  
  3409. void sprintFiletimeTime(mchar* szbuff,FILETIME* filetime)
  3410. {
  3411.     FILETIME ft;
  3412.     SYSTEMTIME st;
  3413.     FileTimeToLocalFileTime(filetime,&ft);
  3414.     FileTimeToSystemTime(&ft,&st);
  3415.     sprintf(szbuff,"%02d:%02d:%02d",st.wHour,st.wMinute,st.wSecond);
  3416. }
  3417.  
  3418. void sprintSizeKB(mchar* szbuff,IFILE size)
  3419. {
  3420.     sprintf(szbuff,"%ldKB (%ld バイト)",divmod(size,1024),size);
  3421. }
  3422.  
  3423. static NLINE txGetNlineall(TX* text,NPARA* pNparaAll)
  3424. {
  3425.     NLINE nlineAll;
  3426.     IFILE adr = txGetAddress(text);
  3427.     int ly = text->ly;
  3428.     int xbase = text->xbase;
  3429.     text->fNoCursor++;
  3430.     txSetUndisp(text);
  3431.     txJumpFileTop(text);
  3432.     text->fCountNline++;
  3433.     txJumpFileEnd(text);
  3434.     text->fCountNline--;
  3435.     if (pNparaAll) *pNparaAll = text->npara;
  3436.     nlineAll = text->nline;
  3437.     txJumpAddress(text,adr);
  3438.     txSetLy(text,ly);
  3439.     text->xbase = xbase;
  3440.     txFlushLx(text);
  3441.     txSetDisp(text);
  3442.     text->fNoCursor--;
  3443.     return nlineAll;
  3444. }
  3445.  
  3446. typedef struct {
  3447.     int nZenkaku;
  3448.     int nHankaku;
  3449. } COUNTCHARS;
  3450.  
  3451. static void CountChars(mchar* p,int size,COUNTCHARS* cc)
  3452. {
  3453. // pからsizeまでの内容をカウント
  3454.     while(size > 0) {
  3455.         mchar c = *p;
  3456.     #if TB_EUC
  3457.         if (iseuc(c)) {
  3458.             int l = eucGetCharSize(p);
  3459.             if (c == CHAR_EUC_KANA) {
  3460.                 cc->nHankaku++;
  3461.             } else if (!(c == 0xA1 && p[1] == 0xA1)) {    // ' '以外
  3462.                 cc->nZenkaku++;
  3463.             }
  3464.             size -= l;
  3465.             p += l;
  3466.         } else {
  3467.             if (c > ' ') {
  3468.                 cc->nHankaku++;
  3469.             }
  3470.             size--;
  3471.             p++;
  3472.         }
  3473.     #else
  3474.         if (iskanji(c)) {
  3475.             if (!(c == 0x81 && p[1] == 0x40)) {    // ' '以外
  3476.                 cc->nZenkaku++;
  3477.             }
  3478.             size -= 2;
  3479.             p += 2;
  3480.         } else {
  3481.             if (c > ' ') {
  3482.                 cc->nHankaku++;
  3483.             }
  3484.             size--;
  3485.             p++;
  3486.         }
  3487.     #endif
  3488.     }
  3489. }
  3490.  
  3491. static void txCountChars(TX* text,COUNTCHARS* cc)
  3492. {
  3493.     structClear(*cc);
  3494.     if (text->fHigh) {
  3495.         CountChars(text->buff,text->cur0,cc);
  3496.         CountChars(text->buff + text->cur,text->sizebuff - text->cur,cc);
  3497.     } else {
  3498.         CountChars(text->buff,text->curgap,cc);
  3499.         CountChars(text->buff + text->curpara,text->sizebuff - text->curpara,cc);
  3500.     }
  3501. }
  3502.  
  3503. static int kcConvertIndex(int kc,BOOL fToIndex)
  3504. {
  3505. //WZ3.90H 980927 EUC,JIS対応
  3506. #if WINDOWSCE
  3507.     #if 1//WZ4.00Ab 990118 PWZもEUC,JIS対応
  3508.     return kc;
  3509.     #else
  3510.     if (fToIndex) {
  3511.         switch(kc) {
  3512.             case KC_UNICODE: return 1;
  3513.             case KC_UNICODEBETA: return 2;
  3514.         }
  3515.         return 0;
  3516.     } else {
  3517.         switch(kc) {
  3518.             case 1: return KC_UNICODE;
  3519.             case 2: return KC_UNICODEBETA;
  3520.         }
  3521.         return KC_SJIS;
  3522.     }
  3523.     #endif
  3524. #else
  3525.     return kc;
  3526. #endif
  3527. }
  3528.  
  3529. #define IDD_NPARA    100
  3530. #define IDD_NLINE    101
  3531. #define IDD_NPAGE    102
  3532. #define IDD_CHARS    103
  3533.  
  3534. typedef struct {
  3535.     TX* text;
  3536.     BOOL fInitTextinfo;
  3537.     BOOL fReload;
  3538.     BYTE kcOpen;
  3539. } FILEINFO;
  3540.  
  3541. static int _ipageTextinfo;
  3542.  
  3543. static void txGetExt(TX* text,mchar szExt[CCHWORD])
  3544. {
  3545.     if (text->wszfilename[0]) {
  3546.         wstrtostr(wpathGetExt(text->wszfilename),-1,szExt,CCHWORD);
  3547.     } else if (text->pcc->wszExt[0]) {
  3548.         wstrtostr(text->pcc->wszExt,-1,szExt,CCHWORD);
  3549.     } else {
  3550.         szExt[0] = 0;
  3551.     }
  3552. }
  3553.  
  3554. #if WZFUNC_EMAIL||WZFUNC_MAILBASE
  3555. static void txMsghdrGetDateFiletime(TX* text,FILETIME* ft)
  3556. {
  3557.     mchar szDate[CCHWORD];
  3558.     {
  3559.         TEXTTOPEXIT context;
  3560.         txResetTexttopEnter(text,&context);
  3561.             txMsghdrGetString(text,"Date:",NULL,szDate,cchof(szDate));
  3562.         txResetTexttopExit(text,&context);
  3563.     }
  3564.     strToFiletime(szDate,strlen(szDate),ft,0);
  3565. }
  3566. #endif
  3567.  
  3568. BOOL CALLBACK dlgprocTextinfo(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  3569. {
  3570.     HDIALOG hd = dialogFromHwnd(hwnd);
  3571.     FILEINFO* context = dialogGetCustdata(hd);
  3572.     TX* text = context->text;
  3573.     switch(message) {
  3574.         case WM_TXDIALOG_PAGECHANGED: {
  3575.             _ipageTextinfo = wParam;
  3576.             if (wParam == 1 && !context->fInitTextinfo) {
  3577.                 //WCE0.93 970920 「文書の情報」文字数行数はオンデマンドで数える
  3578.                 mchar szbuff[120];
  3579.                 //
  3580.                 NPARA nparaAll;
  3581.                 NLINE nlineAll = txGetNlineall(text,&nparaAll);
  3582.                 sprintf(szbuff,"%ld行",nparaAll);
  3583.                 SetDlgItemText_A(hwnd,IDD_NPARA,szbuff);
  3584.                 //
  3585.                 sprintf(szbuff,"%ld行",nlineAll);
  3586.                 SetDlgItemText_A(hwnd,IDD_NLINE,szbuff);
  3587.                 if (text->height) {
  3588.                     sprintf(szbuff,"%ldページ",divmod(nlineAll,text->height));
  3589.                     SetDlgItemText_A(hwnd,IDD_NPAGE,szbuff);
  3590.                 }
  3591.                 {
  3592.                     COUNTCHARS cc;
  3593.                     txCountChars(text,&cc);
  3594.                     sprintf(szbuff,"全角%d文字、半角%d文字、計%d文字",cc.nZenkaku,cc.nHankaku,cc.nZenkaku+cc.nHankaku);
  3595.                     SetDlgItemText_A(hwnd,IDD_CHARS,szbuff);
  3596.                 }
  3597.                 //
  3598.                 context->fInitTextinfo = TRUE;
  3599.             }
  3600.             break;
  3601.         }
  3602.         case WM_COMMAND: {
  3603.             int cmd = GET_WM_COMMAND_CMD(wParam,lParam);
  3604.             int id = GET_WM_COMMAND_ID(wParam,lParam);
  3605.             switch(id) {
  3606.                 case IDD_RELOAD: {
  3607.                     int isel = ComboBox_GetCurSel(GetDlgItem(hwnd,IDD_CHARCODE));
  3608.                     mchar szCode[CCHWORD];
  3609.                     GetDlgItemText_A(hwnd,IDD_CHARCODE,szCode,CCHWORD);
  3610.                     if (question("文字コード「%s」として再読み込みします。\n%sよろしいですか?",szCode,text->fEdit ? "編集内容は失われます。\n" : "") == IDYES) {
  3611.                         context->fReload = TRUE;
  3612.                         context->kcOpen = isel;
  3613.                         PostMessage(GetParent(hwnd),WM_COMMAND,IDCANCEL,0);
  3614.                         return TRUE;
  3615.                     }
  3616.                     return TRUE;
  3617.                 }
  3618.                 #if !__TXC__
  3619.                 case IDD_FILETYPE_CHANGE: {
  3620.                     //PWZ2BETA0.3 980516 new
  3621.                     HDIALOG hd = dialog("拡張子の変更");
  3622.                     BOOL fNewfile = !text->wszfilename[0];
  3623.                     HSTRBLK sb = sbNewAllocEx(1024);
  3624.                     mchar szExt[CCHWORD];
  3625.                     txGetExt(text,szExt);
  3626.                     configtxMakeList(sb,MAKELIST_STRBLK|CFGLIST_EXT_NAME);
  3627.                     dialogControlStrblk(hd,sb);
  3628.                     dialogString(hd,"拡張子(&E):",10,szExt,cchof(szExt),20);
  3629.                     if (!fNewfile) {
  3630.                         dialogCaption(hd,"※ 実際のファイルの名前も変更します。");
  3631.                     }
  3632.                     if (dialogOpen(hd)) {
  3633.                         if (szExt[0] != '.') {
  3634.                             information("%s の指定は間違っています\n . から始まる拡張子を指定してください",szExt);
  3635.                         } else {
  3636.                             BOOL fOK = FALSE;
  3637.                             wchar *wszExt;
  3638.                             mchar* p = strstr(szExt," (");
  3639.                             if (p) *p = 0;    // " (name)"を取り除く
  3640.                             wszExt = wstrdupA(szExt);
  3641.                             if (!fNewfile) {
  3642.                                 BOOL fExist = fileIsExistW(text->wszfilename);
  3643.                                 wchar wsz[CCHPATHNAME];
  3644.                                 //
  3645.                                 wstrcpy(wsz,text->wszfilename);
  3646.                                 wpathSetExt(wsz,wszExt);
  3647.                                 //
  3648.                                 txFileLoadAllUnlock(text);
  3649.                                 //
  3650.                                 if (fileIsExistW(wsz)) {
  3651.                                     if (wquestionNoYes(L"%sは存在します。上書きしますか?",wsz) == IDNO) {
  3652.                                     } else {
  3653.                                         if (fExist) {
  3654.                                             if (CopyFile_W(text->wszfilename,wsz,FALSE)) {
  3655.                                                 DeleteFile_W(text->wszfilename);
  3656.                                                 fOK = TRUE;
  3657.                                             } else {
  3658.                                                 ////err
  3659.                                             }
  3660.                                         } else {
  3661.                                             fOK = TRUE;
  3662.                                         }
  3663.                                     }
  3664.                                 } else {
  3665.                                     if (fExist) {
  3666.                                         if (MoveFile_W(text->wszfilename,wsz)) {
  3667.                                             fOK = TRUE;
  3668.                                         } else {
  3669.                                             ////err
  3670.                                         }
  3671.                                     } else {
  3672.                                         fOK = TRUE;
  3673.                                     }
  3674.                                 }
  3675.                                 if (fOK) {
  3676.                                     wstrcpy(text->wszfilename,wsz);
  3677.                                     histAddW(HIST_FILE,wsz);
  3678.                                     txFileLockModal(text);
  3679.                                 }
  3680.                             } else {
  3681.                                 if (text->pcc) {
  3682.                                     fOK = TRUE;
  3683.                                     wsstrcpy(text->pcc->wszExt,wszExt);
  3684.                                 }
  3685.                             }
  3686.                             free(wszExt);
  3687.                             if (fOK) {
  3688.                                 txConfigGet(text);
  3689.                                 if (fNewfile && text->fTxfEnable && text->fFrame && txGetTextSize(text) == 0) {//PWZ2BETA0.6 980619 fFrameのチェックを追加
  3690.                                     //PWZ2BETA0.5 980617 新規作成のTMLにヘッダを埋め込むようにした
  3691.                                     txSetTml(text);
  3692.                                     text->fEdit = FALSE;
  3693.                                     txFlushTexttop(text);
  3694.                                 } else {//PWZ2BETA0.9A 980623 .TMLからの拡張子変更の処理を改善
  3695.                                     if (!text->fTxfEnable) {
  3696.                                         if (text->texttop) {
  3697.                                             txResetTexttop(text);
  3698.                                         }
  3699.                                         text->fTxf = FALSE;
  3700.                                     }
  3701.                                 }
  3702.                                 txFlush(text);
  3703.                                 txDoCaption(text);
  3704.                             }
  3705.                             // close
  3706.                             PostMessage(GetParent(hwnd),WM_COMMAND,IDCANCEL,0);
  3707.                         }
  3708.                     }
  3709.                     sbDelete(sb);
  3710.                     break;
  3711.                 }
  3712.                 #endif // !__TXC__
  3713.                 #if (WZFUNC_EMAIL||WZFUNC_MAILBASE) && !__TXC__
  3714.                 case IDD_DATE_CHANGE: {    //WZ4.00Bl 990915 
  3715.                     #if WZFUNC_MAILBASE
  3716.                     txuiMaileditSetDate(text);
  3717.                     #else
  3718.                     txMaileditSetDateNow(text);
  3719.                     #endif
  3720.                     {
  3721.                         FILETIME ft;
  3722.                         mchar szbuff[CCHWORD];
  3723.                         txMsghdrGetDateFiletime(text,&ft);
  3724.                         sprintFiletime(szbuff,&ft);
  3725.                         SetDlgItemText_A(hwnd,IDD_DATE,szbuff);
  3726.                     }
  3727.                     break;
  3728.                 }
  3729.                 #endif
  3730.             }
  3731.             break;
  3732.         }
  3733.     }
  3734.     return FALSE;
  3735. }
  3736.  
  3737. static void dialogIndentClm(HDIALOG hd)
  3738. {
  3739.     if (_pspc) {
  3740.         dialogLF(hd);
  3741.         dialogSetPosLX(hd,4);
  3742.     } else {
  3743.         dialogSetPosLX(hd,12);
  3744.     }
  3745. }
  3746.  
  3747. static BOOL _txIDM_UIINFO(TX* text)
  3748. {
  3749.     HDIALOG hd0 = dialog("文書の情報");
  3750.     HDIALOG hd;
  3751.     MAILEDIT* mailedit = text->mailedit;
  3752.     mchar szfilename[CCHPATHNAME];
  3753.     mchar szbuff[120];
  3754.     mchar szSubject[CCHWORD];
  3755.     BYTE ikc = kcConvertIndex(text->kcSave,TRUE);
  3756.     FILEINFO context;
  3757.     structClear(context);
  3758.     context.text = text;
  3759.     dialogSetCustdata(hd0,&context);
  3760.     dialogSetDlgproc(hd0,dlgprocTextinfo);
  3761.     dialogSetStartPage(hd0,_ipageTextinfo);
  3762.     //
  3763.     hd = dialog("ファイル");
  3764.     //WZ3.90I 981017 TMLだけダイアログページを増やすのは使いにくかった
  3765.     if (text->fTML) {
  3766.         txfGetSubject(text,szSubject,CCHWORD);
  3767.         dialogString(hd,"タイトル(&T):",11,szSubject,CCHWORD,34);
  3768.     }
  3769.     dialogSetH(hd);
  3770.     //PWZ2BETA0.3 980515 
  3771.     {
  3772.         dialogCaption(hd,"拡張子");
  3773.         dialogIndentClm(hd);
  3774.         txGetExt(text,szbuff);
  3775.         if (szbuff[0] == 0) strcpy(szbuff,"(なし)");
  3776.         if (text->szEditor[0]) {
  3777.             sstrcat(szbuff," (");sstrcat(szbuff,text->szEditor);sstrcat(szbuff,")");
  3778.         }
  3779.         dialogCaptionDynamic(hd,szbuff,20-_pspc*5);
  3780.         #if !__TXC__
  3781.         if (!text->mailedit) {    //PWZ2BETA0.8 980622 MAIL EDITORでは「ファイル|文書の情報」で拡張子を変更できないようにした
  3782.             dialogControlID(hd,IDD_FILETYPE_CHANGE);
  3783.             dialogPushbutton(hd,"変更(&E)...",10);
  3784.         }
  3785.         #endif // !__TXC__
  3786.         dialogLF(hd);
  3787.     }
  3788.     //
  3789.     if (text->wszfilename[0]) {
  3790.         WIN32_FIND_DATAW ffd;
  3791.         {
  3792.             HANDLE hfind = FindFirstFile_W(text->wszfilename,&ffd);
  3793.             if (hfind != INVALID_HANDLE_VALUE) {
  3794.                 FindClose(hfind);
  3795.             }
  3796.         }
  3797.         wstrtostr(text->wszfilename,-1,szfilename,CCHPATHNAME);
  3798.         //
  3799.         dialogCaption(hd,"ファイル名");
  3800.         dialogIndentClm(hd);
  3801.         dialogCaptionDynamic(hd,pathGetFileName(szfilename),50-_pspc*23);
  3802.             dialogLF(hd);
  3803.         dialogCaption(hd,"フルパス名");
  3804.         dialogIndentClm(hd);
  3805.         dialogCaptionDynamicEx(hd,szfilename,50-_pspc*23,2);//WCE0.91 970911 30*1->50*2に拡大
  3806.             dialogLF(hd);
  3807.         dialogCaption(hd,"サイズ");
  3808.         dialogIndentClm(hd);
  3809.         sprintSizeKB(szbuff,text->sizefileReal);
  3810.         dialogCaptionDynamic(hd,szbuff,30-_pspc*3);
  3811.             dialogLF(hd);
  3812.         if (text->mailedit) {    //WZ4.00Bl 990915 MAIL/NOTE EDITORの「ファイル|文書の情報」の日付の表示を改良。
  3813.         #if WZFUNC_EMAIL||WZFUNC_MAILBASE
  3814.             FILETIME ft;
  3815.             txMsghdrGetDateFiletime(text,&ft);
  3816.             dialogCaption(hd,"日付:");
  3817.             dialogIndentClm(hd);
  3818.             sprintFiletime(szbuff,&ft);
  3819.             dialogControlID(hd,IDD_DATE);
  3820.             dialogCaptionDynamic(hd,szbuff,30);
  3821.             #if !__TXC__
  3822.             //WZ4.00Bl 990915 MAIL/NOTE EDITORの「ファイル|文書の情報」で現在の日付に変更できるようにした。
  3823.             dialogControlID(hd,IDD_DATE_CHANGE);
  3824.             dialogPushbutton(hd,"変更(&E)",8);
  3825.             #endif // !__TXC__
  3826.             dialogLF(hd);
  3827.         #endif
  3828.         } else {
  3829.             #if !WINDOWSCE && !UNIX    // CEでは未サポート
  3830.             //WZ4.00Ac 990206 「文書の情報」で、作成日を表示するようにした。
  3831.             dialogCaption(hd,"作成日");
  3832.             dialogIndentClm(hd);
  3833.             sprintFiletime(szbuff,&ffd.ftCreationTime);
  3834.             dialogCaptionDynamic(hd,szbuff,30);
  3835.             dialogLF(hd);
  3836.             #endif
  3837.             if (fileIsExistW(text->wszfilename)) {
  3838.                 dialogCaption(hd,"更新日");
  3839.                 dialogIndentClm(hd);
  3840.                 sprintFiletime(szbuff,&text->timeFile);
  3841.                 dialogCaptionDynamic(hd,szbuff,30-_pspc*3);
  3842.                     dialogLF(hd);
  3843.                 #if 0    // 参照日は表示しても意味がない。
  3844.                 dialogCaption(hd,"参照日");
  3845.                 dialogIndentClm(hd);
  3846.                 sprintFiletime(szbuff,&ffd.ftLastAccessTime);
  3847.                 dialogCaptionDynamic(hd,szbuff,30);
  3848.                 dialogLF(hd);
  3849.                 #endif
  3850.                 #if UNIX
  3851.                 dialogCaption(hd,"アクセス権");
  3852.                 dialogIndentClm(hd);
  3853.                 sprintFilemask(szbuff,ffd.st_mode);
  3854.                 dialogCaptionDynamic(hd,szbuff,30);
  3855.                     dialogLF(hd);
  3856.                 #endif
  3857.             } else {
  3858.                 //WCE0.94 970922 存在しないファイルを開いたときは、「文書の情報」で、「ファイルは存在していません」を表示。
  3859.                 dialogCaption(hd,"ファイルは存在していません");
  3860.             }
  3861.         }
  3862.     } else {
  3863.         dialogCaption(hd,"(まだファイルに保存されていません)");//WCE0.93 970919 
  3864.     }
  3865.     dialogAddPage(hd0,hd);
  3866.     //
  3867.     hd = dialog("文書サイズ");
  3868.     dialogSetCaptionNoLfPSPC(hd,TRUE);
  3869.     {
  3870.         dialogSetH(hd);
  3871.         //
  3872.         dialogCaption(hd,"サイズ");
  3873.         dialogIndentClm(hd);
  3874.         sprintSizeKB(szbuff,txGetTextSize(text));
  3875.         dialogCaptionDynamic(hd,szbuff,30);
  3876.         dialogLF(hd);
  3877.         dialogCaption(hd,"段落数");
  3878.         dialogIndentClm(hd);
  3879.         dialogControlID(hd,IDD_NPARA);
  3880.         dialogCaptionDynamic(hd,NULL,30);
  3881.         dialogLF(hd);
  3882.         dialogCaption(hd,"行数");
  3883.         dialogIndentClm(hd);
  3884.         dialogControlID(hd,IDD_NLINE);
  3885.         dialogCaptionDynamic(hd,NULL,40);
  3886.         dialogLF(hd);
  3887.         if (text->height) {
  3888.             dialogCaption(hd,"ページ数");
  3889.             dialogIndentClm(hd);
  3890.             dialogControlID(hd,IDD_NPAGE);
  3891.             dialogCaptionDynamic(hd,NULL,40);
  3892.             dialogLF(hd);
  3893.         }
  3894.         //
  3895.         dialogControlID(hd,IDD_CHARS);
  3896.         dialogCaptionDynamic(hd,NULL,55);
  3897.     }
  3898.     dialogAddPage(hd0,hd);
  3899.     //WCE0.93 970919 「文書の情報」ダイアログに「文字コード」タブを追加
  3900.     hd = dialog("文字コード");
  3901.     {
  3902.         //WZ3.90H 980927 「文書の情報」で文字コードを指定した再読み込みをサポート
  3903.         //WZ4.00Bl 990916 (PWZ)「文書の情報」で文字コードを指定した再読み込みをサポート。ユーザ要望(SJISとEUCの認識に失敗した場合に困る)
  3904.         dialogSetH(hd);
  3905.         dialogControlID(hd,IDD_CHARCODE);
  3906.         dialogControlHelp(hd,240);
  3907.         dialogChoiceB(hd,"文字コード(&C):",14,&ikc,20,"シフトJIS","JIS","EUC","Unicode","Unicodeベタ",NULL);
  3908.         dialogLFIndentPSPC(hd,14);    //WZ4.00Ea 001127 
  3909.         dialogControlID(hd,IDD_RELOAD);
  3910.         dialogControlHelp(hd,239);
  3911.         dialogCmd(hd,"再読み込み(&R)...",16);
  3912.         dialogLFSetV(hd);
  3913.             dialogSpaceV(hd);
  3914.         #if UNIX
  3915.         dialogControlHelp(hd,240);
  3916.         dialogChoiceB(hd,"改行コード(&P):",14,&text->crSave,20,"Windowsファイル(CR+LF)","MACファイル(CR)","標準(LF)",NULL);//WZ3.90J 981109 
  3917.         #else
  3918.         dialogControlHelp(hd,240);
  3919.         dialogChoiceB(hd,"改行コード(&P):",14,&text->crSave,20,"標準(CR+LF)","MACファイル(CR)","UNIXファイル(LF)",NULL);//WZ3.90J 981109 
  3920.         #endif
  3921.         dialogControlHelp(hd,240);
  3922.         dialogChoiceB(hd,"EOFコード(&E):",14,&text->fAppendEof,20,"なし","あり",NULL);//WZ3.90J 981110 
  3923.     }
  3924.     dialogAddPage(hd0,hd);
  3925.     //
  3926.     if (dialogOpen(hd0)) {
  3927.         text->kcSave = kcConvertIndex(ikc,FALSE);
  3928.         //PWZ2BETA0.3 980515 
  3929.         if (text->fTML) {
  3930.             TEXTTOPEXIT context;
  3931.             txResetTexttopEnter(text,&context);
  3932.                 txMsghdrSet(text,"Subject:",szSubject);
  3933.             txResetTexttopExit(text,&context);
  3934.             //
  3935.             txDoCaption(text);
  3936.         }
  3937.         return TRUE;
  3938.     }
  3939.     if (context.fReload) {
  3940.         text->pcc->fKcOpen = TRUE;
  3941.         text->pcc->kcOpen = context.kcOpen;
  3942.         txReopenInternalExW(text,NULL,0,text->pcc);
  3943.         return FALSE;
  3944.     }
  3945.     return FALSE;
  3946. }
  3947.  
  3948. BOOL txIDM_UIINFO(TX* text)
  3949. {
  3950. //    if (text->fMemo) return FALSE;    //WZ4.00Dd 000601 
  3951.     if (!text->fFrame) return FALSE;    //WZ4.00Eb 001223 GREP等でIDM_UIINFOできないようにした。
  3952.     return _txIDM_UIINFO(text);
  3953. }
  3954.  
  3955. //##見出しスタイル
  3956.  
  3957. #if WZFUNC_HEADLINECONVERT
  3958.  
  3959. //WZ4.00Be 990512 PWZ:テキストの変換に見出しの変換機能を追加。
  3960. #define HEADLINECONVERT_SUBWIN    WINDOWSCE    //WZ4.00Be 990512 サブウィンドウ表示?
  3961.  
  3962. static mchar _szfilenameCfg[] = "HEAD";
  3963. static mchar _szStyle0[CCHWORD];
  3964.  
  3965. static void headstyle_txMsghdrGetset(TX* text,HEADLINE_SET* head,BOOL fSet)
  3966. {
  3967.     int i;
  3968.     for (i = 0;i < HEADLINE_N;i++) {
  3969.         mchar sz[] = {'H',i + '1',':',0};
  3970.         txMsghdrGetsetString(text,sz,head->t[i].sz,CCHHEADLINE,fSet);
  3971.     }
  3972.     if (!fSet) {
  3973.         int i;
  3974.         for (i = 0;i < HEADLINE_N;i++) {
  3975.             head->t[i].fDelete = FALSE;
  3976.         }
  3977.     }
  3978. }
  3979.  
  3980. static void styleArgInit(STYLESHEETARG* arg,HEADLINE_SET* context)
  3981. {
  3982.     structClear(*arg);
  3983.     arg->szfilenameCfg = _szfilenameCfg;
  3984.     arg->txMsghdrGetset = headstyle_txMsghdrGetset;
  3985.     arg->appContext = context;
  3986.     #if __TXC__
  3987.     arg->fTXC = TRUE;
  3988.     #endif
  3989. }
  3990.  
  3991. int headline_uistyle(HEADLINE_SET* context)
  3992. {
  3993.     STYLESHEETARG arg;
  3994.     styleArgInit(&arg,context);
  3995.     return stylesheet_uiMente(&arg,_szStyle0);
  3996. }
  3997.  
  3998. static BOOL styleLoad(mchar* szStyle,HEADLINE_SET* context)
  3999. {
  4000.     STYLESHEETARG arg;
  4001.     styleArgInit(&arg,context);
  4002.     return stylesheet_Load(&arg,szStyle);
  4003. }
  4004.  
  4005. static BOOL styleSave(mchar* szStyle,HEADLINE_SET* context)
  4006. {
  4007.     STYLESHEETARG arg;
  4008.     styleArgInit(&arg,context);
  4009.     return stylesheet_Save(&arg,szStyle);
  4010. }
  4011.  
  4012. #endif    // WZFUNC_HEADLINECONVERT
  4013.  
  4014. //##テキストの変換
  4015. //WZ3.90K 981113 new
  4016.  
  4017.  
  4018. enum {
  4019.     IDD_LIST2 = 100,IDD_HEADLINE_SRCMENU,IDD_HEADLINE_DSTMENU,
  4020.     IDD_CONVERTHEADLINE_SRC,IDD_CONVERTHEADLINE_DST,    //WZ4.00Be 990512 
  4021.     IDD_HEADLINE_SRC = 1000,
  4022.     IDD_HEADLINE_SRCDEL = 1050,
  4023.     IDD_HEADLINE_DST = 1100,
  4024. };
  4025. #if WZFUNC_EDITOR
  4026. static mchar* _tszCt[] = {    // CT_xxxの値と対応。
  4027.     "プレーンテキスト","改行付きテキスト",
  4028. //    "記号付きテキスト",    // 要らないだろう。
  4029.     "体裁認識テキスト",
  4030.     #if WZFUNC_HTMLHIGH
  4031.     "HTMLテキスト",
  4032.     #endif
  4033.     "TMLテキスト","ワープロ用テキスト",
  4034.     "体裁認識(PWZ2.00以前)","タブ体裁(PWZ)",NULL,
  4035. };
  4036. #else
  4037. static mchar* _tszCt[] = {    // CT_xxxの値と対応。
  4038.     "プレーンテキスト","改行付きテキスト","TMLテキスト",
  4039.     NULL,
  4040. };
  4041. #endif
  4042.  
  4043. #if 0
  4044. static BOOL txIsSymbolFront(TX* text)
  4045. {
  4046. // textの段落先頭からカーソル位置の手前までが記号だけでできているかどうか返す
  4047. //WZ3.90K 981113 new
  4048.     mchar* p = text->buff + text->curpara;
  4049.     mchar* pEnd = text->buff + text->cur0;
  4050.     while(p < pEnd) {
  4051.         int ct = GetCharType(text,p);
  4052.         if (ct == CT_SYMBOL || ct == CT_SPACE) {
  4053.         } else {
  4054.             return FALSE;
  4055.         }
  4056.         p += txGetCharSize(text,p);
  4057.     }
  4058.     return TRUE;
  4059. }
  4060. #endif
  4061.  
  4062. typedef struct tagContextConverttext {
  4063.     TX* text;
  4064.     int ctSrc;
  4065.     int ctDst;
  4066.     HEADLINE_SET headSrc;
  4067.     HEADLINE_SET headDst;
  4068.     BOOL fKeep;    //WZ4.00Ac 990206 前回の条件を再現
  4069. } DIALOG_CONVERTTEXT;
  4070. #if WZFUNC_HEADLINECONVERT
  4071.     #if WZFUNC_HTMLHIGH    //WZ4.00Be 990512 
  4072.         #define ctIsNoHeadline(ct) (ct == CT_HTML || ct == CT_TML)    // 見出し文字列を持たない?
  4073.     #else
  4074.         #define ctIsNoHeadline(ct) (ct == CT_TML)    // 見出し文字列を持たない?
  4075.     #endif
  4076. #endif
  4077.  
  4078. #if WZFUNC_HEADLINECONVERT
  4079. static void dialogAddHeadlineConverttext(HDIALOG hd,DIALOG_CONVERTTEXT* context,BOOL fDst)
  4080. {
  4081.     int i;
  4082.     HEADLINE_SET* head = fDst ? &context->headDst : &context->headSrc;
  4083.     #if !HEADLINECONVERT_SUBWIN
  4084.     dialogSetPosY(hd,dialogGetPosY(hd) - DTCY + UNIX*DTCY);
  4085.     dialogSetPosLF(hd);
  4086.     #endif
  4087.     dialogSetH(hd);
  4088.     if (fDst) {
  4089.         dialogSetPosLX(hd,6);
  4090.         dialogControlID(hd,IDD_HEADLINE_DSTMENU);dialogPushbutton(hd,"見出し(&M)...",10+_pspc*2+SFF*2);    //WZ4.00Be 990512 &W->&L
  4091.     } else {
  4092.         dialogSetPosLX(hd,3);
  4093.         dialogControlID(hd,IDD_HEADLINE_SRCMENU);dialogPushbutton(hd,"見出し(&L)...",10+_pspc*2+SFF*2);    //WZ4.00Be 990512 &E->&M
  4094.     }
  4095.     if (!fDst) {dialogSetPosLX(hd,16);hd->dtyAdd = DTCYINT;dialogCaption(hd,"削除:");}
  4096.     dialogLF(hd);
  4097.     dialogSetIntXY(hd,0,0);
  4098.     for (i = 0;i < HEADLINE_N;i++) {
  4099.         mchar sz[CCHWORD];
  4100.         if (fDst) {
  4101.             #if HEADLINECONVERT_SUBWIN
  4102.             sprintf_A(sz,"&%d:",i + 1);
  4103.             #else
  4104.             if (i == 0) {
  4105.                 strcpy(sz,"1(&A):");
  4106.             } else {
  4107.                 sprintf_A(sz,"%d:",i + 1);
  4108.             }
  4109.             #endif
  4110.             dialogControlID(hd,IDD_HEADLINE_DST + i);
  4111.             dialogString(hd,sz,5,head->t[i].sz,CCHHEADLINE,14);
  4112.         } else {
  4113.             sprintf_A(sz,"&%d:",i + 1);
  4114.             dialogControlID(hd,IDD_HEADLINE_SRC + i);
  4115.             dialogString(hd,sz,2,head->t[i].sz,CCHHEADLINE,14);
  4116.             //
  4117.             dialogControlID(hd,IDD_HEADLINE_SRCDEL + i);
  4118.             dialogCheckB(hd,NULL,&head->t[i].fDelete);
  4119.         }
  4120.         dialogLF(hd);
  4121.     }
  4122.     dialogSetV(hd);
  4123.     dialogResetInt(hd);
  4124. }
  4125. static void cmdprocConvertText(HWND hwnd,DIALOG_CONVERTTEXT* context,int id)
  4126. {
  4127.     HWND hctrl = GetDlgItem(hwnd,id);
  4128.     HDIALOG hd = dialogFromHwnd(hwnd);
  4129.     TX* text = context->text;
  4130.     switch(id) {
  4131.         case IDD_HEADLINE_SRCMENU:
  4132.         case IDD_HEADLINE_DSTMENU: {
  4133.             enum {IDD_H_STD=100,IDD_H_CLEAR,IDD_H_TEXT,IDD_H_STYLE};
  4134.             BOOL fDst = (id == IDD_HEADLINE_DSTMENU);
  4135.             HEADLINE_SET* head = (fDst) ? &context->headDst : &context->headSrc;
  4136.             HMENU hmenu = menuNew();
  4137.             int cmd;
  4138.             RECT r;
  4139.             SetFocus(GetDlgItem(hwnd,fDst ? IDD_HEADLINE_DST : IDD_HEADLINE_SRC));
  4140.             GetWindowRect(hctrl,&r);
  4141.             menuStr(hmenu,"標準の見出し文字(&S)",IDD_H_STD);
  4142.             menuStr(hmenu,"この文書の見出し文字(&T)",IDD_H_TEXT);
  4143.             menuStr(hmenu,"スタイル(&Q)...",IDD_H_STYLE);
  4144.             menuStr(hmenu,"クリア(&Z)",IDD_H_CLEAR);
  4145.             cmd = menuOpenEx(hmenu,MENU_CMD,r.left,r.bottom,hwnd);
  4146.             menuDelete(hmenu);
  4147.             dialogRead(hd);
  4148.             switch(cmd) {
  4149.                 case IDD_H_STYLE: {
  4150.                     if (headline_uistyle(head) == IDOK) {
  4151.                         dialogWrite(hd);
  4152.                     }
  4153.                     break;
  4154.                 }
  4155.                 case IDD_H_STD: {
  4156.                     int i;
  4157.                     for (i = 0;i < HEADLINE_N;i++) {
  4158.                         int n = i + 1;
  4159.                         mchar* dst = head->t[i].sz;
  4160.                         while(n--) *dst++ = '.';
  4161.                         *dst = 0;
  4162.                         if (!fDst) head->t[i].fDelete = TRUE;
  4163.                     }
  4164.                     dialogWrite(hd);
  4165.                     break;
  4166.                 }
  4167.                 case IDD_H_TEXT: {
  4168.                     int i;
  4169.                     for (i = 0;i < HEADLINE_N;i++) {
  4170.                         txHeadlineGet(text,i,head->t[i].sz);
  4171.                         if (!fDst) head->t[i].fDelete = FALSE;
  4172.                     }
  4173.                     dialogWrite(hd);
  4174.                     break;
  4175.                 }
  4176.                 case IDD_H_CLEAR: {
  4177.                     int i;
  4178.                     for (i = 0;i < HEADLINE_N;i++) {
  4179.                         head->t[i].sz[0] = 0;
  4180.                         if (!fDst) head->t[i].fDelete = FALSE;
  4181.                     }
  4182.                     dialogWrite(hd);
  4183.                     break;
  4184.                 }
  4185.             }
  4186.             break;
  4187.         }
  4188.     }
  4189. }
  4190. static void convertHeadlineSetEnable(HWND hwndBase,int id,HWND hwndTarget)
  4191. {
  4192.     HWND hctrl = GetDlgItem(hwndBase,id);
  4193.     int ct = ListBox_GetCurSel(hctrl);
  4194.     BOOL fEnable = !ctIsNoHeadline(ct);
  4195.     int i;
  4196.     for (i = 0;i < HEADLINE_N;i++) {
  4197.         EnableDlgItem(hwndTarget,IDD_HEADLINE_SRC+i,fEnable);
  4198.     }
  4199. }
  4200.  
  4201. BOOL CALLBACK dlgprocConvertHeadline(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  4202. {
  4203. //WZ4.00Be 990512 new
  4204.     HDIALOG hd = dialogFromHwnd(hwnd);
  4205.     DIALOG_CONVERTTEXT* context = dialogGetCustdata(hd);
  4206.     switch(message) {
  4207.         case WM_INITDIALOG: {
  4208.             convertHeadlineSetEnable(GetParent(hwnd),IDD_LIST,hwnd);
  4209.             break;
  4210.         }
  4211.         case WM_COMMAND: {
  4212.             int id = GET_WM_COMMAND_ID(wParam,lParam);
  4213.             cmdprocConvertText(hwnd,context,id);
  4214.             break;
  4215.         }
  4216.     }
  4217.     return FALSE;
  4218. }
  4219. #endif
  4220.  
  4221. int txGetCT(TX* text)
  4222. {
  4223.     if (text->fTxf || text->fTxfEnable) return CT_TML;
  4224.     switch(text->filekind) {
  4225.         case TEXT_PLAIN: return CT_PLAINTEXT;
  4226. #if WZFUNC_EDITOR
  4227.         #if WZFUNC_TABBEAM
  4228.         case TEXT_APFU: return CT_AUTOFORMTEXT;
  4229.         case TEXT_DOCUMENT: return CT_AUTOFORMTEXT;
  4230.         #else
  4231.         case TEXT_APFU: return CT_AUTOFORMTEXTOLD;
  4232.         case TEXT_DOCUMENT: return CT_TABFORMTEXT;
  4233.         #endif
  4234. #endif
  4235.         case TEXT_WZ: return CT_TML;
  4236.         #if WZFUNC_HTMLHIGH
  4237.         case TEXT_HTML: return CT_HTML;
  4238.         case TEXT_XML: return CT_HTML;
  4239.         #endif
  4240.         case TEXT_TEXT: return CT_PLAINTEXT;
  4241.         case TEXT_PROGRAM: return CT_PLAINTEXT;
  4242.     }
  4243.     return CT_PLAINTEXT;
  4244. }
  4245.  
  4246. BOOL CALLBACK dlgprocConvertText(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  4247. {
  4248.     HDIALOG hd = dialogFromHwnd(hwnd);
  4249.     DIALOG_CONVERTTEXT* context = dialogGetCustdata(hd);
  4250.     TX* text = context->text;
  4251.     switch(message) {
  4252.         case WM_INITDIALOG: {
  4253.             HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
  4254.             HWND hctrl2 = GetDlgItem(hwnd,IDD_LIST2);
  4255.             {
  4256.                 mchar** p = _tszCt;
  4257.                 for (;*p;p++) {
  4258.                     ListBox_AddString_A(hctrl,*p);
  4259.                     ListBox_AddString_A(hctrl2,*p);
  4260.                 }
  4261.             }
  4262.             {
  4263.                 if (context->fKeep) {
  4264.                     ListBox_SetCurSel(hctrl,context->ctSrc);
  4265.                     ListBox_SetCurSel(hctrl2,context->ctDst);
  4266.                 } else {
  4267.                     int ct = txGetCT(text);
  4268.                     ListBox_SetCurSel(hctrl,ct);
  4269.                     ListBox_SetCurSel(hctrl2,1);
  4270. #if __DEV__
  4271.     #if WZFUNC_HTMLHIGH
  4272.                     ListBox_SetCurSel(hctrl2,ct == CT_HTML ? 4 : 1);
  4273.     #else
  4274.                     ListBox_SetCurSel(hctrl2,1);
  4275.     #endif
  4276. #endif
  4277.                 }
  4278.                 FORWARD_WM_COMMAND(hwnd,IDD_LIST,hctrl,LBN_SELCHANGE,PostMessage);
  4279.             }
  4280.             break;
  4281.         }
  4282.         case WM_COMMAND: {
  4283.             int id = GET_WM_COMMAND_ID(wParam,lParam);
  4284.             int cmd = GET_WM_COMMAND_CMD(wParam,lParam);
  4285.             HWND hctrl = GET_WM_COMMAND_HWND(wParam,lParam);
  4286.             switch(id) {
  4287.                 case IDOK: {
  4288.                     HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
  4289.                     HWND hctrl2 = GetDlgItem(hwnd,IDD_LIST2);
  4290.                     context->ctSrc = ListBox_GetCurSel(hctrl);
  4291.                     context->ctDst = ListBox_GetCurSel(hctrl2);
  4292.                     break;
  4293.                 }
  4294.                 #if WZFUNC_HEADLINECONVERT
  4295.                 case IDD_LIST: {
  4296.                     if (cmd == LBN_SELCHANGE) {
  4297.                         #if 1//WZ4.00Be 990512 
  4298.                         convertHeadlineSetEnable(hwnd,id,hwnd);
  4299.                         #else
  4300.                         int ct = ListBox_GetCurSel(hctrl);
  4301.                         BOOL fEnable = !ctIsNoHeadline(ct);
  4302.                         int i;
  4303.                         for (i = 0;i < HEADLINE_N;i++) {
  4304.                             EnableDlgItem(hwnd,IDD_HEADLINE_SRC+i,fEnable);
  4305.                         }
  4306.                         #endif
  4307.                     }
  4308.                     break;
  4309.                 }
  4310.                 #endif
  4311.                 #if WZFUNC_HEADLINECONVERT && HEADLINECONVERT_SUBWIN
  4312.                 case IDD_CONVERTHEADLINE_SRC:
  4313.                 case IDD_CONVERTHEADLINE_DST: {
  4314.                     HDIALOG hd = dialog((id == IDD_CONVERTHEADLINE_SRC)?"変換元の見出し":"変換先の見出し");
  4315.                     hd->fCaptionOkBtn = FALSE;
  4316.                     dialogSetDlgproc(hd,dlgprocConvertHeadline);
  4317.                     dialogSetCustdata(hd,context);
  4318.                     dialogAddHeadlineConverttext(hd,context,(id == IDD_CONVERTHEADLINE_DST));
  4319. //                    dialogLFV(hd);dialogClose(hd,8);
  4320.                     dialogOpen(hd);
  4321.                     break;
  4322.                 }
  4323.                 #endif
  4324.             }
  4325.             #if WZFUNC_HEADLINECONVERT
  4326.             cmdprocConvertText(hwnd,context,id);    //WZ4.00Be 990512 
  4327.             #endif
  4328.             break;
  4329.         }
  4330.     }
  4331.     return FALSE;
  4332. }
  4333.  
  4334. BOOL txIDM_UICONVERTTEXT(TX* text)
  4335. {
  4336. // 次の場合に必要なので見出しの変換も付けた。
  4337. // テキストの見出しをTMLに変換する:"..."の場合は見出し文字を取りたい、
  4338. // 見出し文字を付けてないTMLをテキストに変換する:見出し文字を付けて変換したい。
  4339. // 受け取った著者原稿の正規化に必要な機能は、改行付きテキストのプレーンへの変換、見出しの認識、語句統一。
  4340.     static BBOOL _mode;
  4341.     HDIALOG hd;
  4342.     DIALOG_CONVERTTEXT context;
  4343.     BOOL ret = FALSE;
  4344.     int y;
  4345.     //
  4346.     if (!txGetEditable(text)) return FALSE;    //WZ4.00Ac 990206 
  4347.     //
  4348.     hd = dialog("テキストの変換");
  4349.     dialogSetDlgproc(hd,dlgprocConvertText);
  4350.     structClear(context);
  4351.     if (text->converttext) {context = *text->converttext;context.fKeep = TRUE;}
  4352.     context.text = text;
  4353.     dialogSetCustdata(hd,&context);
  4354.     //
  4355.     if (!WINDOWSCE || _pspc) {
  4356.         dialogControlRadioV(hd);
  4357.     }
  4358.     dialogChoiceRadioB(hd,&_mode,"クリップボードにコピー(&C)","テキストを直接変換(&T)",NULL);
  4359.     //
  4360.     dialogSpaceV(hd);dialogSpaceV(hd);
  4361.     dialogSetPosLF(hd);y = dialogGetPosY(hd);
  4362.     dialogControlID(hd,IDD_LIST);
  4363.     dialogAddListbox(hd,"変換元(&S):",22,6-_pspc*3);
  4364.     #if WZFUNC_HEADLINECONVERT
  4365.         #if HEADLINECONVERT_SUBWIN
  4366.             dialogSetPosY(hd,y-DTCY/3);dialogSetPosLX(hd,12);
  4367.             dialogControlID(hd,IDD_CONVERTHEADLINE_SRC);
  4368.             dialogPushbutton(hd,"見出し(&L)...",12-!_pspc*2);
  4369.         #else
  4370.             dialogAddHeadlineConverttext(hd,&context,FALSE);
  4371.         #endif
  4372.     #endif
  4373.     if (_pspc) {
  4374.         dialogLF(hd);
  4375.     } else {
  4376.         dialogLFV(hd);dialogSetPosY(hd,y);dialogSetPosLF(hd);
  4377.         dialogSetPosY(hd,dialogGetPosY(hd) + DTCY*5);dialogCaption(hd,"→");
  4378.         dialogLFV(hd);
  4379.     }
  4380.     dialogSetPosLF(hd);y = dialogGetPosY(hd);    //WZ4.00Be 990512 
  4381.     dialogControlID(hd,IDD_LIST2);
  4382.     dialogAddListbox(hd,"変換先(&E):",22,6-_pspc*3);
  4383.     #if WZFUNC_HEADLINECONVERT
  4384.         #if HEADLINECONVERT_SUBWIN
  4385.             dialogSetPosY(hd,y-DTCY/3);dialogSetPosLX(hd,12);
  4386.             dialogControlID(hd,IDD_CONVERTHEADLINE_DST);
  4387.             dialogPushbutton(hd,"見出し(&M)...",12-!_pspc*2);
  4388.         #else
  4389.             dialogAddHeadlineConverttext(hd,&context,TRUE);
  4390.         #endif
  4391.     #endif
  4392.     //
  4393.     if (dialogOpen(hd)) {
  4394.         if (context.ctSrc != context.ctDst) {
  4395.             if (!text->converttext) text->converttext = malloc(sizeof(DIALOG_CONVERTTEXT));
  4396.         #if __TXC__
  4397.             memcpy(text->converttext,&context,sizeof(DIALOG_CONVERTTEXT));
  4398.         #else
  4399.             //WZ4.00Ca 991201 TX-Cではこのコードはうまく動かない。
  4400.             if (text->converttext) *text->converttext = context;
  4401.         #endif
  4402.             #if WZFUNC_HEADLINECONVERT
  4403.             if (ctIsNoHeadline(context.ctSrc)) {
  4404.                 // この場合は見出しの変換をしないのでゼロクリアする。
  4405.                 HEADLINE_SET* head = &context.headSrc;
  4406.                 int i;
  4407.                 for (i = 0;i < HEADLINE_N;i++) {
  4408.                     head->t[i].sz[0] = 0;
  4409.                     head->t[i].fDelete = FALSE;
  4410.                 }
  4411.             }
  4412.             #endif
  4413.             txConvertText(text,context.ctSrc,context.ctDst,&context.headSrc,&context.headDst,!_mode);
  4414.         }
  4415.         ret = TRUE;
  4416.     }
  4417.     return ret;
  4418. }
  4419.  
  4420. //##文書校正・スペルチェック
  4421.  
  4422. #if !WINDOWSCE
  4423.  
  4424. typedef struct {
  4425. BYTE configTop;
  4426.     mchar szfilenameDic[CCHPATHNAME];
  4427.     BYTE kutoten;
  4428.     BYTE buntai;
  4429.     BYTE kanji_kana;
  4430.     BYTE kuten_brace;
  4431.     BYTE suffix_kana;
  4432.     BYTE reader;
  4433.     BYTE homophone;
  4434.     BYTE itaiji;
  4435.     BYTE ukemi;
  4436.     BYTE strong;
  4437.     BYTE sijisi;
  4438.     BYTE ranuki;
  4439.     BYTE hitei;
  4440.     BYTE josi_continue;
  4441.     BYTE digit_zenhan;
  4442.     BBOOL fWordStandardize;
  4443.     BYTE fCheckLongPara;
  4444.     WORD lcxLongPara;
  4445.     BBOOL fSpellCheck;
  4446.     mchar szfilenameSplchkUserDic[CCHPATHNAME];
  4447.     BBOOL fSplchkNoupper;
  4448.     BBOOL fSplchkNodigit;
  4449.     BBOOL fSplchkShort;    // nSplchkShort文字以下は無視
  4450.     BBOOL fSplchkClearTempDic;    // 一時辞書を削除してから検索
  4451.     BBOOL fSplchkCur;    // カーソル位置の単語のみを検索。
  4452.     BBOOL fSplchkNoUrl;    //WZ3.90L 981116 URLは無視
  4453.     BYTE nSplchkShort;
  4454. BYTE configEnd;
  4455. //
  4456.     TX* text;
  4457.     HSTRBLK sbSplchkTempDic;    // 一時辞書
  4458. // スペルチェック専用モード
  4459.     BOOL fSplchkMode;            // スペルチェック専用モード
  4460.     BOOL fSpellChecked;            // 調査を行った?
  4461. // 用語統一専用モード
  4462.     BOOL fReWording;
  4463. // 内部状態
  4464.     BOOL fSearching;
  4465.     int iSubitemSort;
  4466. } PROOF_DIALOG;
  4467.  
  4468. static mchar _szfilenameProofCfg[] = "PROOF";
  4469. static mchar _szStyle0[CCHWORD];
  4470. static mchar* _tszReplaced[] = {"","済"};
  4471. static BBOOL _fBreaked;
  4472. static HWND _hdlg;
  4473.  
  4474. static BOOL AbortProc(void)
  4475. {
  4476.     if (_hdlg) {
  4477.         MSG msg;
  4478.         while(!_fBreaked && PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
  4479.             if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) {
  4480.                 _fBreaked = TRUE;
  4481.                 break;
  4482.             }
  4483.             TranslateMessage(&msg);
  4484.             DispatchMessage(&msg);
  4485.         }
  4486.         return _fBreaked;
  4487.     }
  4488.     return FALSE;
  4489. }
  4490.  
  4491. static void txMsghdrGetsetProofStyle(TX* text,PROOF_DIALOG* context,BOOL fSet)
  4492. {
  4493.     txMsghdrGetsetIntB(text,"KUTOTEN:",&context->kutoten,fSet);
  4494.     txMsghdrGetsetIntB(text,"DEARU_DESUMASU:",&context->buntai,fSet);
  4495.     txMsghdrGetsetIntB(text,"KANJI_KANA:",&context->kanji_kana,fSet);
  4496.     txMsghdrGetsetIntB(text,"KUTEN_BRACE:",&context->kuten_brace,fSet);
  4497.     txMsghdrGetsetIntB(text,"SUFFIX_KANA:",&context->suffix_kana,fSet);
  4498.     txMsghdrGetsetIntB(text,"READER:",&context->reader,fSet);
  4499.     txMsghdrGetsetIntB(text,"HOMOPHONE:",&context->homophone,fSet);
  4500.     txMsghdrGetsetIntB(text,"ITAIJI:",&context->itaiji,fSet);
  4501.     txMsghdrGetsetIntB(text,"UKEMI:",&context->ukemi,fSet);
  4502.     txMsghdrGetsetIntB(text,"STRONG:",&context->strong,fSet);
  4503.     txMsghdrGetsetIntB(text,"SIJISI:",&context->sijisi,fSet);
  4504.     txMsghdrGetsetIntB(text,"RANUKI:",&context->ranuki,fSet);
  4505.     txMsghdrGetsetIntB(text,"HITEI:",&context->hitei,fSet);
  4506.     txMsghdrGetsetIntB(text,"JOSI_CONTINUE:",&context->josi_continue,fSet);
  4507.     txMsghdrGetsetIntB(text,"DIGIT_ZENHAN:",&context->digit_zenhan,fSet);
  4508.     txMsghdrGetsetIntB(text,"WS:",&context->fWordStandardize,fSet);
  4509.     txMsghdrGetsetString(text,"WSDIC:",context->szfilenameDic,cchof(context->szfilenameDic),fSet);
  4510.     txMsghdrGetsetIntB(text,"SPLCHK:",&context->fSpellCheck,fSet);
  4511.     txMsghdrGetsetString(text,"SPLCHK_USERDIC:",context->szfilenameSplchkUserDic,CCHPATHNAME,fSet);
  4512.     txMsghdrGetsetIntB(text,"SPLCHK_NOUPPER:",&context->fSplchkNoupper,fSet);
  4513.     txMsghdrGetsetIntB(text,"SPLCHK_NODIGIT:",&context->fSplchkNodigit,fSet);
  4514.     txMsghdrGetsetIntB(text,"SPLCHK_NOURL:",&context->fSplchkNoUrl,fSet);//WZ3.90L 981116 
  4515.     //
  4516.     if (!context->fSplchkShort) context->nSplchkShort = 0;
  4517.     txMsghdrGetsetIntB(text,"SPLCHK_NOSHORT:",&context->nSplchkShort,fSet);
  4518.     context->fSplchkShort = !!context->nSplchkShort;
  4519. }
  4520.  
  4521. static void proofstyleArgInit(STYLESHEETARG* arg,PROOF_DIALOG* context)
  4522. {
  4523.     structClear(*arg);
  4524.     arg->szfilenameCfg = _szfilenameProofCfg;
  4525.     arg->txMsghdrGetset = txMsghdrGetsetProofStyle;
  4526.     arg->appContext = context;
  4527.     #if __TXC__
  4528.     arg->fTXC = TRUE;
  4529.     #endif
  4530. }
  4531.  
  4532. static int uistyle(PROOF_DIALOG* context)
  4533. {
  4534.     STYLESHEETARG arg;
  4535.     proofstyleArgInit(&arg,context);
  4536.     return stylesheet_uiMente(&arg,_szStyle0);
  4537. }
  4538.  
  4539. static BOOL proofstyleLoad(mchar* szStyle,PROOF_DIALOG* context)
  4540. {
  4541.     STYLESHEETARG arg;
  4542.     proofstyleArgInit(&arg,context);
  4543.     return stylesheet_Load(&arg,szStyle);
  4544. }
  4545.  
  4546. static BOOL proofstyleSave(mchar* szStyle,PROOF_DIALOG* context)
  4547. {
  4548.     STYLESHEETARG arg;
  4549.     proofstyleArgInit(&arg,context);
  4550.     return stylesheet_Save(&arg,szStyle);
  4551. }
  4552.  
  4553. static void splchkOpenTempDic(PROOF_DIALOG* context)
  4554. {
  4555.     context->sbSplchkTempDic = historyOpen("splchkTempDic",8192);
  4556. }
  4557.  
  4558. static void splchkCloseTempDic(PROOF_DIALOG* context)
  4559. {
  4560.     if (context->sbSplchkTempDic) {
  4561.         historyClose("splchkTempDic",context->sbSplchkTempDic);
  4562.         context->sbSplchkTempDic = NULL;
  4563.     }
  4564. }
  4565.  
  4566. static int splchkExec(PROOF_DIALOG* context,LIST* list)
  4567. {
  4568.     mchar szfilenameDic[CCHPATHNAME];
  4569.     int ret = 0;
  4570.     TX* textDic = textopen(pathFullConfig(szfilenameDic,"spell.dic"));
  4571.     TX* textDicUser = context->szfilenameSplchkUserDic[0] ? textopen(context->szfilenameSplchkUserDic) : NULL;
  4572.     DWORD scmode = 0;
  4573.     if (context->fSplchkNoupper) scmode |= SPLCHK_NOUPPER;
  4574.     if (context->fSplchkNodigit) scmode |= SPLCHK_NODIGIT;
  4575.     if (context->fSplchkNoUrl) scmode |= SPLCHK_NOURL;
  4576.     if (context->fSplchkShort && context->nSplchkShort) scmode |= context->nSplchkShort;
  4577.     if (context->fSplchkClearTempDic) sbDelAll(context->sbSplchkTempDic);
  4578.     if (context->fSplchkCur) scmode |= SPLCHK_CUR;
  4579.     #if __TXC__
  4580.     scmode |= SPLCHK_TXC;
  4581.     #endif
  4582.     ret += txSpellCheck(context->text,textDic,textDicUser,context->sbSplchkTempDic,list,scmode,NULL);
  4583.     textclose(textDic);
  4584.     textclose(textDicUser);
  4585.     return ret;
  4586. }
  4587.  
  4588. static void dialogAddSpellCheck(HDIALOG hd,PROOF_DIALOG* context,BOOL fCommand)
  4589. {
  4590.     dialogSetCustdata(hd,context);
  4591. //
  4592.     dialogSetH(hd);
  4593. //    dialogControlID(hd,IDD_WSDIC);
  4594.     dialogControlRefer(hd,"*.dic");
  4595.     dialogControlHelp(hd,242);
  4596.     dialogString(hd,"ユーザ辞書(&U):",14,context->szfilenameSplchkUserDic,CCHPATHNAME,30);
  4597. //    dialogControlID(hd,IDD_WSEDIT);
  4598. //    dialogPushbutton(hd,"編集",5);
  4599.         dialogLFSetV(hd);
  4600.     dialogControlHelp(hd,243);
  4601.     dialogCheckB(hd,"全て大文字の単語は無視(&I)",&context->fSplchkNoupper);
  4602.     dialogControlHelp(hd,244);
  4603.     dialogCheckB(hd,"数字が付いた単語は無視(&N)",&context->fSplchkNodigit);
  4604.     dialogControlHelp(hd,245);
  4605.     dialogCheckB(hd,"URLは無視(&L)",&context->fSplchkNoUrl);
  4606.     dialogControlHelp(hd,246);
  4607.     dialogCheckB(hd,"一時辞書をクリアしてからチェック(&T)",&context->fSplchkClearTempDic);
  4608.         dialogSetH(hd);
  4609.     dialogControlHelp(hd,247);
  4610.     dialogCheckB(hd,"短い単語は無視(&W):",&context->fSplchkShort);
  4611.     dialogControlUpdown(hd,1,5);
  4612.     dialogControlGuide(hd,"文字以下",8);
  4613.     dialogIntegerB(hd,NULL,0,&context->nSplchkShort,6);
  4614.         dialogLFSetV(hd);
  4615. }
  4616.  
  4617. BOOL CALLBACK dlgprocSpellCheck(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  4618. {
  4619.     HDIALOG hd = dialogFromHwnd(hwnd);
  4620.     PROOF_DIALOG* context = (LPVOID)dialogGetCustdata(hd);
  4621.     switch(message) {
  4622.         case WM_COMMAND: {
  4623.             int id = GET_WM_COMMAND_ID(wParam,lParam);
  4624.             if (id == IDD_STYLE) {
  4625.                 int ret = 0;
  4626.                 dialogRead(hd);
  4627.                 ret = uistyle(context);
  4628.                 if (ret == IDOK) dialogWrite(hd);
  4629.                 return TRUE;
  4630.             }
  4631.             break;
  4632.         }
  4633.     }
  4634.     return FALSE;
  4635. }
  4636.  
  4637. static BOOL _txuiSpellCheck(TX* text,int mode)
  4638. {
  4639. //WZ3.90L 981116 メニューから選ぶスペルチェックは全チェックの簡単なUIに。
  4640.     BOOL fSplchkCur = (mode == 1);    // カーソル位置の単語
  4641.     PROOF_DIALOG _context;
  4642.     PROOF_DIALOG* context = &_context;
  4643.     mchar buff[CCHWORD];
  4644.     HDIALOG hd;
  4645.     BOOL ret = FALSE;
  4646. //uiRegisterWord("c:\\_wz\\u_spell.dic","","ユーザ辞書へ登録");return TRUE;
  4647.     //
  4648.     structClear(*context);
  4649.     context->text = text;
  4650.     proofstyleLoad("前回のスペルチェック",context);
  4651.     splchkOpenTempDic(context);
  4652.     if (fSplchkCur) {
  4653.         context->fSplchkCur = !(text->fClip && !text->fClipSearch) && (isalpha(txGetChar(text)) || isalpha(txGetPrevChar(text)));
  4654.     }
  4655.     if (fSplchkCur) {
  4656.         if (context->fSplchkCur) {
  4657.             // カーソル位置の検査では、「前回のスペルチェック」の設定を使う。
  4658.             splchkExec(context,NULL);
  4659.             ret = TRUE;
  4660.         } else {
  4661.             // カーソル位置の検査でカーソル位置が英単語でなければ何もしない。
  4662.         }
  4663.     } else {
  4664.         sprintf_A(buff,"スペルチェック%s",context->fSplchkCur ? " - カーソル位置の単語" : "");
  4665.         hd = dialog(buff);
  4666.         //
  4667.         dialogAddSpellCheck(hd,context,TRUE);
  4668.         dialogSetDlgproc(hd,dlgprocSpellCheck);
  4669.         dialogLFV(hd);
  4670.         dialogOK(hd,14);
  4671.         dialogCancel(hd,14);
  4672.         dialogSpaceV(hd);
  4673.         dialogControlID(hd,IDD_STYLE);
  4674.         dialogCmd(hd,"スタイル(&Q)...",14);
  4675.         if (dialogOpen(hd)) {
  4676.             proofstyleSave("前回のスペルチェック",context);
  4677.             splchkExec(context,NULL);
  4678.             ret = TRUE;
  4679.         }
  4680.     }
  4681.     splchkCloseTempDic(context);
  4682.     return ret;
  4683. }
  4684.  
  4685. BOOL txIDM_UISPLCHK(TX* text)
  4686. {
  4687.     return _txuiSpellCheck(text,0);
  4688. }
  4689.  
  4690. BOOL txIDM_UISPLCHKCUR(TX* text)
  4691. {
  4692.     return _txuiSpellCheck(text,1);
  4693. }
  4694.  
  4695. #if WZFUNC_EDITOR
  4696.  
  4697. static BOOL txdicSearchCategory(TX* text,mchar* szCategory)
  4698. {
  4699.     txJumpFileTop(text);
  4700.     while(1) {
  4701.         if (txSearchEx(text,".#",SEARCH_CUR|SEARCH_PARATOP)) {
  4702.             if (txCmpParaOffset(text,szCategory,2)) return TRUE;
  4703.             if (!txNextPara(text)) break;
  4704.         } else {
  4705.             break;
  4706.         }
  4707.     }
  4708.     return FALSE;
  4709. }
  4710.  
  4711. static void txdicDeleteCategory(TX* text,mchar* szCategory)
  4712. {
  4713.     if (txdicSearchCategory(text,szCategory)) {
  4714.         txSelectEx(text,CLIP_CHAR);
  4715.         if (txNextPara(text) && txSearchEx(text,".#",SEARCH_CUR|SEARCH_PARATOP)) {
  4716.         } else {
  4717.             txJumpFileEnd(text);
  4718.         }
  4719.         txSelectDelete(text);
  4720.     }
  4721. }
  4722.  
  4723. static void txdicCopyCategory(TX* text,mchar* szCategory,TX* textDst)
  4724. {
  4725.     if (txdicSearchCategory(text,szCategory)) {
  4726.         txSelectEx(text,CLIP_CHAR);
  4727.         if (txNextPara(text) && txSearchEx(text,".#",SEARCH_CUR|SEARCH_PARATOP)) {
  4728.         } else {
  4729.             txJumpFileEnd(text);
  4730.         }
  4731.         txJumpFileEnd(textDst);
  4732.         txInsertTextSelect(textDst,text);
  4733.     }
  4734. }
  4735.  
  4736. static void txdicSwapSrcDst(TX* text,mchar* szCategory)
  4737. {
  4738.     if (txdicSearchCategory(text,szCategory)) {
  4739.         if (txNextPara(text)) {
  4740.             while(1) {
  4741.                 if (txCmpIParatop(text,".#")) break;
  4742.                 {
  4743.                     mchar* pTop = text->buff + text->cur;
  4744.                     mchar* pEnd = pTop + txGetParaContentLen(text);
  4745.                     mchar* p = memchr(pTop,CHAR_TAB,pEnd - pTop);
  4746.                     if (p) {
  4747.                         mchar* sz = strdupLen(pTop,p - pTop);
  4748.                         txDeleteBytes(text,p - pTop + 1);
  4749.                         pTop = text->buff + text->cur;
  4750.                         pEnd = pTop + txGetParaContentLen(text);
  4751.                         p = memchr(pTop,CHAR_TAB,pEnd - p);
  4752.                         if (p) {
  4753.                             txRightBytes(text,p - pTop);
  4754.                         } else {
  4755.                             txJumpParaEnd(text);
  4756.                         }
  4757.                         txInsertChar(text,CHAR_TAB);
  4758.                         txInsert(text,sz);
  4759.                         free(sz);
  4760.                     }
  4761.                 }
  4762.                 if (!txNextPara(text)) break;
  4763.             }
  4764.         }
  4765.     }
  4766. }
  4767.  
  4768. static TX* ProofDicMake(PROOF_DIALOG* context)
  4769. {
  4770.     mchar szfilenameDic[CCHPATHNAME];
  4771.     TX* text = textopen(pathFullConfig(szfilenameDic,"proof.dic"));
  4772.     TX* textDst = textopen(NULL);
  4773. #if UNIX
  4774.     kcToTBEx(text,KC_SJIS);
  4775. #endif
  4776.     switch(context->kutoten) {
  4777.         case 1: txdicCopyCategory(text,"KUTOTEN_to_SIRO",textDst);break;
  4778.         case 2: txdicCopyCategory(text,"KUTOTEN_to_KURO",textDst);break;
  4779.     }
  4780.     switch(context->buntai) {
  4781.         case 1: {
  4782.             txdicCopyCategory(text,"DEARU_DESUMASU",textDst);
  4783.             txdicSwapSrcDst(textDst,"DEARU_DESUMASU");
  4784. //dialogaText(textDst,NULL);
  4785.             break;
  4786.         }
  4787.         case 2: {
  4788.             txdicCopyCategory(text,"DEARU_DESUMASU",textDst);
  4789.             break;
  4790.         }
  4791.     }
  4792.     switch(context->kanji_kana) {
  4793.         case 1: {
  4794.             txdicCopyCategory(text,"KANJI_KANA",textDst);
  4795.             txdicSwapSrcDst(textDst,"KANJI_KANA");break;
  4796.             break;
  4797.         }
  4798.         case 2: txdicCopyCategory(text,"KANJI_KANA",textDst);break;
  4799.     }
  4800.     if (context->kuten_brace) txdicCopyCategory(text,"KUTEN_BRACE",textDst);
  4801.     if (context->suffix_kana) txdicCopyCategory(text,"SUFFIX_KANA",textDst);
  4802.     if (context->reader) txdicCopyCategory(text,"READER",textDst);
  4803.     if (context->homophone) txdicCopyCategory(text,"HOMOPHONE",textDst);
  4804.     if (context->itaiji) txdicCopyCategory(text,"ITAIJI",textDst);
  4805.     if (context->ukemi) txdicCopyCategory(text,"UKEMI",textDst);
  4806.     if (context->strong) txdicCopyCategory(text,"STRONG",textDst);
  4807.     if (context->sijisi) txdicCopyCategory(text,"SIJISI",textDst);
  4808.     if (context->ranuki) txdicCopyCategory(text,"RANUKI",textDst);
  4809.     if (context->hitei) txdicCopyCategory(text,"HITEI",textDst);
  4810.     if (context->josi_continue) txdicCopyCategory(text,"JOSI_CONTINUE",textDst);
  4811.     if (context->digit_zenhan) txdicCopyCategory(text,"DIGIT_ZENHAN",textDst);
  4812.     if (context->fCheckLongPara) {
  4813.         txJumpFileEnd(textDst);
  4814.         txInsertf(textDst,"\t%d\t,,LONGPARA",context->lcxLongPara * 2);
  4815.         txInsertReturn(textDst);
  4816.     }
  4817.     textclose(text);
  4818.     // 辞書が空ならNULLを返す
  4819.     if (txGetTextSize(textDst)) return textDst;
  4820.     textclose(textDst);return NULL;
  4821. }
  4822.  
  4823. static void listFlushProofDeleteArea(LIST* list,IFILE adrTop,IFILE adrEnd,WORD_STANDARDIZE_ITEM* notdelete)
  4824. {
  4825. // adrTopからadrEnd(adrEndは含まない)にかかるアイテムを削除する
  4826.     WORD_STANDARDIZE_ITEM* cur0 = listReadCur(list);
  4827.     WORD_STANDARDIZE_ITEM* now = (LPVOID)list->top;
  4828.     for (;now;) {
  4829.         WORD_STANDARDIZE_ITEM* next = (LPVOID)now->head.next;
  4830.         if (now != notdelete) {
  4831.             if (adrTop <= now->adrFind && now->adrFind < adrEnd) {
  4832.                 listDel(list,now);
  4833.             } else if (adrTop <= now->adrFind+now->lchFind && now->adrFind+now->lchFind < adrEnd) {
  4834.                 listDel(list,now);
  4835.             }
  4836.         }
  4837.         now = next;
  4838.     }
  4839.     listJumpItem(list,cur0);
  4840. }
  4841.  
  4842. static void listFlushProofReplace(LIST* list,IFILE adrFind,int lchFind,int lchReplace,WORD_STANDARDIZE_ITEM* src)
  4843. {
  4844. // srcのadrFind:lchFindをlchReplaceに置き換えたとき、他のリストアイテムの位置を移動する。
  4845.     WORD_STANDARDIZE_ITEM* now = (LPVOID)list->top;
  4846.     int d = lchReplace - lchFind;
  4847.     for (;now;now = (LPVOID)now->head.next) {
  4848.         if (now != src) {
  4849.             if (now->adrFind <= adrFind && adrFind < now->adrFind + now->lchFind) {
  4850.                 // srcを完全に含む場合は、長さを調整する。
  4851.                 now->lchFind += d;
  4852.             }
  4853.             if (now->adrFind >= adrFind) {
  4854.                 now->adrFind += d;
  4855.             }
  4856.         }
  4857.     }
  4858. }
  4859.  
  4860. static void proofOpenContextMenu(HWND hwnd,BOOL fByKey);
  4861.  
  4862. static BOOL issepastr(mchar* str)
  4863. {
  4864. // strが|で区切られたものかどうか返す
  4865.     return strchr(str,'|');
  4866. }
  4867.  
  4868. static BOOL proofProcCmd(HWND hwnd,int id)
  4869. {
  4870.     HDIALOG hd = dialogFromHwnd(hwnd);
  4871.     PROOF_DIALOG* context = (LPVOID)dialogGetCustdata(hd);
  4872.     LIST* list = listh_GetList(GetDlgItem(hwnd,IDD_LIST));
  4873.     TX* text = context->text;
  4874.     if (context->fSplchkMode && id == IDD_SPLCHK) {
  4875.         if (context->fSpellChecked) id = IDD_EXEC;
  4876.     }
  4877.     switch(id) {
  4878.         case IDD_SPLCHK:
  4879.         case IDD_START: {
  4880.             if (context->fSearching) {
  4881.                 _fBreaked = TRUE;
  4882.             } else {
  4883.                 context->fSearching = TRUE;
  4884.                 dialogRead(hd);
  4885.                 #if 1//WZ4.00Ec 010129 用語統一で前回使用した辞書を覚えるようにした。
  4886.                 proofstyleSave("前回の校正",context);
  4887.                 #else
  4888.                 if (!context->fReWording) proofstyleSave("前回の校正",context);
  4889.                 #endif
  4890.                 {
  4891.                     int ret = 0;
  4892.                     EnableDlgItem(hwnd,IDD_EXEC,FALSE);
  4893.                     EnableDlgItem(hwnd,IDD_EXECALL,FALSE);
  4894.                     EnableDlgItem(hwnd,IDD_DELETE,FALSE);
  4895.                     EnableDlgItem(hwnd,IDCANCEL,FALSE);
  4896.                     SetDlgItemText_A(hwnd,id,"中止");
  4897.                     _fBreaked = FALSE;
  4898.                     _hdlg = hwnd;
  4899.                         listDelAll(list);
  4900.                         if (!context->fSplchkMode) {
  4901.                             UINT mode = 0;
  4902.                             #if __TXC__
  4903.                             mode |= SPLCHK_TXC;
  4904.                             #endif
  4905.                             if (!context->fReWording) {
  4906.                                 TX* textDic = ProofDicMake(context);
  4907. //dialogaText(textDic,NULL);
  4908.                                 if (textDic) {
  4909.                                     ret += txWordStandardize(context->text,textDic,list,mode,AbortProc);
  4910.                                     textclose(textDic);
  4911.                                 }
  4912.                             }
  4913.                             if ((context->fReWording || context->fWordStandardize) && context->szfilenameDic[0] && !_fBreaked) {
  4914.                                 TX* textDic = textopen(context->szfilenameDic);
  4915.                                 ret += txWordStandardize(context->text,textDic,list,mode,AbortProc);
  4916.                                 textclose(textDic);
  4917.                             }
  4918.                         }
  4919.                         if (context->fSpellCheck && !_fBreaked) {
  4920.                             ret += splchkExec(context,list);
  4921.                         }
  4922.                         listJumpTop(list);
  4923.                         listNotifySelchange(list);
  4924.                     EnableDlgItem(hwnd,IDCANCEL,TRUE);
  4925.                     if (context->fSplchkMode) {
  4926.                         context->fSpellChecked = TRUE;
  4927.                         EnableDlgItem(hwnd,IDD_SAME,TRUE);    //WZ4.00Bf 990524 hd->hwnd
  4928.                         EnableDlgItem(hwnd,IDD_DELETE,TRUE);//WZ4.00Bf 990524 hd->hwnd
  4929.                         EnableDlgItem(hwnd,IDD_START,TRUE);    //WZ4.00Bf 990524 hd->hwnd
  4930.                         SetDlgItemText_A(hwnd,id,id == IDD_SPLCHK ? "修正(&X)" : "再調査(&S)");
  4931.                     } else {
  4932.                         SetDlgItemText_A(hwnd,IDD_START,"調査");
  4933.                     }
  4934.                     {
  4935.                         BOOL f = !!list->n;
  4936.                         EnableDlgItem(hwnd,IDD_EXEC,f);
  4937.                         EnableDlgItem(hwnd,IDD_EXECALL,f);
  4938.                         EnableDlgItem(hwnd,IDD_DELETE,f);
  4939.                     }
  4940.                     SetFocus(list->hwnd);
  4941.                     _hdlg = NULL;
  4942.                     //
  4943.                     statprintf("%d個あります",ret);
  4944.                     if (_fBreaked) statprintf("中止しました");
  4945.                 }
  4946.                 context->fSearching = FALSE;
  4947.             }
  4948.             return TRUE;
  4949.         }
  4950.         case IDD_DELETE: {
  4951.             if (!context->fSearching) {
  4952.                 WORD_STANDARDIZE_ITEM* item = listWalkStart(list);
  4953.                 for (;item;) {
  4954.                     WORD_STANDARDIZE_ITEM* next = listWalkNext(list,item);
  4955.                     sbAddHist(context->sbSplchkTempDic,item->szFind);    // 一時辞書に記憶
  4956.                     listDel(list,item);
  4957.                     item = next;
  4958.                 }
  4959.                 listDispAll(list);
  4960.             }
  4961.             break;
  4962.         }
  4963.         case IDD_DELETEALL: {
  4964.             //WZ4.00Bl 990909 「用語統一|操作|同じ綴りを全て無視」でアプリエラーになる場合があったのを修正。
  4965.             if (listReadCur(list)) {
  4966.                 WORD_STANDARDIZE_ITEM item = *(WORD_STANDARDIZE_ITEM*)listReadCur(list);
  4967.                 WORD_STANDARDIZE_ITEM* now;
  4968.                 sbAddHist(context->sbSplchkTempDic,item.szFind);    //一時辞書に記憶
  4969.                 listSelectQuit(list);
  4970.                 for (now = (LPVOID)list->top;now;) {
  4971.                     WORD_STANDARDIZE_ITEM* next = (LPVOID)now->head.next;
  4972.                     if (!strcmp(now->szFind,item.szFind)) {
  4973.                         listDel(list,now);
  4974.                     }
  4975.                     now = next;
  4976.                 }
  4977.                 listDispAll(list);
  4978.                 listNotifySelchange(list);
  4979.             }
  4980.             break;
  4981.         }
  4982.         case IDD_EXECALL:
  4983.         case IDD_EXEC: {
  4984.             BOOL fAll = (id == IDD_EXECALL);
  4985.             WORD_STANDARDIZE_ITEM* item = fAll ? list->top : listWalkStart(list);
  4986.             int nReplace = 0;
  4987.             int i = 0;
  4988.             int per0 = 0;
  4989.             txSetUndisp(text);
  4990.             txSelectQuit(text);
  4991.             for (;item;item = fAll ? item->head.next : listWalkNext(list,item),i++) {
  4992.                 if (!item->fDisReplaceable) {
  4993.                     mchar* pInsert = item->szReplace;
  4994.                     int lch;
  4995.                     if (fAll) {
  4996.                         int per = (i * 100) / list->n;
  4997.                         if (per0 != per) {per0 = per;statprintf("%d%%",per);}
  4998.                     }
  4999.                     if (issepastr(item->szReplace)) {
  5000.                         pInsert = sepastrGetIndexStr(item->szReplace,item->head.iMultiString,&lch);
  5001.                     } else {
  5002.                         lch = strlen(pInsert);
  5003.                     }
  5004.                     if (pInsert[0] == '<') {
  5005.                         // コメント、指摘
  5006.                     } else {
  5007.                         mchar* pComment = memchr(pInsert,'<',lch);
  5008.                         int lchReplace = pComment ? pComment - pInsert : lch;
  5009.                         txJumpAddress(text,item->adrFind);
  5010.                         txDeleteBytes(text,item->lchFind);
  5011.                         txInsertBuff(text,pInsert,lchReplace);
  5012.                         nReplace++;
  5013.                         //
  5014.                         listFlushProofReplace(list,item->adrFind,item->lchFind,lchReplace,item);
  5015.                         item->lchFind = lchReplace;
  5016.                         // 済みにセット
  5017.                         item->fReplaced = TRUE;
  5018.                     }
  5019.                 }
  5020.             }
  5021.             listDispAll(list);
  5022.             listNotifySelchange(list);
  5023.             txSetDisp(text);
  5024.             statprintf("%d個、置換しました",nReplace);
  5025.             if (id == IDD_EXEC && i == 1) listUserDown(list);
  5026.             return TRUE;
  5027.         }
  5028.         case IDD_CLEAR: {
  5029.             memset(&context->configTop,0,&context->configEnd - &context->configTop);
  5030.             dialogWrite(hd);
  5031.             PostMessage(hwnd,WM_TXUSER,0,0);
  5032.             return TRUE;
  5033.         }
  5034.         case IDD_STYLE: {
  5035.             int ret = 0;
  5036.             dialogRead(hd);
  5037.             ret = uistyle(context);
  5038.             if (ret == IDOK) dialogWrite(hd);
  5039.             PostMessage(hwnd,WM_TXUSER,0,0);
  5040.             return TRUE;
  5041.         }
  5042.         case IDD_FLONGPARA:
  5043.         case IDD_WS: {
  5044.             PostMessage(hwnd,WM_TXUSER,0,0);
  5045.             break;
  5046.         }
  5047.         case IDD_WSEDIT: {
  5048.             dialogRead(hd);
  5049.             forkstd(context->szfilenameDic,NULL);
  5050.             break;
  5051.         }
  5052.         case IDD_SPLCHK_DETAIL: {
  5053.             HDIALOG hd = dialog("スペルチェックの詳細");
  5054.             dialogAddSpellCheck(hd,context,FALSE);
  5055.             dialogOpen(hd);
  5056.             break;
  5057.         }
  5058.         case IDD_SAME: {
  5059.             WORD_STANDARDIZE_ITEM* item = listReadCur(list);
  5060.             WORD_STANDARDIZE_ITEM* now;
  5061.             int n = 0;
  5062.             listSelectQuit(list);
  5063.             for (now = (LPVOID)list->top;now;now = (LPVOID)now->head.next) {
  5064.                 if (!strcmp(now->szFind,item->szFind)) {
  5065.                     listSelectItem(list,now);n++;
  5066.                     // スペルチェックの場合は、候補も同じものにセットする。
  5067.                     now->head.iMultiString = item->head.iMultiString;
  5068.                 }
  5069.             }
  5070.             listDispAll(list);
  5071.             listNotifySelchange(list);
  5072.             statprintf("%d個あります",n);
  5073.             break;
  5074.         }
  5075.         case IDD_UNDO: {
  5076.             WORD_STANDARDIZE_ITEM* item = listWalkStart(list);
  5077.             for (;item;item = listWalkNext(list,item)) {
  5078.                 if (!item->fDisReplaceable && !item->fDisUndoable && !item->fEdited) {
  5079.                     int lch0 = item->lchFind;
  5080.                     txJumpAddress(text,item->adrFind);
  5081.                     txDeleteBytes(text,item->lchFind);
  5082.                     //
  5083.                     item->lchFind = strlen(item->szFind);
  5084.                     txInsert(text,item->szFind);
  5085.                     //
  5086.                     listFlushProofReplace(list,item->adrFind,lch0,item->lchFind,item);
  5087.                     // 済みをリセット
  5088.                     item->fReplaced = FALSE;
  5089.                 }
  5090.             }
  5091.             listDispAll(list);
  5092.             listNotifySelchange(list);
  5093.             break;
  5094.         }
  5095.         case IDD_MENU: {
  5096.             proofOpenContextMenu(hwnd,TRUE);
  5097.             break;
  5098.         }
  5099.         case IDD_EDIT: {
  5100.             WORD_STANDARDIZE_ITEM* item = listReadCur(list);
  5101.             listNotifySelchange(list);    // 表示をフラッシュ
  5102.             if (item) {
  5103.                 HDIALOG hd = dialog("編集");
  5104.                 int ly0 = text->ly;
  5105.                 TX* text2 = txAllocText(0);
  5106.                 text2->fEnableUndo = TRUE;
  5107.                 text2->tabsize = text->tabsize;
  5108. //                text2->fSetWidthByWindow = TRUE;
  5109.                 txOpenText(text2);
  5110.                 {
  5111.                     IFILE adrTop;
  5112.                     txSetUndisp(text);
  5113.                     txJumpAddress(text,item->adrFind);
  5114.                     txJumpParaTop(text);
  5115.                     adrTop = txGetAddress(text);
  5116.                     {
  5117.                         int cch = txGetParaContentLen(text) + 10;
  5118.                         IFILE adr2 = item->adrFind - adrTop;
  5119.                         mchar* buff = malloc(cch);
  5120.                         txGetParaEx(text,buff,cch);
  5121.                         txInsert(text2,buff);
  5122.                         txJumpAddress(text2,adr2);
  5123.                         txSelectEx(text2,CLIP_MOUSE);
  5124. //information("%d %d",adr2 + item->lchFind,txGetTextSize(text2));
  5125.                         txJumpAddress(text2,adr2 + item->lchFind);
  5126.                     }
  5127.                     listNotifySelchange(list);
  5128.                     txSetDisp(text);
  5129.                 }
  5130.                 dialogEditWz(hd,"段落の内容(&C):",text2,60,10,WS_VSCROLL|WS_HSCROLL);
  5131.                 dialogLFV(hd);
  5132.                 dialogControlID(hd,IDOK);dialogCmdDefault(hd,"&OK",10);
  5133.                 dialogCancel(hd,10);
  5134.                 if (dialogOpen(hd)) {
  5135.                     txSetUndisp(text);
  5136.                     txSelectQuit(text);
  5137.                     //
  5138.                     txJumpAddress(text,item->adrFind);
  5139.                     txJumpParaTop(text);
  5140.                     {
  5141.                         IFILE size0 = txGetTextSize(text);
  5142.                         IFILE adrFind = txGetAddress(text);
  5143.                         txDeletePara(text);
  5144.                         {
  5145.                             IFILE lchFind = size0 - txGetTextSize(text);
  5146.                             IFILE adr0 = txGetAddress(text);
  5147.                             txInsertText(text,text2);
  5148.                             txInsertReturn(text);
  5149.                             {
  5150.                                 IFILE lch = txGetAddress(text) - adr0;
  5151.                                 listFlushProofDeleteArea(list,adrFind,adrFind+lchFind,item);
  5152.                                 listFlushProofReplace(list,adrFind,lchFind,lch,item);
  5153.                                 item->fDisReplaceable = TRUE;
  5154.                                 item->fDisUndoable = TRUE;
  5155.                                 item->fEdited = TRUE;
  5156.                                 item->fReplaced = TRUE;
  5157.                                 item->lchFind = lch;
  5158.                                 item->adrFind = adrFind;
  5159.                             }
  5160.                         }
  5161.                     }
  5162.                     listDispAll(list);
  5163.                     listNotifySelchange(list);
  5164.                     txSetLy(text,ly0);
  5165.                     txSetDisp(text);
  5166.                 }
  5167.                 textclose(text2);
  5168.             }
  5169.             break;
  5170.         }
  5171.     }
  5172.     return FALSE;
  5173. }
  5174.  
  5175. static void proofOpenContextMenu(HWND hwnd,BOOL fByKey)
  5176. {
  5177.     HDIALOG hd = dialogFromHwnd(hwnd);
  5178.     PROOF_DIALOG* context = (LPVOID)dialogGetCustdata(hd);
  5179.     LIST* list = listh_GetList(GetDlgItem(hwnd,IDD_LIST));
  5180.     if (listReadCur(list)) {
  5181.         HMENU hmenu = menuNew();
  5182.         int cmd;
  5183.         menuStr(hmenu,"無視(&D)",IDD_DELETE);
  5184.         menuStr(hmenu,"同じ綴りを全て無視(&F)",IDD_DELETEALL);
  5185.         menuSepa(hmenu);
  5186.         menuStr(hmenu,"同じ綴りを全て選択(&S)",IDD_SAME);
  5187.         menuSepa(hmenu);
  5188.         menuStr(hmenu,"編集(&E)",IDD_EDIT);
  5189.         menuStr(hmenu,"修正(&X)",IDD_EXEC);
  5190.         menuStr(hmenu,"元に戻す(&U)",IDD_UNDO);
  5191.         menuSepa(hmenu);
  5192. //        menuStr(hmenu,"先頭を大文字にする(&T)",IDD_Aaa);
  5193.         if (fByKey) {
  5194.             RECT r;
  5195.             listGetItemRect(list,&r);
  5196.             ClientToScreen(list->hwnd,(LPVOID)&r);// warning OK
  5197.             cmd = menuSelectXY(hmenu,r.left,r.top);
  5198.         } else {
  5199.             cmd = menuSelectMouse(hmenu);
  5200.         }
  5201.         if (cmd > 0) {
  5202.             proofProcCmd(hwnd,cmd);
  5203.         }
  5204.     } else {
  5205.         information("操作対象を一覧から選んでください");    //WZ4.00Bm 990928 一覧が空のときに校正の操作メニューが出ない説明を付けた。
  5206.     }
  5207. }
  5208.  
  5209. static int keyhookProc(WPARAM wParam,LPARAM lParam)
  5210. {
  5211.     if (wParam == VK_MENU) return TRUE;
  5212.     return FALSE;
  5213. }
  5214.  
  5215. BOOL CALLBACK dlgprocProof(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  5216. {
  5217.     HDIALOG hd = dialogFromHwnd(hwnd);
  5218.     PROOF_DIALOG* context = (LPVOID)dialogGetCustdata(hd);
  5219.     switch(message) {
  5220.         case WM_INITDIALOG: {
  5221.             LIST* list = listh_GetList(GetDlgItem(hwnd,IDD_LIST));
  5222.             WORD_STANDARDIZE_ITEM item;
  5223.             SUBLISTITEMATR* atr = &list->tSubitem[0];
  5224.             list->fNoHeaderTrack = TRUE;    //WZ4.00Cc 000122 用語統一/自動校正でヘッダカラム幅を変更できないようにした。
  5225.             //
  5226.     #if !UNIX
  5227.             listSetHfont(list,GetStockObject(DEFAULT_GUI_FONT));
  5228.     #endif
  5229.             //
  5230.             atr->type = LISTITEM_CHOICEB;
  5231.             atr->offset = (LPBYTE)&item.fReplaced - (LPBYTE)&item;
  5232.             atr->cx = dtcxListString(list,"済");
  5233.             atr->tszIndex = _tszReplaced;
  5234.                 atr++;
  5235.             atr->type = LISTITEM_INT;
  5236.             atr->offset = (LPBYTE)&item.npara - (LPBYTE)&item;
  5237.             atr->cx = dtcx(DTCX * 5);
  5238.             strcpy(atr->szGuide,"段落");
  5239.                 atr++;
  5240.             atr->type = LISTITEM_SZ;
  5241.             atr->offset = (LPBYTE)item.szFind - (LPBYTE)&item;
  5242.             atr->cx = dtcx(DTCX * 20);
  5243.             strcpy(atr->szGuide,"検出単語");
  5244.                 atr++;
  5245.             atr->type = LISTITEM_SZ;
  5246.             atr->offset = (LPBYTE)item.szReplace - (LPBYTE)&item;
  5247.             atr->fMultiString = TRUE;
  5248.             atr->cx = -1;
  5249.             strcpy(atr->szGuide,"置換候補");
  5250.                 atr++;
  5251.             //
  5252.             list->nSubitem = atr - &list->tSubitem[0];
  5253.             listHeaderSetup(list);
  5254.             //
  5255.             EnableDlgItem(hwnd,IDD_EXEC,FALSE);
  5256.             EnableDlgItem(hwnd,IDD_EXECALL,FALSE);
  5257.             PostMessage(hwnd,WM_TXUSER,0,0);
  5258.             break;
  5259.         }
  5260.         case WM_COMMAND: {
  5261.             int id = GET_WM_COMMAND_ID(wParam,lParam);
  5262.             if (proofProcCmd(hwnd,id)) return TRUE;
  5263.             break;
  5264.         }
  5265.         case WM_NOTIFY: {
  5266.             LISTNOTIFY* notify = lParam;
  5267.             LIST* list = listh_GetList(GetDlgItem(hwnd,IDD_LIST));
  5268.             if (list && notify->hdr.hwndFrom == list->hwnd) {
  5269.                 switch(notify->hdr.code) {
  5270.                     case LISTN_SELCHANGE: {
  5271.                         WORD_STANDARDIZE_ITEM* item = listReadCur(list);
  5272.                         if (item) {
  5273.                             TX* text = context->text;
  5274.                             txSetUndisp(text);
  5275.                             txSelectQuit(text);
  5276.                             txJumpAddress(text,item->adrFind);
  5277.                             txSelectEx(text,CLIP_CHAR);text->fClipSearch = TRUE;
  5278.                             txRightBytes(text,item->lchFind);
  5279.                             txSetLy(text,2);    // ダイアログに重ならないように
  5280.                             txSetDisp(text);
  5281.                         }
  5282.                         break;
  5283.                     }
  5284.                     case LISTN_FORWARD: {
  5285.                         switch(notify->message) {
  5286.                             case WM_KEYDOWN: {
  5287.                                 switch(notify->wParam) {
  5288.                                     case VK_DELETE: PostMessage(hwnd,WM_COMMAND,IDD_DELETE,0);break;
  5289.                                 }
  5290.                                 break;
  5291.                             }
  5292.                             case WM_SYSKEYDOWN: {
  5293.                                 switch(notify->wParam) {
  5294.                                     case VK_RETURN: {
  5295.         #if 0    // ダイアログでAlt+Enterを押すとビープ音が出てしまうが、以下では抑止できなかった。
  5296.                                         BYTE buff[256];
  5297.                                         GetKeyboardState(buff);
  5298.                                         buff[VK_MENU] &= 0x7E;
  5299.                                         SetKeyboardState(buff);
  5300.                                         //
  5301.                                         hwndControlProcWmKey(hwnd);
  5302.                                         //
  5303.                                         keyhookStart(keyhookProc);
  5304.                                         keyhookEnd();
  5305.         #endif
  5306.         #if 0    //WZ4.00Ca 991128 
  5307.         {
  5308.             int n = sbGetCount(context->sbSplchkTempDic);int i;
  5309.             for (i = 0;i < n;i++) printf("%s\n",sbRead(context->sbSplchkTempDic,i));
  5310.         information("%d",sbiSearchLen(context->sbSplchkTempDic,"API45",3));
  5311.         }
  5312.         #endif
  5313.         //                                proofOpenContextMenu(hwnd,TRUE);
  5314.                                         return TRUE;
  5315.                                     }
  5316.                                 }
  5317.                                 break;
  5318.                             }
  5319.                             #if !WINDOWSCE
  5320.                             case WM_RBUTTONDOWN: {
  5321.                                 proofOpenContextMenu(hwnd,FALSE);
  5322.                                 break;
  5323.                             }
  5324.                             #endif
  5325.                         }
  5326.                         break;
  5327.                     }
  5328.                 }
  5329.             }
  5330.             if (notify->hdr.hwndFrom == GetDlgItem(hwnd,IDD_LIST)) {
  5331.                 HD_NOTIFY* header = (LPVOID)lParam;
  5332.                 if (header->hdr.code == HDN_ITEMCLICK) {
  5333.                     int iSubitem = listHeaderConvertIndex(list,header->iItem);
  5334.                     WORD_STANDARDIZE_ITEM* item = listReadCur(list);
  5335.                     listSort(list,iSubitem,(context->iSubitemSort == iSubitem));
  5336.                     context->iSubitemSort = (context->iSubitemSort == iSubitem) ? -1 : iSubitem;
  5337.                     listJumpItem(list,item);
  5338.                 #if 0//WZ4.00Cc 000122 
  5339.                 } else if (header->hdr.code == HDN_BEGINTRACK) {
  5340.                     statprintf("幅は変更できません");
  5341.                     return TRUE;    // 幅の変更不可
  5342.                 #endif
  5343.                 }
  5344.             }
  5345.             break;
  5346.         }
  5347.         case WM_TXUSER: {
  5348.             BOOL f = (context->fReWording) ? TRUE : IsDlgButtonChecked(hwnd,IDD_WS);
  5349.             EnableDlgItem(hwnd,IDD_WSDIC,f);
  5350.             EnableDlgItem(hwnd,IDD_WSEDIT,f);
  5351.             //
  5352.             f = IsDlgButtonChecked(hwnd,IDD_FLONGPARA);
  5353.             EnableDlgItem(hwnd,IDD_LONGPARA,f);
  5354.             break;
  5355.         }
  5356.     }
  5357.     return FALSE;
  5358. }
  5359.  
  5360. static BOOL _txuiProof(TX* text,int mode)
  5361. {
  5362. // mode == 1: スペルチェック(廃止)
  5363. // mode == 2: 用語統一    //WZ3.90L 981116 
  5364.     BOOL fReWording = (mode == 2);
  5365.     BOOL fSplchk = (mode == 1);
  5366.     HDIALOG hd = dialog(fReWording ? "用語統一" : (fSplchk ? "スペルチェック" : "校正"));
  5367.     PROOF_DIALOG contextBody;
  5368.     PROOF_DIALOG* context = &contextBody;
  5369.     HSTRBLK sb = historyOpen("proofWsDic",4096);
  5370.     DTRECT r;
  5371.     DTRECT r0;
  5372.     IFILE adr0 = txGetAddress(text);
  5373.     //
  5374.     structClear(*context);
  5375.     context->text = text;
  5376.     proofstyleLoad("前回の校正",context);
  5377.     splchkOpenTempDic(context);
  5378. //context->fSpellCheck = TRUE;
  5379. //    pathFullConfig(context->szfilenameDic,"vc.dic");
  5380.     //
  5381.     dialogSetDlgproc(hd,dlgprocProof);
  5382.     dialogSetCustdata(hd,context);
  5383.     context->fReWording = fReWording;
  5384.     //
  5385.     if (fSplchk) {
  5386. /*    インターフェースが難しかったので、逐次で実現した。
  5387.         context->fSplchkMode = TRUE;
  5388.         context->fSpellCheck = TRUE;
  5389.         dialogAddSpellCheck(hd,context,TRUE);
  5390.         dialogSpaceV(hd);dialogSpaceV(hd);dialogSpaceV(hd);dialogSpaceV(hd);
  5391.         dialogSpaceV(hd);dialogSpaceV(hd);dialogSpaceV(hd);dialogSpaceV(hd);
  5392.         dialogSpaceV(hd);dialogSpaceV(hd);dialogSpaceV(hd);dialogSpaceV(hd);
  5393. */
  5394.     } else {
  5395.         if (!fReWording) {
  5396.             dialogHeadline(hd,"統一",26);
  5397.             dialogChoiceB(hd,"句読点(&I):",10,&context->kutoten,16,"調査しない","、。",",.",NULL);
  5398.             dialogChoiceB(hd,"文体(&F):",10,&context->buntai,16,"調査しない","です・ます調","だ・である調",NULL);
  5399.             dialogCaptionGuide(hd,"漢字と仮名の多用(&K):");
  5400.             dialogChoiceB(hd,NULL,0,&context->kanji_kana,16,"調査しない","仮名を多用","漢字を多用",NULL);
  5401.             dialogCheckB(hd,"同音異義語(&H)",&context->homophone);
  5402.             dialogCheckB(hd,"閉じ括弧の句点(&B)",&context->kuten_brace);
  5403.             dialogGetPos(hd,&r0);
  5404.             dialogCheckB(hd,"送り仮名を本則に(&O)",&context->suffix_kana);
  5405.             dialogCheckB(hd,"リーダー記号(&R)",&context->reader);
  5406.         }
  5407.         // 用語統一
  5408.         if (!fReWording) {
  5409.             dialogControlID(hd,IDD_WS);
  5410.             dialogCheckB(hd,"用語統一(&W)",&context->fWordStandardize);
  5411.         }
  5412.         dialogSetH(hd);
  5413.         dialogControlID(hd,IDD_WSDIC);
  5414.         #if !__TXC__
  5415.         {
  5416.             //WZ3.90L 981116 用語統一辞書の拡張子はRELにした。
  5417.             mchar szpath[CCHPATHNAME];
  5418.             CONFIGAPP app;
  5419.             configappLoad(&app);strcpy(szpath,app.dicpath);if (szpath[0]) pathSetDir(szpath);
  5420.             pathSetFileName(szpath,"*.rel");
  5421.             dialogControlRefer(hd,szpath);
  5422. //information(szpath);
  5423.         }
  5424.         #endif
  5425.         dialogControlStrblkHist(hd,sb);
  5426.         dialogString(hd,"  辞書:",7,context->szfilenameDic,CCHPATHNAME,35);
  5427.         dialogControlID(hd,IDD_WSEDIT);
  5428.         dialogPushbutton(hd,"編集",5);
  5429.         dialogSetV(hd);
  5430.         //
  5431.         if (!fReWording) {
  5432.             dialogSetPosLX(hd,24);
  5433.             dialogSetPosY(hd,r0.y - DTCYINT);
  5434.             dialogSetH(hd);
  5435.                 dialogCheckB(hd,"スペルチェック(&E):",&context->fSpellCheck);
  5436.                 dialogControlID(hd,IDD_SPLCHK_DETAIL);
  5437.                 dialogPushbutton(hd,"詳細(&G)...",10);
  5438.             dialogSetV(hd);
  5439.             dialogSetPosLX(hd,24);
  5440.             dialogSetPosY(hd,r0.y + DTCYBOX + DTCYINT);
  5441.             //
  5442.             dialogCheckB(hd,"異体字を現代字に(&L)",&context->itaiji);
  5443.             dialogCheckB(hd,"全角数字2桁、半角数字1桁(&2)",&context->digit_zenhan);
  5444.                 dialogLFV(hd);
  5445.                 dialogSetPosLX(hd,28);
  5446.             dialogHeadline(hd,"指摘",30);
  5447.             //
  5448.             dialogGetPos(hd,&r0);
  5449.             dialogSetH(hd);
  5450.             hd->dtyAdd = DTCYINT;
  5451.             dialogControlID(hd,IDD_FLONGPARA);
  5452.             dialogCheckB(hd,"長い段落(&P):",&context->fCheckLongPara);
  5453.             dialogControlID(hd,IDD_LONGPARA);
  5454.             dialogControlGuide(hd,"文字",4);
  5455.             dialogControlUpdown(hd,40,500);
  5456.             dialogIntegerW(hd,"全角",4,&context->lcxLongPara,6-SFF*2);
  5457.             dialogSetV(hd);
  5458.             r0.y += DTCYBOX + DTCYINT;
  5459.             dialogSetPos(hd,&r0);
  5460.             //
  5461.             dialogCheckB(hd,"受け身(&U)",&context->ukemi);
  5462.             dialogCheckB(hd,"強調表現(&T)",&context->strong);
  5463.             dialogCheckB(hd,"指示詞(&J)",&context->sijisi);
  5464.                 r0.x += DTCX * 15;
  5465.                 dialogSetPos(hd,&r0);
  5466.             dialogCheckB(hd,"ら抜き(&V)",&context->ranuki);
  5467.             dialogCheckB(hd,"否定(&N)",&context->hitei);
  5468.             dialogCheckB(hd,"助詞の連続(&C)",&context->josi_continue);
  5469.         }
  5470.     }
  5471.     //
  5472.     dialogLF(hd);
  5473.     {
  5474.         int lcxList = 73;
  5475.         r.y = dialogGetPosY(hd);
  5476.         if (context->fSplchkMode) {
  5477. /*            lcxList = 60;
  5478.             dialogSetPosY(hd,r.y - DTCYKEY);dialogSetPosLX(hd,lcxList-8-1);
  5479.             dialogCaptionGuide(hd,"一覧(&D):");
  5480. */
  5481.         } else {
  5482.             dialogSetPosY(hd,r.y - DTCYBOX);dialogSetPosLX(hd,lcxList-7-SFF);
  5483.             dialogControlID(hd,IDD_MENU);
  5484.             dialogPushbutton(hd,"操作(&M)",7+SFF);    //WZ3.90L 981116 "メニュー"から"操作"に変更。
  5485.             //
  5486.             dialogSetPosY(hd,r.y - DTCYKEY);dialogSetPosLX(hd,lcxList-8-7-1);
  5487.             #if UNIX
  5488.             {
  5489.                 int cyInt0 = hd->cyInt;
  5490.                 hd->cyInt = 0;
  5491.                 dialogCaptionDynamic(hd,"一覧 &D:",8);
  5492.                 hd->cyInt = cyInt0;
  5493.             }
  5494.             #else
  5495.             dialogCaptionGuide(hd,"一覧(&D):");
  5496.             #endif
  5497.         }
  5498.         dialogSetPosLX(hd,0);
  5499.         r.x = dialogGetPosX(hd);
  5500.         r.cx = DTCX * lcxList;
  5501.         r.cy = DTCY * 10;
  5502.         __dialogAddItem(hd,szclassListH,NULL,IDD_LIST,&r,WS_GROUP|WS_TABSTOP|WS_BORDER|WS_CHILD|WS_VISIBLE);
  5503.         dialogSetPosY(hd,r.y + r.cy + DTCYINT);
  5504.     }
  5505.     //
  5506. #if 0
  5507.     dialogSetH(hd);
  5508.     dialogControlID(hd,IDD_DELETE);
  5509.     dialogPushbutton(hd,"一覧から除く(&X)",16);
  5510.     dialogSetV(hd);
  5511. #endif
  5512.     //
  5513.     dialogLFV(hd);
  5514.     if (context->fSplchkMode) {
  5515. /*        dialogControlID(hd,IDD_SPLCHK);
  5516.         dialogCmdDefault(hd,"調査",17);
  5517.         dialogControlID(hd,IDCANCEL);
  5518.         dialogCmd(hd,"閉じる",17);
  5519.             dialogSpaceV(hd);
  5520.         dialogControlEnable(hd,FALSE);
  5521.         dialogControlID(hd,IDD_SAME);
  5522.         dialogPushbuttonBig(hd,"同じ綴りも訂正(&A)",17);
  5523.         dialogControlEnable(hd,FALSE);
  5524.         dialogControlID(hd,IDD_DELETE);
  5525.         dialogPushbuttonBig(hd,"無視(&Z)",17);
  5526.             dialogSpaceV(hd);
  5527.         dialogControlEnable(hd,FALSE);
  5528.         dialogControlID(hd,IDD_START);
  5529.         dialogPushbuttonBig(hd,"再調査(&S)",12);
  5530.         dialogControlID(hd,IDD_STYLE);
  5531.         dialogPushbuttonBig(hd,"スタイル(&Q)...",12);
  5532. */
  5533.     } else {
  5534.         if (!fReWording) {
  5535.             dialogIndent(hd,-13);
  5536.         }
  5537.         dialogControlID(hd,IDD_START);
  5538.         dialogCmdDefault(hd,"調査",12);
  5539.         dialogControlID(hd,IDCANCEL);
  5540.         dialogCmd(hd,"閉じる",12);
  5541.             dialogSpaceV(hd);
  5542.         dialogControlID(hd,IDD_EXEC);
  5543.         dialogCmd(hd,"修正(&X)",12);
  5544.         dialogControlID(hd,IDD_EXECALL);
  5545.         dialogCmd(hd,"一括修正(&A)",12);
  5546.             dialogSpaceV(hd);
  5547.         dialogControlID(hd,IDD_CLEAR);
  5548.         dialogCmd(hd,"クリア(&Z)",12);
  5549.         dialogControlID(hd,IDD_STYLE);
  5550.         dialogCmd(hd,UNIX?"スタイル(&Q)...":"スタイル(&Q)...",12);
  5551.     }
  5552.     //
  5553.     dialogOpen(hd);
  5554.     txMarkEx(text,0,adr0);    // すぐに元の位置に戻れるように
  5555.     if (text->fClip) text->fClipMouse = TRUE;
  5556.     historyClose("proofWsDic",sb);
  5557.     splchkCloseTempDic(context);
  5558.     return TRUE;
  5559. }
  5560.  
  5561. BOOL txIDM_PROOFAUTO(TX* text)
  5562. {
  5563.     return _txuiProof(text,0);
  5564. }
  5565.  
  5566. BOOL txIDM_UIREWORDING(TX* text)
  5567. {
  5568.     return _txuiProof(text,2);
  5569. }
  5570.  
  5571. #endif    // WZFUNC_EDITOR
  5572. #endif    // !WINDOWSCE
  5573.  
  5574. //##全角と半角の変換
  5575.  
  5576. static void FlushDispAc(HWND hwnd)
  5577. {
  5578.     if (GetDlgItem(hwnd,IDD_AUTOCORRECT)) {
  5579.         BOOL f = IsDlgButtonChecked(hwnd,IDD_AUTOCORRECT);
  5580.         EnableDlgItem(hwnd,IDD_KATA,f);
  5581.         EnableDlgItem(hwnd,IDD_HIRA,f);
  5582.         EnableDlgItem(hwnd,IDD_ALPHABET,f);
  5583.         EnableDlgItem(hwnd,IDD_NUMBER,f);
  5584.         EnableDlgItem(hwnd,IDD_SPACE,f);
  5585.         EnableDlgItem(hwnd,IDD_KIGOU,f);
  5586.         EnableDlgItem(hwnd,IDD_BRACE,f);
  5587.         EnableDlgItem(hwnd,IDD_CLEAR,f);
  5588.     }
  5589. }
  5590.  
  5591. BOOL CALLBACK dlgprocConvertChar(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  5592. {
  5593.     switch(message) {
  5594.         case WM_INITDIALOG: {
  5595.             FORWARD_WM_COMMAND(hwnd,IDD_AUTOCORRECT,NULL,0,PostMessage);
  5596.             break;
  5597.         }
  5598.         case WM_COMMAND: {
  5599.             int id = GET_WM_COMMAND_ID(wParam,lParam);
  5600.             int notify = GET_WM_COMMAND_CMD(wParam,lParam);
  5601.             switch(id) {
  5602.                 case IDD_AUTOCORRECT: {
  5603.                     FlushDispAc(hwnd);
  5604.                     break;
  5605.                 }
  5606.                 case IDD_CLEAR: {
  5607.                     ComboBox_SetCurSel(GetDlgItem(hwnd,IDD_KATA),0);
  5608.                     ComboBox_SetCurSel(GetDlgItem(hwnd,IDD_HIRA),0);
  5609.                     ComboBox_SetCurSel(GetDlgItem(hwnd,IDD_ALPHABET),0);
  5610.                     ComboBox_SetCurSel(GetDlgItem(hwnd,IDD_NUMBER),0);
  5611.                     ComboBox_SetCurSel(GetDlgItem(hwnd,IDD_SPACE),0);
  5612.                     ComboBox_SetCurSel(GetDlgItem(hwnd,IDD_KIGOU),0);
  5613.                     CheckDlgButton(hwnd,IDD_BRACE,FALSE);
  5614.                     return TRUE;
  5615.                 }
  5616.             }
  5617.             break;
  5618.         }
  5619.     }
  5620.     return FALSE;
  5621. }
  5622.  
  5623. void dialogAddConvertChar(HDIALOG hd,CCCONTEXT* ccc)
  5624. {
  5625.     int lxg = 12;
  5626.     int lcx = 12+SFF;
  5627.     dialogControlID(hd,IDD_KATA);
  5628.     dialogControlHelp(hd,116);
  5629.     dialogChoice(hd,"カタカナ(&K):",lxg,&ccc->modeKata,lcx,"そのまま","半角へ","全角へ","ひらがなへ",NULL);
  5630.     //
  5631.     dialogControlID(hd,IDD_HIRA);
  5632.     dialogControlHelp(hd,117);
  5633.     dialogChoice(hd,"ひらがな(&N):",lxg,&ccc->modeHira,lcx,"そのまま","半角カタカナへ",NULL);
  5634.     //
  5635.     dialogControlID(hd,IDD_ALPHABET);
  5636.     dialogControlHelp(hd,118);
  5637.     dialogChoice(hd,"アルファベット(&L):",lxg,&ccc->modeAlphabet,lcx,"そのまま","半角へ","全角へ",NULL);
  5638.     //
  5639. #if 0    ///未実装
  5640.     dialogControlID(hd,IDD_BRACE);
  5641.     dialogCheck(hd,"「」を[]へ(&B)",&ccc->fJbraceToBrace);
  5642. #endif
  5643.     //
  5644. #if !WINDOWSCE
  5645. //    dialogCaption(hd,"全角数字2文字を半角に");    // 未完成
  5646. //    dialogCaption(hd,"半角数字1文字を全角に");    // 未完成
  5647. #endif
  5648.     if (!_pspc) {
  5649.         dialogLFV(hd);
  5650.         dialogSpaceH(hd);
  5651.         lxg = 8+SFF;
  5652.     }
  5653.     dialogControlID(hd,IDD_NUMBER);
  5654.     dialogControlHelp(hd,119);
  5655.     dialogChoice(hd,"数字(&U):",lxg,&ccc->modeNumber,lcx,"そのまま","半角へ","全角へ",NULL);
  5656.     //
  5657.     dialogControlID(hd,IDD_KIGOU);
  5658.     dialogControlHelp(hd,120);
  5659.     dialogChoice(hd,"記号(&I):",lxg,&ccc->modeKigou,lcx,"そのまま","半角へ","全て半角へ","全角へ","全て全角へ",NULL);    //WZ3.90N 981130 中黒も半角カナに変換する「全て半角へ」を追加。    //WZ4.00Bn 991006 「全て全角へ」を追加。
  5660.     //
  5661.     dialogControlID(hd,IDD_SPACE);
  5662.     dialogControlHelp(hd,121);
  5663.     dialogChoice(hd,"空白(&S):",lxg,&ccc->modeSpace,lcx,"そのまま","半角へ","全角へ",NULL);
  5664.     //
  5665.     dialogLF(hd);//WCE0.94 970921 
  5666.     dialogSpaceV(hd);
  5667.     dialogControlID(hd,IDD_CLEAR);
  5668.     dialogControlHelp(hd,122);
  5669.     dialogPushbutton(hd,"クリア(&Z)",12);
  5670. }
  5671.  
  5672. // ー・
  5673. void ccToCcc(CHARCONVERT* cc,CCCONTEXT* ccc)
  5674. {
  5675.     structClear(*ccc);
  5676.     ccc->fAutoCollect = cc->fAc;
  5677.     ccc->fJbraceToBrace = cc->fJbraceToBrace;
  5678.     ccc->modeKata = (cc->fJkataToKana + cc->fKanaToJkata * 2 + cc->fKanaToJhira * 3);
  5679.     ccc->modeHira = cc->fJhiraToKana;
  5680.     ccc->modeAlphabet = cc->fJalphabetToAnk + cc->fAlphabetToJank * 2;
  5681.     ccc->modeNumber = cc->fJnumberToAnk + cc->fNumberToJank * 2;
  5682.     ccc->modeSpace = cc->fJspaceToAnk + cc->fSpaceToJank * 2;
  5683.     if (cc->fKigouToJank) {
  5684.         ccc->modeKigou = 3 + cc->fZenHanKanaAll;
  5685.     } else if (cc->fJkigouToAnk) {
  5686.         ccc->modeKigou = 1 + cc->fZenHanKanaAll;
  5687.     }
  5688. }
  5689.  
  5690. void ccFromCcc(CHARCONVERT* cc,CCCONTEXT* ccc)
  5691. {
  5692.     cc->fAc = ccc->fAutoCollect;
  5693.     cc->fJbraceToBrace = ccc->fJbraceToBrace;
  5694.     cc->fJkataToKana = (ccc->modeKata == 1);
  5695.     cc->fKanaToJkata = (ccc->modeKata == 2);
  5696.     cc->fKanaToJhira = (ccc->modeKata == 3);
  5697.     //WZ3.90N 981130 
  5698.     cc->fZenHanKanaAll = FALSE;
  5699.     if (ccc->modeKata == 4) {
  5700.         cc->fJkataToKana = TRUE;
  5701.         cc->fZenHanKanaAll = TRUE;
  5702.     }
  5703.     //
  5704.     cc->fJhiraToKana = ccc->modeHira;
  5705.     cc->fJalphabetToAnk = (ccc->modeAlphabet == 1);
  5706.     cc->fAlphabetToJank = (ccc->modeAlphabet == 2);
  5707.     cc->fJnumberToAnk = (ccc->modeNumber == 1);
  5708.     cc->fNumberToJank = (ccc->modeNumber == 2);
  5709.     cc->fJspaceToAnk = (ccc->modeSpace == 1);
  5710.     cc->fSpaceToJank = (ccc->modeSpace == 2);
  5711.     cc->fJkigouToAnk = (ccc->modeKigou == 1 || ccc->modeKigou == 2);
  5712.     cc->fKigouToJank = (ccc->modeKigou == 3 || ccc->modeKigou == 4);
  5713.     cc->fZenHanKanaAll = (ccc->modeKigou == 2 || ccc->modeKigou == 4);
  5714. }
  5715.  
  5716. static BOOL _txuiConvertChar(TX* text,CHARCONVERT* cc)
  5717. {
  5718.     CCCONTEXT ccc;
  5719.     HDIALOG hd = dialog("文字の変換");
  5720.     //WZ3.90N 981130 
  5721.     dialogCaption(hd,text->fClip ? "範囲内の文字を変換します" : "文書のすべての文字を変換します");
  5722.     dialogSetPosLF(hd);
  5723.     //
  5724.     ccToCcc(cc,&ccc);
  5725.     dialogSetDlgproc(hd,dlgprocConvertChar);
  5726.     dialogAddConvertChar(hd,&ccc);
  5727.     if (!_pspc) {
  5728.         dialogCmdLFV(hd);
  5729.         dialogOK(hd,12);
  5730.         dialogCancel(hd,12);
  5731.     }
  5732.     if (dialogOpen(hd)) {
  5733.         ccFromCcc(cc,&ccc);
  5734.         return TRUE;
  5735.     }
  5736.     return FALSE;
  5737. }
  5738.  
  5739. #if !__TXC__
  5740. BOOL TXAPI txuiConvertCharZenhan(TX* text)
  5741. {
  5742. // 半角文字と全角文字の変換
  5743.     if (_txuiConvertChar(text,&sh->charconvert)) {
  5744.         shconfigWriteConfigshare();
  5745. #if 1//WCE1.01 980322 MIPSで「半角文字と全角文字の変換」が機能しなかった
  5746.         {
  5747.             CHARCONVERT cc;
  5748.             memcpy(&cc,&sh->charconvert,sizeof(cc));
  5749.             txCharConvert(text,&cc);
  5750.         }
  5751. #else
  5752.         txCharConvert(text,&sh->charconvert);
  5753. #endif
  5754.         return TRUE;
  5755.     }
  5756.     return FALSE;
  5757. }
  5758. #endif // !__TXC__
  5759.  
  5760. //##表の変換
  5761.  
  5762. #if !POCKETWZ && !__TXC__
  5763. static BOOL txuiConvertTable(TX* text)
  5764. {
  5765. // 表の変換
  5766. //WZ3.90J 981110 new
  5767.     if (!txGetEditable(text)) return FALSE;    //WZ4.00Ac 990206 
  5768.     if (!text->fTxf) {
  5769.         information("タグ表示OFFのTMLファイルでしか実行できません");
  5770.     } else if (!text->fClip) {
  5771.         information("変換する部分を選択してください");
  5772.     } else {
  5773.         HDIALOG hd = dialog("表の変換");
  5774.         int mode = 0;
  5775.         {    // setup mode
  5776.             txWalkStart(text);
  5777.             if (txfCellGetExist(text)) {
  5778.                 mode = 2;
  5779.             } else {
  5780.                 mchar szline[CCHLINE];
  5781.                 txGetParaEx(text,szline,CCHLINE);
  5782.                 {
  5783.                     mchar* pTab = strchrlast(szline,CHAR_TAB);
  5784.                     mchar* pCsv = strchrlast(szline,',');
  5785.                     // 最後にTABと','のどちらが出現したかによって認識する。
  5786.                     mode = (pTab > pCsv) ? 0 : 1;
  5787.                 }
  5788.             }
  5789.             txWalkEnd(text);
  5790.         }
  5791.         dialogControlRadioV(hd);
  5792.         dialogChoiceRadio(hd,&mode,
  5793.             "タブ区切りの表 → WZの表",
  5794.             "カンマ区切りの表 → WZの表",
  5795.             "WZの表 → タブ区切りの表",
  5796.             "WZの表 → カンマ区切りの表",
  5797.             NULL
  5798.         );
  5799.         if (dialogOpen(hd)) {
  5800.             BOOL fToWz = (mode == 0 || mode == 1);
  5801.             BOOL fFromWz = (mode == 2 || mode == 3);
  5802.             BOOL fTab = (mode == 0 || mode == 2);
  5803.             BOOL fCsv = (mode == 1 || mode == 3);
  5804.             txWalkStart(text);
  5805.             while(txIsWalking(text)) {
  5806.                 txJumpParaTop(text);
  5807.                 if (fFromWz) {
  5808.                     int i;
  5809.                     for (i = 0;;i++) {
  5810.                         if (!txfCellJumpClm(text,1)) break;
  5811.                         txDeleteChar(text);
  5812.                         if (!txfCellGetExistRear(text)) break;
  5813.                         if (i != 0) {
  5814.                             txInsertChar(text,fTab ? CHAR_TAB : ',');
  5815.                         }
  5816.                     }
  5817.                 } else {
  5818.                     txInsertCell(text);
  5819.                     while(1) {
  5820.                         TXCHAR c = txGetChar(text);
  5821.                         if (txIsCurReturn(text)) break;
  5822.                         if ((fTab && c == CHAR_TAB) || (fCsv && c == ',')) {
  5823.                             txDeleteChar(text);
  5824.                             txInsertCell(text);
  5825.                         }
  5826.                         if (!txRight(text)) break;
  5827.                     }
  5828.                     txInsertCell(text);
  5829.                 }
  5830.                 //
  5831.                 if (!txNextPara(text)) break;
  5832.             }
  5833.             if (txPrevPara(text)) {
  5834.                 txfRowSetLineBottom(text,TRUE);
  5835.                 txJumpParaTop(text);txfCellFlush(text);
  5836.             }
  5837.             txWalkEnd(text);
  5838.             return TRUE;
  5839.         }
  5840.     }
  5841.     return FALSE;
  5842. }
  5843. #endif    // !POCKETWZ
  5844.  
  5845. //##罫線の変換
  5846.  
  5847. #if WINDOWSMT
  5848.  
  5849. static mchar _szNEC[] = "「」コカヨルスレケンイョホム、ニヌゼソ瘋オメアユ・ハヘツ艷ナ";
  5850. static mchar _szJIS[] = "─━┘└┴┷┛┸┗┻┐┌┬┯│┤┥├┼┝┿┓┰┏┳┃┨┫┠╂┣╋";
  5851.  
  5852. BOOL txConvertKeisenNecToJis(TX* text)
  5853. {
  5854. // ファイル内のNEC罫線をJISに変換
  5855.     txSetUndispEx(text);
  5856.     txJumpFileTop(text);
  5857.     txSetHigh(text);
  5858.     while(1) {
  5859.         if (text->buff[text->cur] == 0x86) {//3.00C 971013 84->86 「罫線の変換」バグ対処
  5860.             TXCHAR ch = txGetChar(text);
  5861.             mchar* p;
  5862.             if (p = strchr(_szNEC,ch)) {
  5863.                 txDeleteChar(text);
  5864.                 p = _szJIS + (p - _szNEC);
  5865.                 txInsertChar(text,MAKEWORD(p[1],*p));
  5866.             } else {    //WZ4.00Ei 010523 「NEC・JIS罫線の変換」でハングアップすることがあるのを修正。
  5867.                 if (!txRight(text)) break;
  5868.             }
  5869.         } else {
  5870.             if (!txRight(text)) break;
  5871.         }
  5872.     }
  5873.     txJumpFileTop(text);
  5874.     txResetHigh(text);
  5875.     txSetDispEx(text);
  5876.     return TRUE;
  5877. }
  5878.  
  5879. BOOL txConvertKeisenJisToNec(TX* text)
  5880. {
  5881. // ファイル内のJIS罫線をNECに変換
  5882.     txSetUndispEx(text);
  5883.     txJumpFileTop(text);
  5884.     txSetHigh(text);
  5885.     while(1) {
  5886.         if (text->buff[text->cur] == 0x84) {//3.00C 971013 86->84 「罫線の変換」バグ対処
  5887.             TXCHAR ch = txGetChar(text);
  5888.             mchar* p;
  5889.             if (p = strchr(_szJIS,ch)) {
  5890.                 txDeleteChar(text);
  5891.                 p = _szNEC + (p - _szJIS);
  5892.                 txInsertChar(text,MAKEWORD(p[1],*p));
  5893.             } else {    //WZ4.00Ei 010523 
  5894.                 if (!txRight(text)) break;
  5895.             }
  5896.         } else {
  5897.             if (!txRight(text)) break;
  5898.         }
  5899.     }
  5900.     txJumpFileTop(text);
  5901.     txResetHigh(text);
  5902.     txSetDispEx(text);
  5903.     return TRUE;
  5904. }
  5905.  
  5906. static BOOL txuiConvertKeisen(TX* text)
  5907. {
  5908. // 罫線の変換
  5909. //WZ3.90J 981110 new
  5910.     HDIALOG hd;
  5911.     int modeConvertKeisen = 0;    // permanent
  5912.     
  5913.     if (!txGetEditable(text)) return FALSE;    //WZ4.00Ac 990206 
  5914.     //
  5915.     hd = dialog("罫線の変換");
  5916.     dialogCaption(hd,"文書のすべての罫線文字コードを変換します");
  5917.     //
  5918.     dialogControlRadioV(hd);
  5919.     dialogChoiceRadio(hd,&modeConvertKeisen,
  5920.         "JIS罫線をNEC罫線に変換(&N)",
  5921.         "NEC罫線をJIS罫線に変換(&J)",
  5922.         NULL
  5923.     );
  5924.     if (dialogOpen(hd)) {
  5925.         switch(modeConvertKeisen) {
  5926.             case 0:return txConvertKeisenJisToNec(text);
  5927.             case 1:return txConvertKeisenNecToJis(text);
  5928.         }
  5929.     }
  5930.     return FALSE;
  5931. }
  5932.  
  5933. #endif    // WINDOWSMT
  5934.  
  5935. //##マクロ
  5936.  
  5937. #if WZFUNC_TXC
  5938. BOOL txIDM_MACRO_HELP(TX* text)
  5939. {
  5940.     wchar wsz[CCHPATHNAME];
  5941.     #if __DEV__
  5942.     wpathFullConfig(wsz,L"txc.tml");
  5943.     #elif UNIX
  5944.     wpathFullConfig(wsz,L"txc/txc.tml");
  5945.     #else
  5946.     wpathFullConfig(wsz,L"txc\\txc.tml");
  5947.     #endif
  5948.     forkstdW(wsz,UNIX?L"-v":L"/v");
  5949.     return TRUE;
  5950. }
  5951.  
  5952. BOOL txIDM_MACRO_HELPAPI(TX* text)
  5953. {
  5954.     wchar wsz[CCHPATHNAME];
  5955.     #if __DEV__
  5956.     wpathFullConfig(wsz,L"api.tml");
  5957.     #elif UNIX
  5958.     wpathFullConfig(wsz,L"txc/api.tml");
  5959.     #else
  5960.     wpathFullConfig(wsz,L"txc\\api.tml");
  5961.     #endif
  5962.     {
  5963.         NPARA npara = 1;
  5964.         TX* text2 = textopenExW(wsz,TXO_TML);
  5965.         if (text2) {
  5966.             mchar szfind[CCHWORD];
  5967.             txGetWordAfterEx(text,szfind,CCHWORD);
  5968. //information(szfind);
  5969.             if (txSearchEx(text2,szfind,SEARCH_WORD|SEARCH_PARATOP)) {
  5970.             } else {
  5971.                 mchar szfindtx[CCHWORD];
  5972.                 strcpy(szfindtx,"tx");
  5973.                 sstrcat(szfindtx,szfind);
  5974.                 txSearchEx(text2,szfindtx,SEARCH_WORD|SEARCH_NOSENSECASE|SEARCH_PARATOP);
  5975.             }
  5976.             npara = text2->npara;
  5977.         }
  5978.         textclose(text2);
  5979. //winformation(L"%s %d",wsz,npara);
  5980.         {
  5981.             wchar wsw[CCHWORD];
  5982.         #if UNIX
  5983.             sprintf_W(wsw,L"-v -j%d",npara);
  5984.         #else
  5985.             sprintf_W(wsw,L"/v /j%d",npara);
  5986.         #endif
  5987.             forkstdW(wsz,wsw);
  5988.         }
  5989.     }
  5990.     return TRUE;
  5991. }
  5992. #endif
  5993.  
  5994. //##プラグイン
  5995.  
  5996. #if __TXC__
  5997. void __pluginGetProperty(mchar* prop,txstr res)
  5998. {
  5999. //information("%s",prop);
  6000.     if (!stricmp(prop,"name")) res = "ツールIDM処理";
  6001.     if (!stricmp(prop,"author")) res = sysGetName();
  6002.     if (!stricmp(prop,"version")) res = sysGetVersionPrim();
  6003. }
  6004.  
  6005. static HOOKRESULT CALLBACK wndprocTextHook(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  6006. {
  6007.     if (message == WM_TXEVENT && wParam == TXEVENT_IDMEXEC) {
  6008.         TX* text = hwndtextGetText(hwnd);
  6009.         int idm = lParam;
  6010.         switch(idm) {
  6011. #if !WINDOWSCE
  6012.             case IDM_UIREWORDING: {    // サンプル
  6013. statprintf("用語統一 by macro");
  6014.                 txIDM_UIREWORDING(text);
  6015.                 return HOOK_CAPTURE;
  6016.             }
  6017.             case IDM_PROOFAUTO: {    // サンプル
  6018. statprintf("校正 by macro");
  6019.                 txIDM_PROOFAUTO(text);
  6020.                 return HOOK_CAPTURE;
  6021.             }
  6022.             case IDM_UISPLCHK: {    // サンプル
  6023. statprintf("スペルチェック by macro");
  6024.                 txIDM_UISPLCHK(text);
  6025.                 return HOOK_CAPTURE;
  6026.             }
  6027.             case IDM_UICONVERTTEXT: {    // サンプル
  6028. statprintf("テキストの変換 by macro");
  6029.                 txIDM_UICONVERTTEXT(text);
  6030.                 return HOOK_CAPTURE;
  6031.             }
  6032.             case IDM_SEARCHFUNCTION: {    // サンプル
  6033. statprintf("関数定義の検索 by macro");
  6034.                 txIDM_SEARCHFUNCTION(text);
  6035.                 return HOOK_CAPTURE;
  6036.             }
  6037. #endif
  6038.             case IDM_UIINFO: {    // サンプル
  6039. statprintf("文書の情報 by macro");
  6040.                 txIDM_UIINFO(text);
  6041.                 return HOOK_CAPTURE;
  6042.             }
  6043.         }
  6044.     }
  6045.     return HOOK_CONTINUE;
  6046. }
  6047.  
  6048. void __on_txFrameNew(TX* text)
  6049. {
  6050.     txSetHookWndproctextTxpcode(text,wndprocTextHook);
  6051. }
  6052.  
  6053. void __pluginHelp(TX* text)
  6054. {
  6055. // test
  6056.     information("HELP");
  6057. }
  6058.  
  6059. void __pluginConfig(TX* text)
  6060. {
  6061. // test
  6062.     information("CONFIG");
  6063. }
  6064.  
  6065. #endif
  6066.