home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1999 March / VPR9903A.BIN / APUPDATE / VC / Tx300d / TX300D.LZH / EDIT.C < prev    next >
C/C++ Source or Header  |  1997-10-13  |  114KB  |  4,568 lines

  1. // WZ EDITOR 標準機能 編集
  2. // Copyright 1995-96 TY
  3. // Thanks y.mikomeさん for complete.c/template.c/ms like select/seikei.c
  4. // Thanks CM.(千葉誠)さん for tssel
  5.  
  6. //2.99D 970331 TXCMDBASE対応
  7.  
  8. // std.view_to_edit,exec,wzopenをここに移動
  9.  
  10. #include <windows.h>
  11. #include <windowsx.h>
  12. #include "dialog.h"
  13.  
  14. #define IDD_OPEN    800
  15. #define IDD_LIST    801
  16. #define IDD_JUMP    802
  17. #define IDD_LOAD    803
  18. #define IDD_DEL        804
  19. #define IDD_NEWEST    805
  20. #define IDD_COMMENT    806
  21. #define IDD_CONFIRM    1002
  22. #define IDD_INSERT    1003
  23. #define IDD_PREVIEW    1004
  24.  
  25. //{###カット&ペースト}
  26.  
  27. //1.99C 
  28. static BOOL txSelectCopyEx(TX* text)
  29. {
  30.     if (!text->fClip) {
  31.         // 範囲指定されてなければカレント論理行をCopyする
  32.         return txClipCopyEx(text,0,0,HCLIP_WIN,CLIP_COPYPARA1,0,0);
  33.     } else {
  34.         return txSelectCopy(text);
  35.     }
  36. }
  37.  
  38. //1.00C {#MS}削除
  39. //2.00E {#VZ} txClipboardCopyへ移動
  40. //2.00E2 TXCMD削除
  41. void TXAPI txSelectTsCbPushQuit(tx *text)
  42. {
  43.     // コピー(テキストスタック連動)
  44.     // 範囲内をクリップボードにコピーして、
  45.     // テキストスタックへPUSHし、範囲指定中止
  46.     text->fCopyingWinTs++;//2.99C 970325 
  47.     clipClear(HCLIP_WIN);//1.00C VZ.KEYで、クリップボードに他アプリでコピーしたデータが入っているときに、範囲選択しないで^KK、^KCしても^KKでコピーした内容が貼り付けられなかった
  48.     txSelectCopyEx(text);
  49.     txSelectTsPushQuit(text);
  50.     text->fCopyingWinTs--;//2.99C 970325 
  51. }
  52.  
  53. //1.00C {#MS}追加
  54. //2.00E {#MS} txClipboardCopyへ移動
  55. //2.00E2 TXCMD削除
  56. BOOL TXAPI txSelectTsCbPush(tx *text)
  57. {
  58.     // コピー(テキストスタック連動)
  59.     // 範囲内をクリップボードにコピーして、
  60.     // テキストスタックへPUSH
  61. #if 1//2.99C 970325 
  62.     BOOL ret;
  63.     text->fCopyingWinTs++;//2.99C 970325 
  64.     clipClear(HCLIP_WIN);//1.00C
  65.     txSelectCopyEx(text);
  66.     if (text->fClip) text->fClipMouse = TRUE;// 1.00C y.mikome
  67.     ret = txSelectTsPush(text);
  68.     text->fCopyingWinTs--;//2.99C 970325 
  69.     return ret;
  70. #else
  71.     clipClear(HCLIP_WIN);//1.00C
  72.     txSelectCopyEx(text);
  73.     if (text->fClip) text->fClipMouse = TRUE;// 1.00C y.mikome
  74.     return txSelectTsPush(text);
  75. #endif
  76. }
  77.  
  78. //2.00E {#MS}{#VZ} txClipboardCutへ移動
  79. //2.00E2 TXCMD削除
  80. void TXAPI txSelectTsCbPushDelete(tx *text)
  81. {
  82.     // 切り取り(テキストスタック連動)
  83.     // 範囲内をクリップボードにコピーして、
  84.     // テキストスタックへPUSHし、削除し、範囲指定中止
  85.     text->fCopyingWinTs++;//2.99C 970325 
  86.     clipClear(HCLIP_WIN);//1.00C
  87.     txSelectCopyEx(text);
  88.     txSelectTsPushDelete(text);
  89.     text->fCopyingWinTs--;//2.99C 970325 
  90. }
  91.  
  92.  
  93. static BOOL IsClipOther(tx *text)
  94. {
  95. #if 1//2.90 テキストスタックとクリップボード併用でペースト時に、
  96.     // マクロでtxSelectCopyした内容がペーストされず、HCLIP_TSの内容がコピーされることがあった
  97.     // txSelectCopy時に、HCLIP_TSにデータがあるときがだめだった。
  98.     if (clipGetKind(HCLIP_WIN) && !clipIsWz()) return TRUE;
  99.     if (text->share->hclipLastCopy == HCLIP_WIN) return TRUE;
  100.     return FALSE;
  101. #else
  102.     if (clipGetKind(HCLIP_WIN) && !clipIsWz()) return TRUE;
  103.     return FALSE;
  104. #endif
  105. }
  106.  
  107. static void cutAtMouse(tx *text)
  108. {
  109.     if (text->fClip && text->fClipMouse) {
  110.         txSelectDelete(text);
  111.     }
  112. }
  113.  
  114. //2.00E2 TXCMD削除
  115. BOOL TXAPI txTsCbPaste(tx *text)
  116. {
  117.     // 貼り付け(クリップボード連携)
  118.     // WZ以外でペーストしたデータがクリップボードにあれば、そこからペースト
  119.     // テキストスタックからペースト
  120.     // カーソルを、ペーストしたバイト数、移動します。
  121.     cutAtMouse(text);
  122.     if (IsClipOther(text)) return txPaste(text);
  123.     if (txTsPaste(text)) return TRUE;
  124.     return txPaste(text);
  125. }
  126.  
  127. static BOOL pop(tx *text)
  128. {
  129.     int ret = txPaste(text);
  130.     clipClear(HCLIP_WIN);
  131.     return ret;
  132. }
  133.  
  134. //2.00E2 TXCMD削除
  135. BOOL TXAPI txTsCbPop(tx *text)
  136. {
  137.     // 吐き出し(クリップボード連携)
  138.     // テキストスタックからPOP
  139.     // カーソルは移動しません
  140.     cutAtMouse(text);
  141.     if (IsClipOther(text)) return pop(text);
  142. #if 1//1.00E 1.00DだとTsが空の時にtxCopyした内容が出なかった
  143.     if (txTsPop(text)) {
  144.         clipClear(HCLIP_WIN);
  145.         return TRUE;
  146.     }
  147.     return pop(text);
  148. #else
  149.     #if 1//1.00D 一番最初にtxTsCbCopyした内容が重複した
  150.     clipClear(HCLIP_WIN);
  151.     return txTsPop(text);
  152.     #else
  153.     if (txTsPop(text)) return TRUE;
  154.     return pop(text);
  155.     #endif
  156. #endif
  157. }
  158.  
  159. static BOOL pastemodal(tx *text)
  160. {
  161.     return txClipPaste(text,HCLIP_WIN,text->fJumpTxPasteEnd,0);
  162. }
  163.  
  164. static BOOL _txTsCbPasteModal(tx *text,HCLIP* pHclip)
  165. {
  166.     // 貼り付け(テキストスタック連携)
  167.     // テキストスタックからペースト
  168.     // text->fJumpTxPasteEndが真ならカーソルを移動します
  169.     cutAtMouse(text);
  170.     *pHclip = HCLIP_WIN;
  171.     if (IsClipOther(text)) {
  172.         return pastemodal(text);
  173.     }
  174.     if (txTsPasteModal(text)) {
  175.         *pHclip = HCLIP_TS;
  176.         return TRUE;
  177.     }
  178.     return pastemodal(text);
  179. }
  180.  
  181. //2.00E {#MS},{#VZ} txClipboardPasteへ移動
  182. //2.00E2 TXCMD削除
  183. BOOL TXAPI txTsCbPasteModal(tx *text)
  184. {
  185.     // 貼り付け(テキストスタック連携)
  186.     // テキストスタックからペースト
  187.     // text->fJumpTxPasteEndが真ならカーソルを移動します
  188.     HCLIP hclip;
  189.     return _txTsCbPasteModal(text,&hclip);
  190. }
  191.  
  192. static BOOL popmodal(tx *text)
  193. {
  194.     int ret = txClipPaste(text,HCLIP_WIN,text->fJumpTxPasteEnd,0);
  195.     clipClear(HCLIP_WIN);
  196.     return ret;
  197. }
  198.  
  199. static BOOL _txTsCbPopModal(tx *text,HCLIP* pHclip)
  200. {
  201.     // 吐き出し(テキストスタック連携)
  202.     // テキストスタックからPOP
  203.     // text->fJumpTxPasteEndが真ならカーソルを移動します
  204.     cutAtMouse(text);
  205.     *pHclip = HCLIP_WIN;
  206.     if (IsClipOther(text)) return popmodal(text);
  207. #if 1//1.00E 1.00DだとTsが空の時にtxCopyした内容が出なかった
  208.     if (txTsPopModal(text)) {
  209.         clipClear(HCLIP_WIN);
  210.         *pHclip = HCLIP_TS;
  211.         return TRUE;
  212.     }
  213.     return popmodal(text);
  214. #else
  215.     #if 1//1.00D 一番最初にtxTsCbCopyした内容が重複した
  216.     clipClear(HCLIP_WIN);
  217.     return txTsPopModal(text);
  218.     #else
  219.     if (txTsPopModal(text)) return TRUE;
  220.     return popmodal(text);
  221.     #endif
  222. #endif
  223. }
  224.  
  225. //2.00E {#MS},{#VZ} txClipboardPopへ移動
  226. //2.00E2 TXCMD削除
  227. BOOL TXAPI txTsCbPopModal(tx *text)
  228. {
  229.     // 吐き出し(テキストスタック連携)
  230.     // テキストスタックからPOP
  231.     // text->fJumpTxPasteEndが真ならカーソルを移動します
  232.     HCLIP hclip;
  233.     return _txTsCbPopModal(text,&hclip);
  234. }
  235.  
  236. //2.00E2 TXCMD削除
  237. void TXAPI txTsCbClear(tx *text)
  238. {
  239. // テキストスタックのトップを消去します。
  240. // クリップボードにWZがペーストしたデータがあるときは、これも消去します。
  241. #if 0//1.00D
  242.     cutAtMouse(text);
  243. #endif
  244.     if (IsClipOther(text)) {
  245.         clipClear(HCLIP_WIN);
  246.     } else {
  247.         clipClear(HCLIP_WIN);
  248.         txTsClear(text);
  249.     }
  250. }
  251.  
  252. //2.00E カットアンドペースト系のコマンドが多かったので一本化。従来のコマンドはそのまま残っています。
  253.  
  254. LPVOID TXAPI plugatrRead(TX* text,TYP typ)
  255. {
  256.     return (LPVOID)txOp(text,TXOP_PLUG_READ,typ,0);
  257. }
  258.  
  259. static PLUGOLE* txIsCurOLE(TX* text)
  260. {
  261. #ifdef __FLAT__
  262.     if (text->editmode) {
  263.         CHARATR charatr;
  264.         charatrRead(text,txGetAddress(text),&charatr);
  265.         if (charatr.fLink) {
  266.             PLUGOLE* plug = plugatrRead(text,charatrGetPlug(charatr));
  267.             if (plug->head.modePlug == PLUG_OLE) {
  268.                 return plug;
  269.             }
  270.         }
  271.     }
  272.     return NULL;
  273. #else
  274.     return NULL;
  275. #endif
  276. }
  277.  
  278. BOOL TXAPI TXCMDBASE txClipboardCopy(TX* text)
  279. {
  280. // 範囲内をクリップボードへコピー
  281. // [設定]-[編集]-[クリップボード]の設定に従ってWindowsクリップボード/テキストスタックを使用
  282. //2.00Eで追加
  283.     //{#MS} ^C ^{Insert}
  284.     //{#VZ} ^KK +{F8} +%{Delete}
  285.     //{#EMACS} +{F8} +%{Delete}
  286. #if 0///2.99D 970329 OLEオブジェクトのコピーはいらない。アクティベートしてアプリケーションの機能でコピーすればいい
  287.     #ifdef __FLAT__
  288.     PLUGOLE* plugole;
  289.     if (!text->fClip && (plugole = txIsCurOLE(text))) {
  290.         return txOp(text,TXOP_OBJECTCOPY,(LPARAM)plugole,0);
  291.     }
  292.     #endif
  293. #endif
  294.     if (!text->fClip && !text->fClipboardNoSelect) return FALSE;//2.98 970307 
  295.     //2.95 970125 CLIPMODE_XXX対応
  296.     BOOL ret = FALSE;
  297.     switch(txGetModeClipboard(text)) {
  298.         case CLIPBOARD_WIN_TS: ret = txSelectTsCbPush(text);break;
  299.         case CLIPBOARD_WIN: ret = txSelectCopy(text);break;
  300.         case CLIPBOARD_TS: ret = txSelectTsPush(text);break;
  301.     }
  302.     if (text->fClipboardWinBased == CLIPMODE_WZ) txSelectQuit(text);
  303.     return ret;
  304. }
  305.  
  306. BOOL TXAPI TXCMDBASE txClipboardCut(TX* text)
  307. {
  308. // 範囲内をクリップボードへカット
  309. // [設定]-[編集]-[クリップボード]の設定に従ってWindowsクリップボード/テキストスタックを使用
  310. //2.00Eで追加
  311.     //{#MS} ^X +{Delete} +^{Delete}
  312.     //{#VZ} ^Y {F8} %{Delete}
  313.     //{#EMACS} {F8} %{Delete}
  314.     if (!text->fClip && !text->fClipboardNoSelect) return FALSE;//2.98 970307 
  315.     switch(txGetModeClipboard(text)) {
  316.         case CLIPBOARD_WIN_TS: return txSelectTsCbPushDelete(text);
  317.         case CLIPBOARD_WIN: return txSelectCopyDelete(text);
  318.         case CLIPBOARD_TS: return txSelectTsPushDelete(text);
  319.     }
  320.     return FALSE;
  321. }
  322.  
  323. static BOOL _txClipboardPaste(TX* text,BOOL fPop)
  324. {
  325.     //2.95 970125 CLIPMODE_XXX対応
  326.     txSetUndisp(text);//2.00E4 選択中にペーストするとちらついた
  327.     if (text->fClip) {
  328.         if (text->fClipboardWinBased == CLIPMODE_WZ) {
  329.             txSelectQuit(text);
  330.         } else {
  331.             txSelectDelete(text);
  332.         }
  333.     }
  334.     BOOL ret = FALSE;
  335.     IFILE adr = txGetAddress(text);
  336.     int ly = text->ly;
  337.     BOOL fSelectPaste = (text->fClipboardWinBased == CLIPMODE_WINWZ);
  338.     if (fSelectPaste) {
  339.         txSetUndisp(text);
  340.     }
  341.     HCLIP hclip = HCLIP_WIN;
  342.     if (fPop) {
  343.         switch(txGetModeClipboard(text)) {
  344.             case CLIPBOARD_WIN_TS: ret = _txTsCbPopModal(text,&hclip);break;
  345.             case CLIPBOARD_WIN: {
  346.                 ret = txPaste(text);
  347.                 clipClear(HCLIP_WIN);
  348.                 break;
  349.             }
  350.             case CLIPBOARD_TS: ret = txTsPopModal(text);hclip = HCLIP_TS;break;
  351.         }
  352.     } else {
  353.         switch(txGetModeClipboard(text)) {
  354.             case CLIPBOARD_WIN_TS: ret = _txTsCbPasteModal(text,&hclip);break;
  355.             case CLIPBOARD_WIN: ret = txPaste(text);break;
  356.             case CLIPBOARD_TS: ret = txTsPasteModal(text);hclip = HCLIP_TS;break;
  357.         }
  358.     }
  359.     if (fSelectPaste) {
  360.         if (ret) {
  361. #if 1        //2.95 970125 行単位選択でコピーして、行の途中でペーストすると、
  362.             // ペーストした文の選択がズレた。
  363.             int lyClip = text->ly;
  364.             txSetUndisp(text);
  365.             if (text->fClipPasteJump) {
  366.                 txJumpAddress(text,text->clippastetop);
  367.                 txSelectEx(text,CLIP_CHAR);
  368.                 txJumpAddress(text,text->clippasteend);
  369.                 txSetLy(text,lyClip);
  370.             } else {
  371.                 txJumpAddress(text,text->clippasteend);
  372.                 txSelectEx(text,CLIP_CHAR);
  373.                 txJumpAddress(text,text->clippastetop);
  374.                 txSetLy(text,ly);
  375.             }
  376.             text->fClipMouse = TRUE;
  377.             txSetDisp(text);
  378. #else
  379.             txSelectEx(text,CLIP_CHAR);
  380.             text->fClipMouse = TRUE;
  381.             txJumpAddress(text,adr);
  382.             txSetLy(text,ly);
  383. #endif
  384.         }
  385.         txSetDisp(text);
  386.     }
  387.     txSetDisp(text);//2.00E4 
  388.     return ret;
  389. }
  390.  
  391. BOOL TXAPI TXCMDBASE txClipboardPaste(TX* text)
  392. {
  393. // クリップボードからペースト
  394. // [設定]-[編集]-[クリップボード]の設定に従ってWindowsクリップボード/テキストスタックを使用
  395. //2.00Eで追加
  396.     //{#MS} ^V +{Insert}
  397.     //{#VZ} ^KC +{F9} +%{Insert}
  398.     //{#EMACS} +{F9} +%{Insert} ^Y
  399.     return _txClipboardPaste(text,FALSE);
  400. }
  401.  
  402. //3.00B1 970522 追加カット、追加コピーを追加
  403.  
  404. BOOL TXAPI TXCMDBASE txClipboardAddCopy(TX* text)
  405. {
  406. // 範囲内をクリップボードへ追加コピー
  407. // [設定]-[編集]-[クリップボード]の設定に従ってWindowsクリップボード/テキストスタックを使用
  408. //3.00B1 970522 new
  409.     TX* text0 = text;
  410.     BOOL ret = FALSE;
  411.     {
  412.         TX* text = textopen(NULL);
  413.         if (text) {
  414.             txClipboardPaste(text);
  415.             txPrivatePush(text0);
  416.             txPrivatePop(text);
  417.             txSelectAll(text);
  418.             ret = txClipboardCopy(text);
  419.         }
  420.         textclose(text);
  421.     }
  422.     return ret;
  423. }
  424.  
  425. BOOL TXAPI TXCMDBASE txClipboardAddCut(TX* text)
  426. {
  427. // 範囲内をクリップボードへ追加カット
  428. // [設定]-[編集]-[クリップボード]の設定に従ってWindowsクリップボード/テキストスタックを使用
  429. //3.00B1 970522 new
  430.     TX* text0 = text;
  431.     BOOL ret = FALSE;
  432.     {
  433.         TX* text = textopen(NULL);
  434.         if (text) {
  435.             txClipboardPaste(text);
  436.             txPrivatePush(text0);
  437.             txSelectDelete(text0);
  438.             txPrivatePop(text);
  439.             txSelectAll(text);
  440.             ret = txClipboardCopy(text);
  441.         }
  442.         textclose(text);
  443.     }
  444.     return ret;
  445. }
  446.  
  447. BOOL TXAPI TXCMD txClipboardPasteReplace(TX* text)
  448. {
  449. // クリップボードからペースト
  450. // 範囲選択されてたら、それを削除してからtxClipboardPasteする。
  451. //3.00A2 970507 new
  452.     if (text->fClip) txSelectDelete(text);
  453.     return txClipboardPaste(text);
  454. }
  455.  
  456. BOOL TXAPI TXCMDBASE txClipboardPop(TX* text)
  457. {
  458. // クリップボードからポップ
  459. // [設定]-[編集]-[クリップボード]の設定に従ってWindowsクリップボード/テキストスタックを使用
  460. //2.00Eで追加
  461.     //{#MS} +^V +^{Insert}
  462.     //{#VZ} ^J {F9} %{Insert}
  463.     //{#EMACS} {F9} %{Insert}
  464.     return _txClipboardPaste(text,TRUE);
  465. }
  466.  
  467. BOOL TXAPI TXCMD txClipboardPopReplace(TX* text)
  468. {
  469. // クリップボードからポップ
  470. // 範囲選択されてたら、それを削除してからtxClipboardPopする。
  471. //3.00A2 970507 new
  472.     if (text->fClip) txSelectDelete(text);
  473.     return txClipboardPop(text);
  474. }
  475.  
  476. BOOL TXCMDBASE txClipboardCopyWord(TX* text)
  477. {
  478. // 単語を選択してクリップボードへコピー。
  479. // 2.91で追加。
  480.     txSelectEx(text,CLIP_WORD);
  481.     txstr sz;
  482.     txGetWord(text,sz);
  483.     txClipboardCopy(text);
  484.     statprintf(sz);
  485.     return TRUE;
  486. }
  487.  
  488. //{###編集}
  489.  
  490. // 以下の関数はもう不要であるが互換性の為、残しておく
  491. tabtospace
  492. {
  493. // テキスト全体で、タブをスペースに変換します
  494.     txTabToSpace(text);
  495. }
  496.  
  497. spacetotab
  498. {
  499. // テキスト全体で、行頭のスペースをタブに変換します
  500.     txSpaceToTab(text);
  501. }
  502.  
  503. deletetailspace
  504. {
  505. // テキスト全体で、行末のタブ/スペース/全角空白を削除します。
  506.     txDeleteTailSpace(text);
  507. }
  508.  
  509. //{###編集}
  510.  
  511.  
  512. //2.96 970210 txDeleteCharMs廃止。edit.txkeyDeleteCharを使ってください。
  513. //2.96 970210 txDeletePrevMs廃止。edit.txkeyDeletePrevを使ってください。
  514.  
  515. extern "word" BOOL TXAPI TXCMD txFormArticleClear(tx *text);
  516.  
  517. static int txGetPrevPlugmode(TX* text)
  518. {
  519. // カーソル位置の一つ手前の文字のplugmodeを返す
  520. //2.99D 970329 new
  521.     if (text->editmode) {
  522.         IFILE adr = txGetAddress(text);
  523.         if (adr >= 1) {
  524.             CHARATR charatr;
  525.             charatrRead(text,adr-1,&charatr);
  526.             if (charatr.fLink) {
  527.                 return plugatrGetModePlug(text,charatrGetPlug(charatr));
  528.             }
  529.         }
  530.     }
  531.     return 0;
  532. }
  533.  
  534. //2.99D 970329 OLEオブジェクトをDeleteやBackspaceで削除するときは問い合わせをするようにした
  535. static int questionOleDelete(void)
  536. {
  537.     #ifdef __FLAT__//強制ACTIVE
  538.     wndtxSetActive(textf->hwndbase);
  539.     #endif
  540.     return MessageBox(
  541.         wndtxGetActive(textf->hwndbase),
  542.         "OLEオブジェクトは削除するとアンドゥできません\n本当に削除しても良いですか?",
  543.         "WZ",MB_ICONQUESTION|MB_YESNOCANCEL|MB_DEFBUTTON2
  544.     );
  545. }
  546.  
  547. int TXAPI TXCMDBASE TXMODAL txkeyDeletePrev(TX* text)
  548. {
  549. // 1文字前方削除(バックスペース)
  550. // カーソルがフリーカーソル域に居るときはtxkeyLeftを実行します。
  551. // 上書きモードのときは、txkeyLeftを実行します。
  552. //{#VZ} {Backspace} ^H
  553. //{#MI} {Backspace} ^H
  554. //{#MS} {Backspace}
  555. //{#EMACS} {Backspace}
  556. //2.96 970210 WZ.EXEから移動
  557. #if 1///3.00A 970430 VZ.KEYで^Bによる範囲選択中にBSすると範囲部分が削除された
  558.     if (
  559.         text->fClipMouse ||
  560.         (text->fClip && text->modeEditor == ME_WIN)
  561.     ) {
  562.         txSelectDelete(text);
  563.         return TRUE;
  564.     }
  565. #else
  566.     if (text->fClip) {//2.96 970209 
  567.         txSelectDelete(text);
  568.         return TRUE;
  569.     }
  570. #endif
  571.     if (text->fHTML && !text->fDispTag) {
  572.         //2.99B 970322 タグを消しているときに{Backspace}でタグを削除しないようにした
  573. #if 1//2.99D 970329 
  574.         if (txGetPrevPlugmode(text) == PLUG_HTML_TAG) {
  575.             statprintf("タグの表示をオフにしているので、タグは削除しません");
  576.             return FALSE;
  577.         }
  578. #else
  579.         IFILE adr = txGetAddress(text);
  580.         if (adr >= 1) {
  581.             CHARATR charatr;
  582.             charatrRead(text,adr-1,&charatr);
  583.             if (charatr.fLink && plugatrGetModePlug(text,charatrGetPlug(charatr)) == PLUG_HTML_TAG) {
  584.                 statprintf("タグの表示をオフにしているので、タグは削除しません");
  585.                 return FALSE;
  586.             }
  587.         }
  588. #endif
  589.     }
  590.     if (!text->fClip && txGetPrevPlugmode(text) == PLUG_OLE) {
  591.         int ret = questionOleDelete();
  592.         if (ret != IDYES) return FALSE;
  593.     }
  594.     if (txIsCurFree(text)) {
  595.         txkeyLeft(text);
  596.         if (!txIsCurFree(text)) {
  597.             if (!txIsCurReturn(text)) txDeleteChar(text);
  598.         }
  599.         return FALSE;
  600.     }
  601.     if (text->fOverWrite) {
  602.         txkeyLeft(text);
  603.         return FALSE;
  604.     }
  605.     if (text->editmode && text->fAfArticleDisc && txIsCurParaTop(text)) {
  606.         //2.98 970309 fAfArticleDiscがONのとき行頭BSで箇条書きクリア
  607.         PARAATR paraatr;
  608.         paraatrRead(text,text->npara,¶atr);
  609.         if (paraatr.fArticle) {
  610.             //2.98A 970311 実際に箇条書きがあるときだけ実行しないと、行頭でBSが効かなくなる。
  611.             txFormArticleClear(text);
  612.             return TRUE;
  613.         }
  614.     }
  615.     return txDeletePrev(text);
  616. }
  617.  
  618. static int _txkeyDeleteChar(TX* text,int modeEditor)
  619. {
  620. // 1文字削除
  621.     if (!text->fClip && text->fHTML) {
  622.         if (!text->fDispTag && txGetCurPlugmode(text) == PLUG_HTML_TAG) {
  623.             //2.99B 970322 タグを消しているときに{Delete}でタグを削除しないようにした
  624.             statprintf("タグの表示をオフにしているので、タグは削除しません");
  625.             return FALSE;
  626.         }
  627. #if 0//2.99D 970331 HTMLテキストモードでタグ'<'で{Delete}したときタグを丸ごと削除するのは不自然なのでやめた
  628.         if (call("html.htmlDeleteTag")) return TRUE;
  629. #endif
  630.     }
  631.     if (!text->fClip && txGetCurPlugmode(text) == PLUG_OLE) {
  632.         int ret = questionOleDelete();
  633.         if (ret != IDYES) return FALSE;
  634.     }
  635.     if (modeEditor == ME_WIN) {
  636.         if (text->fClip) {
  637.             txSelectDelete(text);
  638.             return TRUE;
  639.         } else {
  640.             if (text->modeAutoIndent && !txIsCurParaTop(text) && txIsCurReturn(text)) {
  641.                 txDeleteChar(text);
  642.                 if (txGetChar(text) == ' ' || txGetChar(text) == '\t') {
  643.                     txDeleteWord(text);
  644.                 }
  645.             } else {
  646.                 txDeleteChar(text);
  647.             }
  648.         }
  649.         return TRUE;
  650.     } else {
  651.         if (text->fClipMouse) {//3.00A 970429 VZ.KEY,MI.KEY:マウスで選択してDeleteすると範囲内を削除するようにした
  652.             txSelectDelete(text);
  653.             return TRUE;
  654.         }
  655.         if (txIsCurFree(text)) return FALSE;
  656.         return txDeleteChar(text);
  657.     }
  658. }
  659.  
  660. //2.99D 970402 new
  661. int TXCMDBASE txkeyDeleteCharMs(TX* text)
  662. {
  663. // ユーザインターフェースの設定にかかわらず、Windows準拠な文字削除
  664.     return _txkeyDeleteChar(text,ME_WIN);
  665. }
  666.  
  667. int TXAPI TXCMDBASE txkeyDeleteChar(TX* text)
  668. {
  669. // 1文字削除(ユーザインターフェース)
  670. // ユーザインターフェースの設定によって動作が変わります
  671. //{#RET}削除できたか返す
  672. //{#VZ} {Delete} ^G
  673. //{#MI} {Delete} ^G 
  674. //{#MS} {Delete}
  675. //{#EMACS} {Delete} ^D
  676.     return _txkeyDeleteChar(text,text->modeEditor);
  677. }
  678.  
  679. int TXCMDBASE txkeyDeleteWord(TX* text)
  680. {
  681. // 単語削除(ユーザインターフェース)
  682. // ユーザインターフェースの設定によって動作が変わります
  683. //2.99A 970321 {#MS} ^{Delete} new
  684. //{#MS} ^{Delete}
  685.     if (text->modeEditor == ME_MI) return txDeleteWordMi(text);
  686.     return txDeleteWord(text);
  687. }
  688.  
  689. int TXCMDBASE txkeyDeletePrevWord(TX* text)
  690. {
  691. // 前単語削除(ユーザインターフェース)
  692. // ユーザインターフェースの設定によって動作が変わります
  693. //2.99A 970321 {#MS} ^{Backspace} new
  694. //{#MS} ^{Backspace}
  695.     return txDeletePrevWord(text);
  696. }
  697.  
  698. int TXCMDBASE txkeySelect(TX* text)
  699. {
  700. // 選択開始(ユーザインターフェース)
  701. // ユーザインターフェースの設定によって動作が変わります
  702. // 選択中なら、選択を中止
  703.     if (text->modeEditor == ME_MI) return txSelect(text);
  704.     if (text->modeEditor == ME_VZ) return txSelectVz(text);
  705.     return txSelectWz(text);
  706. }
  707.  
  708. vzZenhan
  709. {
  710.     // 全角/半角変換
  711.     // カーソル位置から1語を変換
  712.     // 範囲選択しているときは、その範囲を変換。範囲の先頭文字
  713.     // を見てどちらの変換をするか判断します。
  714.     //2.99A 970321 {#MS} ^{F3} ^%U -> {#MS} ^%U
  715.     //{#MS} ^%U
  716.     //{#VZ} ^KZ
  717. #if 1///2.00E6 範囲選択を解除する動作を改良
  718.     txSetUndisp(text);
  719.     int fClip = text->fClip;
  720.     if (text->fClip) {
  721.         txJumpSelectTop(text);
  722.     } else {
  723.         txSelect(text);
  724.         if (isspace(txGetChar(text))){
  725.             txRightWord(text);
  726.         } else {
  727.             txJumpWordEnd(text);
  728.         }
  729.         txJumpSelectTop(text);
  730.     }
  731.     if (txchIsKanji(txGetChar(text))) {
  732.         txJankToAnk(text);
  733.         txJkataToKana(text);
  734.     } else {
  735.         txAnkToJank(text);
  736.         txKanaToJkata(text);
  737.     }
  738.     if (fClip) {
  739.         text->fClipMouse = TRUE;
  740.     } else {
  741.         // 範囲選択してないときは次の文字へ移動
  742.         txJumpSelectEnd(text);
  743.         txSelectQuit(text);
  744.     }
  745.     txSetDisp(text);
  746. #else
  747.     setundisp;
  748.     if (text->fClip==0) {
  749.         select;
  750.         if (isspace(getchar)){
  751.             rightword;
  752.         } else {
  753.     #if 1//1.00C
  754.             jumpwordend;
  755.     #else
  756.             jumpwordendmi;
  757.             while (isspace(getchar)){
  758.                 left;
  759.             }
  760.             right;
  761.     #endif
  762.         }
  763.     }
  764.     txstr buff;
  765.     getword(buff);
  766.     mchar c = buff[0];
  767. //    if (c>=' '&&c<='~'||c>='「'&&c<='゚') {
  768.     if (!iskanji(c)) {//1.00C
  769.         anktojank;
  770.         kanatojkata;
  771.     } else {
  772.         janktoank;
  773.         jkatatokana;
  774.     }
  775. //    selectjump;
  776.     select;
  777.     setdisp;
  778. #endif
  779. }
  780.  
  781. int uiIsCaseWordUpper(void)
  782. {
  783.     HDIALOG hd = dialog("大文字/小文字変換");
  784.     int mode = 0;
  785.     dialogRadioID(hd,&mode,"大文字→小文字","小文字→大文字");
  786.     if (dialogOpen(hd)) {
  787.         if (mode == 1) return IDNO;
  788.         return IDYES;
  789.     }
  790.     return IDCANCEL;
  791. }
  792.  
  793. //2.00E6 txCaseWord -> edit.txCaseWord
  794. BOOL TXCMDBASE txCaseWord(TX* text)
  795. {
  796.     // 大文字/小文字変換(半角文字のみ変換)
  797.     // カーソル位置から1語を変換
  798.     // カーソル位置の文字を見てどちらの変換をするか判断します。
  799.     // 範囲選択しているときは、その範囲を変換。
  800.     // 大文字に変換するか小文字に変換するか問い合わせます。
  801.     //{#MI} ^QK
  802.     if (text->fClip) {
  803.         int ret = uiIsCaseWordUpper();
  804.         if (ret == IDCANCEL) return;
  805.         if (ret == IDYES) {
  806.             txEditOp(text,TXEDITOP_TOLOWER,NULL);
  807.         } else {
  808.             txEditOp(text,TXEDITOP_TOUPPER,NULL);
  809.         }
  810.     } else {
  811.         txEditOp(text,TXEDITOP_TOUPPER,NULL);
  812.     }
  813.     return TRUE;
  814. }
  815.  
  816. vzCaseWord
  817. {
  818.     // 大文字/小文字変換(全角対応)
  819.     // カーソル位置から1語を変換
  820.     // 範囲選択しているときは、その範囲を変換。
  821.     // 範囲の先頭文字を見てどちらの変換をするか判断します。
  822.     //2.99A 970321 {#MS} +{F3} ^U +^U -> {#MS} +^U
  823.     //{#MS} +^U
  824.     //{#VZ} ^QU
  825. #if 1///2.00E6 高速モードでvzCaseWordを実行すると支障があった
  826.     txSetUndisp(text);
  827.     int fClip = text->fClip;
  828.     if (text->fClip) {
  829.         txJumpSelectTop(text);
  830.     } else {
  831.         txSelect(text);
  832.         txJumpWordEndMi(text);
  833.         txJumpSelectTop(text);
  834.     }
  835.     TXCHAR c = txGetChar(text);
  836.     BOOL fKanji = txchIsKanji(c);
  837.     if (fKanji) {
  838.         txJankToAnk(text);
  839.         c = txGetChar(text);
  840.     }
  841.     txEditOp(text,islower(c)?TXEDITOP_TOUPPER:TXEDITOP_TOLOWER,NULL);
  842.     if (fKanji) {
  843.         txAnkToJank(text);
  844.     }
  845.     if (fClip) {
  846.         text->fClipMouse = TRUE;
  847.     } else {
  848.         txSelectQuit(text);
  849.     }
  850.     txSetDisp(text);
  851.     return TRUE;
  852. #else
  853.     //2.00E6 buffに文字列をコピーして、あとでinsertする手法は、
  854.     // 図やCHARATRの兼ね合いのため、高速モードでは無効
  855.     setundispex;//1.00C 折り返しを含む単語を変換するとスクロールしていた
  856.     if (text->fClip==0) {
  857.         select;
  858.         jumpwordendmi;
  859. //        right;//1.00C
  860.     }
  861.     txstr buff;
  862.     getword(buff);
  863.     mchar c = buff[0];
  864.     BOOL f;
  865.     if ((c>='!'&&c<='~')||(c>='「'&&c<='゚')) {
  866.         f=FALSE;
  867.     } else {
  868.         f=TRUE;
  869.         janktoank;
  870.         jkatatokana;
  871.     }
  872.     getword(buff);
  873.     c=buff[0];
  874.     if (c>='A'&&c<='Z') { strlwr(buff); }
  875.     if (c>='a'&&c<='z') { strupr(buff); }
  876.     selectdelete;
  877.     IFILE ad = getaddress;
  878.     insert(buff);
  879.     select;
  880.     jumpaddress(ad);
  881.     if(f){
  882.         anktojank;
  883.         kanatojkata;
  884.     }
  885.     selectquit;
  886.     setdispex;//1.00C
  887. #endif
  888. }
  889.  
  890.  
  891. vzuiInsertFind
  892. {
  893.     // 選択文字列の複写
  894.     // 検索文字列ヒストリーの内容をダイアログで選択して
  895.     // カーソル位置へペースト。
  896.     //2.95 970131 uiInsertFindを新設しました。そちらを使ってください
  897.     txstr str1=histRead(HIST_SEARCH,histGetCount(HIST_SEARCH)-1);//1.00B 選択文字列の複写でファイルヒストリの内容がデフォルト表示された
  898.     HDIALOG hd = dialog("複写文字列");
  899.     dialogControlHist(hd,HIST_SEARCH);
  900.     dialogStr(hd,"",str1,4,30);
  901.     if(dialogOpen(hd)){
  902.         insertfind;
  903.     }
  904. }
  905.  
  906. #define IDD_INSERTFIND    100
  907.  
  908. BOOL dlgprocInsertFind(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  909. {
  910.     HDIALOG hd = dialogFromHwnd(hwnd);
  911.     switch(message) {
  912.         case WM_INITDIALOG: {
  913.             HWND hctrl = GetDlgItem(hwnd,IDD_INSERTFIND);
  914.             HSTRBLK sb = sbFromHist(HIST_SEARCH);
  915.             int n = sbGetCount(sb);
  916.             while(n--) {
  917.                 ListBox_AddString(hctrl,sbRead(sb,n));
  918.             }
  919.             ListBox_SetCurSel(hctrl,0);
  920.             break;
  921.         }
  922.         case WM_COMMAND: {
  923.             int id = WM_COMMAND_GetId(wParam);
  924.             int notify = WM_COMMAND_GetNotify(wParam,lParam);
  925.             if (id == IDOK) {
  926.                 HWND hctrl = GetDlgItem(hwnd,IDD_INSERTFIND);
  927.                 int isel = ListBox_GetCurSel(hctrl);
  928.                 if (isel >= 0) {
  929.                     txstr sz(ListBox_GetTextLen(hctrl,isel)+1);
  930.                     if (sz) {
  931.                         ListBox_GetText(hctrl,isel,sz);
  932.                         txInsert(text,sz);
  933.                         histAdd(HIST_SEARCH,sz);
  934.                     }
  935.                 }
  936.             }
  937.             break;
  938.         }
  939.     }
  940.     return FALSE;
  941. }
  942.  
  943. BOOL TXCMDBASE uiInsertFind(TX* text)
  944. {
  945.     // 過去に検索した文字列を挿入
  946.     // 検索文字列ヒストリの内容をダイアログで選択して
  947.     // カーソル位置へ挿入。
  948.     //{#MS} ^%I
  949.     //{#VZ} ^KA +{F7}
  950.     //{#EMACS} +{F7}
  951.     HDIALOG hd = dialog("過去に検索した文字列を挿入");
  952.     dialogSetHookEx(hd,"\m.dlgprocInsertFind");
  953.     DTRECT r;
  954.     dialogGetPos(hd,&r);
  955.     r.cx = DTCX * 30;
  956.     r.cy = DTCY * 10;
  957.     __dialogAddItem(hd,"LISTBOX",NULL,IDD_INSERTFIND,&r,LBS_NOTIFY|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP);
  958.     return dialogOpen(hd);
  959. }
  960.  
  961. static UINT _insertBrace(TX* text,UINT index)
  962. {
  963.     static mchar szkakko[] = "[]「」〔〕『』【】《》";
  964.     txSetUndisp(text);
  965.     TXCHAR ch = txGetChar(text);
  966.     mchar *p = strchr(szkakko,ch);
  967.     if (p && (((p - szkakko) / 2) % 2 == 1)) {
  968.         txDeletePrev(text);
  969.         txDeleteChar(text);
  970.         // next
  971.         p += 2;
  972.         if (*p == 0) p = szkakko;
  973.     } else {
  974.         int n = strlen(szkakko) / 4;
  975.         if (index < n) {
  976.             p = szkakko + index * 4;
  977.         } else {
  978.             p = szkakko;
  979.         }
  980.     }
  981.     txInsert(text,strleft(p,4));
  982.     txLeft(text);
  983.     txSetDisp(text);
  984.     return (p - szkakko) / 4;
  985. }
  986.  
  987. permanent p_iBrace;
  988.  
  989. insertBrace
  990. {
  991. // 全角括弧挿入(学習つき)
  992. // 全角括弧のペアを挿入後、カーソルを括弧の中にセット
  993. // 連続して実行すると、いくつかの種類の括弧をトグル切り替え
  994. // 最後に挿入したペアを覚えていて、次挿入するときは、そのペアを挿入します。
  995. //{#MS} +^K
  996. //{#MI} +^K
  997. //{#VZ} ^]
  998. //3.00A3 970507 new
  999.     p_iBrace = _insertBrace(text,p_iBrace);
  1000. }
  1001.  
  1002. //3.00A2 970507 {#MS} ^%] -> +^K
  1003. //3.00A2 970507 {#MI} +^K に割り当て
  1004. //3.00A3 970507 vzInsertBrace:{#MS} +^K , {#MI} +^K , {#VZ} ^]キー 割り当て解除。代わりにinsertBraceに割り当て
  1005. vzInsertBrace
  1006. {
  1007. // 全角括弧挿入
  1008. // 全角括弧のペアを挿入後、カーソルを括弧の中にセット
  1009. // 連続して実行すると、いくつかの種類の括弧をトグル切り替え
  1010. #if 1///3.00A3 970507 
  1011.     _insertBrace(text,0);
  1012. #else
  1013.     static mchar szkakko[] = "[]「」〔〕『』【】《》";
  1014.     #if 1//1.01A 
  1015.     setundisp;
  1016.     TXCHAR ch = getchar;
  1017.     mchar *p = strchr(szkakko,ch);
  1018.     if (p && (((p - szkakko) / 2) % 2 == 1)) {
  1019.         deleteprev;
  1020.         deletechar;
  1021.         // next
  1022.         p += 2;
  1023.         if (*p == 0) p = szkakko;
  1024.     } else {
  1025.         p = szkakko;
  1026.     }
  1027.     insert(strleft(p,4));
  1028.     left;
  1029.     setdisp;
  1030.     #else
  1031.     setundisp;
  1032.     mchar *c;
  1033.     txstr c0;
  1034.     c=strchr(szkakko,getchar);
  1035.     if (c) {
  1036.         deletechar; deleteprev;
  1037.         c0=strrear(c,2);
  1038.         if(strlen(c0)==0) c0=szkakko;
  1039.     } else {
  1040.         c0=szkakko;
  1041.     }
  1042.     insert(strleft(c0,4));
  1043.     left;
  1044.     setdisp;
  1045.     #endif
  1046. #endif
  1047. }
  1048.  
  1049. //2.00E6 キー割り当てされてなかったので#WZKEY {Enter}を削除
  1050. WriteReturnC
  1051. {
  1052.     // Cインデント展開改行
  1053.     // '{'の直後で実行するとCインデントに展開します。その他の位置では
  1054.     // 通常の改行として働きます。Enterキーに割り当てて利用します。
  1055. #if 1//2.99C 970325 Cインデント展開改行 改良
  1056.     if (
  1057.         !text->fOverWrite &&    // 上書き時は展開しない
  1058.         txIsCurReturn(text) && 
  1059.         txGetCharPrev(text) == '{'
  1060.     ) {
  1061.         txWriteReturn(text);
  1062.         txWriteReturn(text);
  1063.         txInsert(text,"}");
  1064.         txLeft(text);//2.00E6 タブの前に空白が入った
  1065.         txUp(text);
  1066.         txWriteTab(text);
  1067.     } else {
  1068.         txWriteReturn(text);
  1069.     }
  1070. #else
  1071.     if (
  1072.         text->cur0 && text->buff[text->cur0 - 1] == '{' &&
  1073.         !text->fOverWrite//2.00E6 上書き時は展開しない
  1074.     ) {
  1075.         txWriteReturn(text);
  1076.         txWriteReturn(text);
  1077.         txInsert(text,"}");
  1078.         txLeft(text);//2.00E6 タブの前に空白が入った
  1079.         txUp(text);
  1080.         txWriteTab(text);
  1081.     } else {
  1082.         txWriteReturn(text);
  1083.     }
  1084. #endif
  1085. }
  1086.  
  1087.  
  1088. //{###カット&ペースト}
  1089.  
  1090. txDupePara
  1091. {
  1092.     // 論理行の複写
  1093.     // カーソル位置の論理行を二重化。
  1094.     //{#VZ} ^KD
  1095.     //{#MI} +{F10}
  1096.     SelectTsPushQuit;
  1097.     tspop;
  1098. }
  1099.  
  1100. clipCopyFilename
  1101. {
  1102. // テキストのファイル名をクリップボードへコピー
  1103. //3.00A2 970505 new VZ.KEY:^QNに割り当て
  1104. //{#VZ} ^QN
  1105.     if (text->szfilename[0]) {
  1106.         memClipCopy(text->szfilename,strlen(text->szfilename),HCLIP_WIN,CLIP_CHAR);
  1107.         return TRUE;
  1108.     }
  1109.     return FALSE;
  1110. }
  1111.  
  1112. //{###編集}
  1113.  
  1114. insertFilename
  1115. {
  1116. // テキストのファイル名をフルパスで挿入
  1117. //3.00A2 970505 new
  1118.     txInsert(text,text->szfilename);
  1119. }
  1120.  
  1121. BOOL TXCMDBASE OpenContextMenu(TX* text)
  1122. {
  1123. // 状況に応じた右クリックメニューを開く。
  1124. // {#MS} +{F10}
  1125.     txstr szMenu;
  1126.     if (text->fClip) {
  1127.         szMenu = text->szMenuMouseRClip;
  1128.     } else {
  1129.         szMenu = text->szMenuMouseR;
  1130.     }
  1131. //information(text->szMenu);
  1132.     if (!strnicmp(szMenu,"macro:",6)) {//3.00A3 970507 右クリックメニューにマクロを指定できるようにした。"macro:test.main"の様に指定しておくと、"test.main"を呼び出す。
  1133.         call(&szMenu[6]);
  1134.         return TRUE;
  1135.     }
  1136.     call("menu." + szMenu);
  1137.     return TRUE;
  1138. }
  1139.  
  1140. //旧:usermenu.umcMouseR
  1141. //あんまり多すぎると、VGAではみ出してしまう
  1142. //3.00A 970427 {#EMACS} {MouseR}追加
  1143. menuMouseR
  1144. {
  1145. #WZKEY
  1146. // 右クリックメニュー
  1147. //{#MS} {MouseR}
  1148. //{#VZ} {MouseR}
  1149. //{#MI} {MouseR}
  1150. //{#EMACS} {MouseR}
  1151.     OpenContextMenu(text);//2.91 
  1152. //    call("menu." + text->szMenuMouseR);
  1153. }
  1154.  
  1155. //旧:usermenu.umcMouseRClip
  1156. //3.00A 970427 {#EMACS} {MouseRClip}追加
  1157. menuMouseRClip
  1158. {
  1159. #WZKEY
  1160. // 選択時の右クリックメニュー
  1161. //{#MS} {MouseRClip}
  1162. //{#VZ} {MouseRClip}
  1163. //{#MI} {MouseRClip}
  1164. //{#EMACS} {MouseRClip}
  1165.     OpenContextMenu(text);//2.91 
  1166. //    call("menu." + text->szMenuMouseRClip);
  1167. }
  1168.  
  1169.  
  1170. err_undo
  1171. {
  1172.     statprintf("これ以上やり直しできません");
  1173.     if (text->fbeep) MessageBeep(MB_ICONEXCLAMATION);
  1174. }
  1175.  
  1176. ViewToEdit
  1177. {
  1178.     txSwitchViewMode(text);
  1179.     txKeyLoad(text);
  1180. }
  1181.  
  1182. //2.99 970320 
  1183. extern "word" {
  1184. BOOL TXAPI TXCMD txInsertBeamtab(TX* text);
  1185. BOOL TXAPI TXCMD txFormIndentInc(tx *text);
  1186. BOOL TXAPI TXCMD txFormIndentDec(tx *text);
  1187. }
  1188.  
  1189. //1.99H 
  1190. BOOL TXCMDBASE tab(TX* text)
  1191. {
  1192. // 文字範囲選択なら、選択範囲を消去してタブに置き換えます。
  1193. // 行範囲選択なら、インデントを増加します。
  1194. // 上書きモードなら、カーソルを次のタブ位置へ進めます。
  1195. // 挿入モードなら、タブを挿入します。
  1196. //{#MS} {Tab}
  1197. //{#VZ} {Tab} ^I
  1198. //{#MI} {Tab} ^I
  1199. //{#EMACS} {Tab}
  1200.     if (text->fClip && txIsClipInPara(text)) {
  1201.         // 文字範囲選択なら、選択範囲を消去してタブに置き換える。
  1202.         txSelectDelete(text);
  1203.         {
  1204.             BOOL fOverWrite0 = text->fOverWrite;
  1205.             text->fOverWrite = FALSE;
  1206.             txWriteTab(text);
  1207.             text->fOverWrite = fOverWrite0;
  1208.         }
  1209.     } else if (text->fClip) {
  1210. #if 1//2.99 970320 
  1211.         if (txIsWP(text)) {
  1212.             txFormIndentInc(text);
  1213.         } else {
  1214.             txIndentInc(text);
  1215.         }
  1216. #else
  1217.         if (text->editmode == 0) {
  1218.             txIndentInc(text);
  1219.         } else {
  1220.             call("word.txFormIndentDec");
  1221.         }
  1222. #endif
  1223.     } else if (txIsWP(text)) {
  1224.         //2.99C 970327 表で{TAB}入力が変だった
  1225.         PLUGTAB* plug = txIsCurParaIncludeTable(text);
  1226.         if (plug && plug->modeTab == MODETAB_TABLE) {
  1227.             txWriteTab(text);
  1228.         } else {
  1229.             //2.99 970320 体裁/詳細モードでは、タブで字下げ及び桁揃えを行う様にした
  1230.             // <TX>文書では、行頭タブは字下げと見なされるので、通常のタブを挿入しても仕方がない
  1231.             if (txIsCurParaTop(text)) {
  1232.                 txFormIndentInc(text);
  1233.             } else {
  1234.                 txInsertBeamtab(text);
  1235.             }
  1236.         }
  1237.     } else {
  1238.         txWriteTab(text);
  1239.     }
  1240.     return TRUE;
  1241. }
  1242.  
  1243. //1.99H 
  1244. BOOL TXCMDBASE tabPrev(TX* text)
  1245. {
  1246. // 文字範囲選択なら、選択範囲を消去します。
  1247. // 行範囲選択なら、インデントを減らします。
  1248. // 選択中でなければ行頭のタブを削除します。
  1249. //{#MS} +{Tab}
  1250. //{#VZ} +{Tab}
  1251. //{#MI} +{Tab}
  1252. //{#EMACS} +{Tab}
  1253.     if (text->fClip && txIsClipInPara(text)) {
  1254.         // 文字範囲選択なら、選択範囲を消去
  1255.         txSelectDelete(text);
  1256.     } else if (text->fClip) {
  1257. #if 1//2.99 970320 
  1258.         if (txIsWP(text)) {
  1259.             txFormIndentDec(text);
  1260.         } else {
  1261.             txIndentDec(text);
  1262.         }
  1263. #else
  1264.         if (text->editmode == 0) {
  1265.             txIndentDec(text);
  1266.         } else {
  1267.             call("word.txFormIndentDec");
  1268.         }
  1269. #endif
  1270.     } else if (txIsWP(text)) {
  1271.         //2.99 970320 体裁/詳細モードでは、Shift+タブで字下げの解除を行う様にした
  1272.         txFormIndentDec(text);
  1273.     } else {
  1274.         txJumpParaTop(text);
  1275.         if (txGetChar(text) == CHAR_TAB) {
  1276.             txDeleteChar(text);
  1277.         }
  1278.     }
  1279.     return TRUE;
  1280. }
  1281.  
  1282. //2.99 970320 
  1283. // Enter,Shift+Enterなどに割り付けるキーコマンドを用意した。
  1284. // HTMLやeditmodeでコマンド名が異なるが、キーコマンドを用意したことによって、
  1285. // コマンド名の差異を吸収した。
  1286.  
  1287. BOOL TXCMDBASE txkeyEnter(TX* text)
  1288. {
  1289. // {Enter}キー割り当て用コマンド
  1290. // 改行を挿入または上書き。
  1291. //{#MS} {Enter} ^M
  1292. //{#VZ} {Enter} ^M
  1293. //{#MI} {Enter} ^M
  1294. //{#EMACS} {Enter} ^J ^M
  1295. //2.99 970320 new
  1296.     txWriteReturn(text);
  1297.     return TRUE;
  1298. }
  1299.  
  1300. WORD at_cmdcheck(WZCMD wzcmd)
  1301. {
  1302. //3.00B1 970523 new
  1303.     mchar* szcmd = wzcmdToSzcmd(wzcmd);
  1304.     if (!szcmd) return 0;
  1305.     if (!stricmp(szcmd,"\m.txkeyShiftEnter")) {
  1306.         if (!text->fHTML && !text->fWztext) {
  1307.             if (text->tszformat[SZFORMAT_BR][0] == 0) return MF_GRAYED;
  1308.         }
  1309.     }
  1310.     return 0;
  1311. }
  1312.  
  1313. BOOL TXCMDBASE txkeyShiftEnter(TX* text)
  1314. {
  1315. // Shift+{Enter}キー割り当て用コマンド
  1316. //{#MS} +{Enter}
  1317. //{#VZ} +{Enter}
  1318. //{#MI} +{Enter}
  1319. //{#EMACS} +{Enter}
  1320. //2.99 970320 new
  1321.     if (text->fHTML) {
  1322.         call("html.insertBR");
  1323.     } else {
  1324.         call("word.txInsertBR");
  1325.     }
  1326.     return TRUE;
  1327. }
  1328.  
  1329. BOOL TXCMDBASE txkeyCtrlEnter(TX* text)
  1330. {
  1331. // Ctrl+{Enter}キー割り当て用コマンド
  1332. //{#MS} ^{Enter}
  1333. //{#VZ} ^{Enter}
  1334. //{#MI} ^{Enter}
  1335. //{#EMACS} ^{Enter}
  1336. //2.99 970320 new
  1337.     if (text->fHTML) {
  1338.         call("html.insertP");
  1339.     } else {
  1340.         call("word.txFormFeedModal");
  1341.     }
  1342.     return TRUE;
  1343. }
  1344.  
  1345. BOOL TXCMDBASE txkeyAltEnter(TX* text)
  1346. {
  1347. // Alt+{Enter}キー割り当て用コマンド
  1348. //{#MS} %{Enter}
  1349. //{#VZ} %{Enter}
  1350. //{#MI} %{Enter}
  1351. //{#EMACS} %{Enter}
  1352. //2.99 970320 new
  1353.     if (text->fHTML) {
  1354.         call("html.uiPropertyTag");
  1355.     } else {
  1356.         if (text->textParaform) {
  1357.             call("paraform.config");
  1358.         } else if (txIsWP(text)) {
  1359.             call("word.txuiCharProperty");
  1360.         } else {
  1361.             call("paraform.form");
  1362.         }
  1363.     }
  1364.     return TRUE;
  1365. }
  1366.  
  1367. //2.96 970210 WriteTabMs廃止 edit.tabを使用してください
  1368.  
  1369. //1.00B edit.ShiftTabを追加
  1370. BOOL TXCMDBASE ShiftTab(TX* text)
  1371. {
  1372.     // 範囲選択中は逆インデント、
  1373.     // 選択中でないときは、カーソル行を逆インデントします
  1374.     if (text->fClip) {
  1375.         txIndentDec(text);
  1376.     } else {
  1377.         txJumpParaTop(text);
  1378.         if (txGetChar(text) == 0x09) {
  1379.             txDeleteChar(text);
  1380.         }
  1381.     }
  1382.     return TRUE;
  1383. }
  1384.  
  1385. insertlf
  1386. {
  1387. // 改行を挿入
  1388. // 上書きモードでも、改行が挿入されます
  1389. // 1.00Eで追加
  1390.     txInsert(text,"\n");
  1391. }
  1392.  
  1393. insertff
  1394. {
  1395. // 改頁コードを挿入
  1396. // 1.00Fで追加
  1397.     txInsertChar(text,'L'-0x40);
  1398. }
  1399.  
  1400. BOOL TXCMDBASE uiInsertControl(TX* text)
  1401. {
  1402. // コントロールコードを挿入
  1403. // 1.00Fで追加
  1404. //{#VZ} ^P
  1405. //{#MI} ^V
  1406.     inittext2;
  1407.     opentext2;
  1408.     {
  1409.         HDIALOG hd = dialog("制御文字の入力");
  1410.         
  1411.         {
  1412.             int i;
  1413.             
  1414.             for (i = 0;i <= 0x1B;i++) {
  1415.                 if (i == 0x0A) continue;//0x0Aは入力できない
  1416.                 insertf2("%c:\tCtrl-%c\n",i+'@',i+'@');
  1417.             }
  1418.             text2->npara = 1;
  1419.         }
  1420.         dialogList(hd,NULL,text2,20,10);
  1421.         
  1422.         if (dialogOpen(hd)) {
  1423.             int code = text2->npara;
  1424.             code--;
  1425.             if (code >= 0x0A) code++;
  1426.             txInsertChar(text,code);
  1427.         }
  1428.     }
  1429.     close2;
  1430.     return TRUE;
  1431. }
  1432.  
  1433. uiInsertTitle
  1434. {
  1435. // タイトル文字列を挿入
  1436. // 1.00Fで追加
  1437.     HDIALOG hd = dialog("タイトル文字列の挿入");
  1438.     BOOL data[SZTITLE_N];
  1439.     int i;
  1440.     
  1441.     memset(data,0,sizeof(data));
  1442.     for (i = SZTITLE_N;i--;) {
  1443.         if (text->tsztitle[i][0]) {
  1444.             data[i] = TRUE;
  1445.             break;
  1446.         }
  1447.     }
  1448.     
  1449.     dialogRadioInit(hd);
  1450.     for (i = 0;i < SZTITLE_N;i++) {
  1451.         dialogRadio(hd,"タイトル&" + inttostr(i + 1) + ": " + text->tsztitle[i],&data[i]);
  1452.     }
  1453.     
  1454.     if (dialogOpen(hd)) {
  1455.         for (i = 0;i < SZTITLE_N;i++) {
  1456.             if (data[i]) {
  1457.                 jumpparatop;
  1458.                 insert(text->tsztitle[i]);
  1459.                 break;
  1460.             }
  1461.         }
  1462.     }
  1463. }
  1464.  
  1465. BOOL TXCMDBASE OpenAutosaveBackup(TX* text)
  1466. {
  1467. // 自動保存によるバックアップファイルを開く
  1468.     if (text->autosaveMode == AUTOSAVE_BACKUP) {
  1469.         mchar szfilename[CCHPATHNAME];
  1470.         if (autosaveGetFileName(text,szfilename)) {
  1471.             if (fileIsExist(szfilename)) {
  1472.                 txOpenForkFast(text,szfilename);
  1473.                 return TRUE;
  1474.             }
  1475.         }
  1476.     }
  1477.     statprintf("バックアップファイルはありません");
  1478.     return FALSE;
  1479. }
  1480.  
  1481. //2.90 
  1482. //2.99 970315 ehPopup廃止
  1483.  
  1484. permanent txstr szQuote = ">\\s";
  1485.  
  1486. #define TXQUOTE_SELECT    1    // 範囲選択されてなかった時でも選択状態にする
  1487.  
  1488. BOOL TXAPI txQuoteEx(TX* text,int mode)
  1489. {
  1490. //2.00Bで追加
  1491.     strfromesc(szQuote);
  1492.     txSetUndisp(text);
  1493.     {
  1494.         int fClip = text->fClip;
  1495.         IFILE adr0 = txGetAddress(text);
  1496.         //
  1497.         if (!text->fClip) {
  1498.             IFILE adr = txGetAddress(text);
  1499.             txClipPasteEx(text,HCLIP_WIN,0,0,TRUE,CLIP_CHAR);
  1500.             txSelect(text);
  1501.             text->fClipMouse = TRUE;
  1502.             adr0 = txGetAddress(text);
  1503.             txJumpAddress(text,adr);
  1504.         }
  1505.         {
  1506.             txWalkStart(text);
  1507.             while(txIsWalking(text)) {
  1508.                 txJumpParaTop(text);
  1509.                 txInsert(text,szQuote);
  1510.                 if (!txNextPara(text)) break;
  1511.             }
  1512.             txWalkEnd(text);
  1513.         }
  1514.         if (mode == TXQUOTE_SELECT) {
  1515.             // 範囲選択されていなかった時は範囲選択する。
  1516.         } else {
  1517.             // 範囲選択されていなかった時は範囲選択を解除する。
  1518.             // カーソル位置はペーストしたデータの末尾の次の文字とする。
  1519.             if (!fClip) {
  1520.                 txSelectQuit(text);
  1521.                 txJumpAddress(text,adr0);
  1522.             }
  1523.         }
  1524.     }
  1525.     txSetDisp(text);
  1526.     strtoesc(szQuote);
  1527.     return TRUE;
  1528. }
  1529.  
  1530. quote
  1531. {
  1532. // 引用符の挿入
  1533. // 選択中なら、範囲内の各行に引用符を付けます
  1534. // 選択中でなければ、クリップボードから引用符を付けて貼り付けます
  1535. // 動作の確認ダイアログは出しません
  1536. //2.00Bで追加
  1537.     return txQuoteEx(text,TXQUOTE_SELECT);
  1538. }
  1539.  
  1540. BOOL TXAPI TXCMD TXUI txQuote(TX* text)
  1541. {
  1542. // 引用符の挿入
  1543. // 選択中なら、範囲内の各行に引用符を付けます
  1544. // 選択中でなければ、クリップボードから引用符を付けて貼り付けます
  1545. // 動作の確認ダイアログを出します
  1546.     HDIALOG hd = dialog("引用符の挿入");
  1547.     
  1548.     if (text->fClip) {
  1549.         dialogCaption(hd,"範囲内の各行に、引用符を付けます。");
  1550.     } else {
  1551.         dialogCaption(hd,"クリップボードから、引用符を付けて貼り付けます。");
  1552.     }
  1553.     
  1554.     dialogIndent(hd,4);
  1555.     dialogStr(hd,"引用符(&Q):",szQuote,16,10);
  1556.     dialogCaption(hd,"    (半角スペースは\"\\s\"で指定してください)");
  1557.     
  1558.     if (dialogOpen(hd)) {
  1559.         return txQuoteEx(text,TXQUOTE_SELECT);
  1560.     }
  1561.     return FALSE;
  1562. }
  1563.  
  1564. //##世代管理
  1565. //1.92 undo.cから移動
  1566.  
  1567. #define MAXGENELIST    200
  1568. typedef struct {
  1569.     TIME tTime[MAXGENELIST];
  1570.     mchar tszComment[MAXGENELIST][CCHWORD];
  1571.     GENELIST gl;
  1572. } GENECONTEXT;
  1573. GENECONTEXT _genecontext;
  1574.  
  1575. BOOL dlgprocGeneList(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  1576. {
  1577.     switch(message) {
  1578.         case WM_INITDIALOG: {
  1579.             HWND hwndList = GetDlgItem(hwnd,IDD_LIST);
  1580.             int i;
  1581.             SendMessage(hwndList,LB_ADDSTRING,0,(LPARAM)"現在テキスト編集開始時点");
  1582.             for (i = 1;i <= _genecontext.gl.nList;i++) {
  1583.                 mchar* szComment = _genecontext.tszComment[i];
  1584.                 mchar buff[100 + CCHWORD];
  1585.                 mchar* dst = buff;
  1586.                 TM tm;
  1587.                 timeGetLocal(&tm,&_genecontext.tTime[i]);
  1588.                 sprintf(dst,"%02d/%02d/%02d %02d:%02d:%02d - ",tm.tm_year,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);
  1589.                 dst += strlen(dst);
  1590.                 if (szComment[0]) {
  1591.                     sprintf(dst,"%s",szComment);
  1592.                 } else {
  1593.                     sprintf(dst,"%d世代",i);
  1594.                 }
  1595.                 SendMessage(hwndList,LB_ADDSTRING,0,(LPARAM)buff);
  1596.             }
  1597.             SendMessage(hwndList,LB_SETCURSEL,_genecontext.gl.curgene,0);
  1598.             SetFocus(hwndList);
  1599.             return FALSE;
  1600.         }
  1601.         case WM_COMMAND: {
  1602.             int id = LOWORD(wParam);
  1603.             switch(id) {
  1604.                 case IDD_NEWEST: {
  1605.                     txUndoNewest(text);
  1606.                     EndDialog(hwnd,TRUE);
  1607.                     return TRUE;
  1608.                 }
  1609.                 case IDD_COMMENT: {
  1610.                     HDIALOG hd = dialog("世代コメント");
  1611.                     dialogStrC(hd,"コメント:",txGetFrameNow()->pGeneComment,10,CCHWORD,30);//2.99C 970324 text1->txGetFrameNow()
  1612.                     dialogCaption(hd,"    (次に上書き保存するとできる世代のコメントになります)");
  1613.                     if (dialogOpen(hd)) {
  1614.                         
  1615.                     }
  1616.                     return TRUE;
  1617.                 }
  1618.                 case IDD_OPEN:
  1619.                 case IDD_JUMP:
  1620.                 case IDD_LOAD:
  1621.                 case IDD_DEL: {
  1622.                     HWND hwndList = GetDlgItem(hwnd,IDD_LIST);
  1623.                     int isel = SendMessage(hwndList,LB_GETCURSEL,0,0);
  1624.                     if (isel != LB_ERR) {
  1625.                         EndDialog(hwnd,TRUE);
  1626.                         switch(id) {
  1627.                             case IDD_JUMP: {
  1628.                                 NPARA npara = text->npara;
  1629.                                 txSetUndisp(text);//2.92 ちらつき低減
  1630.                                 txGeneJump(text,isel);
  1631.                                 txJumpPara(text,npara);//カーソル位置を復元したほうが使いやすい
  1632.                                 txSetDisp(text);//2.92 ちらつき低減
  1633.                                 break;
  1634.                             }
  1635.                             case IDD_OPEN: {
  1636.                                 txGeneOpen(text,isel);
  1637.                                 break;
  1638.                             }
  1639.                             case IDD_DEL: {
  1640.                                 if (!txGeneDelete(text,isel)) {
  1641.                                     attention("現在開いている世代が削除される場合、削除できません");
  1642.                                 }
  1643.                                 break;
  1644.                             }
  1645.                             default: {
  1646.                                 txuiGeneLoad(text,isel);
  1647.                                 break;
  1648.                             }
  1649.                         }
  1650.                     } else {
  1651.                         EndDialog(hwnd,FALSE);
  1652.                     }
  1653.                     return TRUE;
  1654.                 }
  1655.             }
  1656.             return FALSE;
  1657.         }
  1658.     }
  1659.     return FALSE;
  1660. }
  1661.  
  1662. GeneOpen
  1663. {
  1664.     txGeneOpen(text,1);
  1665. }
  1666.  
  1667. BOOL TXCMDBASE uiGeneList(TX* text)
  1668. {
  1669.     _genecontext.gl.maxList = MAXGENELIST;
  1670.     _genecontext.gl.tTime = _genecontext.tTime;
  1671.     _genecontext.gl.tszComment = _genecontext.tszComment;
  1672.     if (text->text2 && !text->fMultiChild && text->modeMulti == MM_GENE) {
  1673.         SetFocus(text->text2->hwndtext);
  1674.     }
  1675.     txGeneMakeList(text,&_genecontext.gl);
  1676.     if (_genecontext.gl.nList == _genecontext.gl.maxList) {
  1677.         information("世代が多すぎます。%d世代より前は表示できません。",MAXGENELIST);
  1678.     }
  1679.     {
  1680.         HDIALOG hd = dialog("世代管理");
  1681.         dialogSetContexthelp(hd,TRUE);
  1682.         PMACROFUNC pfunc;
  1683.         if (macroGetFuncAddress("dlgprocGeneList",&pfunc)) {
  1684.             dialogSetHook(hd,&pfunc);
  1685.         }
  1686.         dialogControlID(hd,IDD_LIST);
  1687.         dialogControlHelp(hd,206);
  1688.         _dialogList(hd,NULL,60,12);
  1689.         _dialogAddControlInfo(hd,IDD_LIST);
  1690.         dialogLFV(hd);
  1691.         int lcx = 15;
  1692.         if (text->fGene) {
  1693.             dialogControlID(hd,IDD_JUMP);
  1694.             dialogControlHelp(hd,207);
  1695.             dialogCmdDefault(hd,"移動(&J)",lcx);
  1696. //ここでは「以前を削除」コマンドは無効である。保存できないので
  1697.         } else {
  1698.             dialogControlID(hd,IDD_OPEN);
  1699.             dialogControlHelp(hd,208);
  1700.             dialogCmdDefault(hd,"参照(&R)",lcx);
  1701.             dialogControlID(hd,IDD_DEL);
  1702.             dialogControlHelp(hd,209);
  1703.             dialogCmd(hd,"以前を削除(&D)",lcx);
  1704. //            dialogControlID(hd,IDD_LOAD);
  1705. //            dialogCmd(hd,"読み込み(&L)",lcx);
  1706. //            dialogSpaceV(hd);
  1707. //            dialogControlID(hd,IDD_NEWEST);
  1708. //            dialogCmd(hd,"最新へ移動(&N)",lcx);
  1709.             dialogControlID(hd,IDD_COMMENT);
  1710.             dialogControlHelp(hd,210);
  1711.             dialogCmd(hd,"コメント(&C)...",lcx);
  1712.         }
  1713.         dialogCancel(hd,lcx);
  1714.         dialogSpaceV(hd);
  1715.         dialogHelpID(hd,lcx,"wz",IDH_GENMNGR);
  1716.         dialogOpen(hd);
  1717.     }
  1718.     return TRUE;
  1719. }
  1720.  
  1721. //##ms.key範囲選択
  1722. //1.92 select.cから移動
  1723.  
  1724. //{###範囲選択}
  1725.  
  1726. // カーソル位置と選択開始位置が同じなら選択解除
  1727. static void SelectQuitEx(TX* text)
  1728. {
  1729.     if (text->clipcur0 == txGetAddress(text)) {
  1730.         txSelectQuit(text);
  1731.     }
  1732. }
  1733.  
  1734. // 拡張選択モード
  1735. static void SelectExtend(TX* text,int d)
  1736. {
  1737.     static int mode = 0;
  1738.     if (!text->fClip) mode = 0;
  1739.     
  1740.     mode += d;
  1741.     if (mode > 5) mode = 0;
  1742.     if (mode < 1) mode = 0;
  1743.     
  1744.     switch(mode) {
  1745.         case 0: {
  1746.             txSelectQuit(text);
  1747.             break;
  1748.         }
  1749.         case 1: {
  1750.             SelectQuitEx(text);
  1751.             txSelect(text);
  1752.             break;
  1753.         }
  1754.         case 2: {
  1755.             SelectQuitEx(text);
  1756.             txSelectWord(text);
  1757.             break;
  1758.         }
  1759.         case 3: {
  1760.             SelectQuitEx(text);
  1761.             txSelectSentence(text);
  1762.             break;
  1763.         }
  1764.         case 4: {
  1765.             SelectQuitEx(text);
  1766.             txSelectParaCur(text);
  1767.             break;
  1768.         }
  1769.         case 5: {
  1770.             SelectQuitEx(text);
  1771.             txSelectAll(text);
  1772.             break;
  1773.         }
  1774.     }
  1775. }
  1776.  
  1777. BOOL TXCMDBASE selectExtend(TX* text)
  1778. {
  1779. #WZKEY {F8}
  1780.     // 拡張選択モード
  1781.     // 方向キーで長さの調節が可能な選択モード
  1782.     // 続けてキーを押すことで選択範囲を自動調節する
  1783.     // :1回目=選択開始 2回目=単語選択 3回目=一文選択
  1784.     // :4回目=段落選択 5回目=全文選択
  1785.     //{#MS} {F8}
  1786.     SelectExtend(text,1);
  1787.     return TRUE;
  1788. }
  1789.  
  1790. BOOL TXCMDBASE selectExtendPrev(TX* text)
  1791. {
  1792. #WZKEY +{F8}
  1793.     // 拡張選択モード(逆順)
  1794.     // 拡張選択モードの選択範囲トグルを戻す。
  1795.     //{#MS} +{F8}
  1796.     if (!text->fClip) return FALSE;
  1797.     SelectExtend(text,-1);
  1798.     return TRUE;
  1799. }
  1800.  
  1801. //3.00B1 970613 new
  1802. BOOL TXAPI TXCMDBASE txSelectRevival(TX* text)
  1803. {
  1804. // 範囲選択の再現
  1805. // 直前に指定した選択開始位置からカーソル位置までを文字単位で範囲選択します。
  1806.     IFILE cliptop = text->cliptopnow;
  1807.     IFILE clipend = txGetAddress(text);
  1808.     int ly = text->ly;
  1809.     txSetUndispSilent(text);
  1810.     txJumpAddress(text,cliptop);
  1811.     txSelectEx(text,CLIP_CHAR);
  1812.     txJumpAddress(text,clipend);
  1813.     txSetLy(text,ly);
  1814.     txSetDispSilent(text);
  1815.     return TRUE;
  1816. }
  1817.  
  1818. //{###ジャンプ}
  1819.  
  1820. //3.00B1 970613 new
  1821. //3.00B1 970613 VZ.KEY txSelectJump=^QB -> edit.txSelectJumpEx=^QB
  1822. BOOL TXAPI TXCMDBASE txSelectJumpEx(TX* text)
  1823. {
  1824. // 範囲の先頭/末尾へジャンプ
  1825. // 範囲選択中でないときでも、直前に指定した範囲でジャンプします。
  1826. //{#VZ} ^QB
  1827.     if (text->fClip) {
  1828.         return txSelectJump(text);
  1829.     } else {
  1830.         IFILE adr = txGetAddress(text);
  1831.         int ly = text->ly;
  1832.         //
  1833.         txSetUndispSilent(text);
  1834.         txJumpAddress(text,text->cliptopnow);
  1835.         txSetLy(text,text->lyClip);
  1836.         txSetDispSilent(text);
  1837.         //
  1838.         text->cliptopnow = adr;
  1839.         text->lyClip = ly;
  1840.         return TRUE;
  1841.     }
  1842. }
  1843.  
  1844. //2.00B 整形etcのカテゴリが"範囲選択"だったのを修正
  1845. //{###編集}
  1846.  
  1847. //##整形
  1848. // センタリング、右寄せ、左寄せ、インデント、1字見出し(※,・◎)にも対応したい
  1849.  
  1850. #include <windows.h>
  1851. #include "dialog.h"
  1852.  
  1853. permanent txstr ftszParaTop = " 「|>≫|>";
  1854. permanent int ftWidth = 70;
  1855. permanent int ftMode = 0;
  1856. permanent int ftArea = 0;
  1857. // カレント行が段落の先頭か?
  1858. static BOOL IsLineParaTop(tx* text)
  1859. {
  1860.     mchar*p = text->buff + text->cury;
  1861.     if (text->cury == text->cur0) {
  1862.         // カーソルが行頭に居る
  1863.         p = text->buff + text->cur;
  1864.     }
  1865.     WORD c = *p;
  1866.     if (c == CHAR_LF || c == CHAR_CR || c == CHAR_FF || c == CHAR_EOF) return TRUE;
  1867. #if 0//文中の大文字単語"WindowsNT"などにも引っかかってしまう
  1868.     if (isupper(c)) return TRUE;
  1869. #endif
  1870.     if (iskanji(c)) {
  1871.         c = MAKEWORD(p[1],c);
  1872.     }
  1873.     if (strchr(ftszParaTop,c)) {
  1874.         return TRUE;
  1875.     }
  1876.     return FALSE;
  1877. }
  1878.  
  1879. // カレント行が段落の末尾か?
  1880. static BOOL IsLineEnd(tx* text)
  1881. {
  1882.     int cxWidth = ftWidth * text->cxChar;
  1883.     BOOL ret = FALSE;
  1884.     int x = text->x;
  1885.     // 行の最後が折り返し桁に達しているか?
  1886.     txJumpLineEnd(text);
  1887.     if (text->x + text->cxChar * 4 < cxWidth) {
  1888.         // 達してなければ...
  1889.         ret = TRUE;
  1890.     }
  1891.     // カーソル位置を戻す
  1892.     txJumpX(text,x);
  1893.     return ret;
  1894. }
  1895.  
  1896. // 段落の先頭へ
  1897. static void JumpParaTop(tx *text)
  1898. {
  1899.     BOOL fFirst = TRUE;
  1900.     txJumpLineTop(text);
  1901.     while(1) {
  1902.         if (!fFirst && IsLineEnd(text)) {
  1903.             txDown(text);
  1904.             break;
  1905.         }
  1906.         if (IsLineParaTop(text)) break;
  1907.         if (!txUp(text)) break;
  1908.         fFirst = FALSE;
  1909.     }
  1910. }
  1911.  
  1912. static int strGetSpaceTop(mchar* szline)
  1913. {
  1914.     int lchIndent = 0;
  1915.     if (szline[0] == ' ') {
  1916.         mchar*p = szline;
  1917.         while(*p == ' ') {
  1918.             lchIndent++;
  1919.             p++;
  1920.         }
  1921.     }
  1922.     return lchIndent;
  1923. }
  1924.  
  1925. //2.00B 行頭の半角空白(インデント)を削除
  1926. static void txDeleteSpaceTop(TX* text)
  1927. {
  1928.     txstr szline;
  1929.     txGetLine(text,szline);
  1930.     int lchIndent = strGetSpaceTop(szline);
  1931.     if (lchIndent) {
  1932.         txDeleteBytes(text,lchIndent);
  1933.     }
  1934. }
  1935.  
  1936. #define FORMTEXT_FORM        0x0001
  1937. #define FORMTEXT_JOINT        0x0002
  1938. #define FORMTEXT_RIGHT        0x0004
  1939. #define FORMTEXT_CENTER        0x0008
  1940. #define FORMTEXT_LEFT        0x0010
  1941. #define FORMTEXT_PARA1        0x0020
  1942. #define FORMTEXT_SELECT        0x0040
  1943. #define FORMTEXT_ALLTEXT    0x0080
  1944. static int FormText(tx* text,int mode)
  1945. {
  1946.     txstr szline;
  1947.     int cxWidth = ftWidth * text->cxChar;
  1948.     //
  1949.     txSetUndisp(text);
  1950.     if (mode & FORMTEXT_ALLTEXT) {
  1951.         txJumpFileTop(text);
  1952.     } else if (mode & FORMTEXT_SELECT) {
  1953.         txJumpSelectTop(text);
  1954.     }
  1955.     //
  1956.     while(1) {
  1957.         JumpParaTop(text);
  1958. //information("!!!");
  1959.         // 改行を削除して1行にする
  1960.         if (IsLineEnd(text)) {
  1961.             //2.00B いきなり行の最後なら、何もしない
  1962.             if (!txDown(text)) break;
  1963.         } else {
  1964.             while(1) {
  1965.                 if (txIsLineLf(text)) {
  1966.                     if (!txDown(text)) break;
  1967.                     if (IsLineParaTop(text)) break;
  1968.                     // 行の最後か?
  1969.                     if (IsLineEnd(text)) {
  1970.                         txJumpLineTop(text);
  1971.                         txDeleteSpaceTop(text);
  1972.                         txDeletePrev(text);
  1973.                         txNextPara(text);
  1974.                         break;
  1975.                     }
  1976.                     //
  1977.                     txDeleteSpaceTop(text);
  1978.                     txDeletePrev(text);
  1979.                     txJumpLineTop(text);
  1980.                 } else {
  1981.                     if (!txDown(text)) break;
  1982.                 }
  1983.             }
  1984.             if (mode & FORMTEXT_JOINT) {
  1985.             } else {
  1986.                 // 折り返して改行を入れる
  1987.                 txUp(text);
  1988.                 JumpParaTop(text);
  1989.                 if (1) {
  1990.                     int cxWidth0 = text->cxWidth;
  1991.                     int width0 = text->width;
  1992.                     
  1993.                     text->width = ftWidth;
  1994.                     text->cxWidth = cxWidth;
  1995.                     txFlushCurysize(text);
  1996.                     //2.00B 整形で、行頭の半角スペースによるインデントに対応
  1997.                     mchar szspace[CCHLINE];
  1998.                     txGetLine(text,szline);
  1999.                     int lchIndent = strGetSpaceTop(szline);
  2000.                     if (lchIndent) {
  2001.                         memset(szspace,' ',lchIndent);
  2002.                     }
  2003.                     while(1) {
  2004.                         if (txIsLineLf(text)) {
  2005.                             txDown(text);
  2006.                             break;
  2007.                         }
  2008.                         if (!txDown(text)) break;//2.00B 
  2009.                         txInsertReturn(text);
  2010.                         if (lchIndent) {//2.00B 
  2011.                             txCurInsertBuff(text,szspace,lchIndent);
  2012.                             // 行が全て空白だと無限ループになるから。
  2013.                             int len = lchIndent;
  2014.                             while(len >= text->curysize) {
  2015.                                 txDeleteChar(text);
  2016.                                 len--;
  2017.                             }
  2018.                         }
  2019.                     }
  2020.                     //
  2021.                     text->width = width0;
  2022.                     text->cxWidth = cxWidth0;
  2023.                     txFlushCurysize(text);
  2024.                     // widthの変更をリセット
  2025.                     txJumpAddress(text,txGetAddress(text));
  2026.                 }
  2027.             }
  2028.         }
  2029.         if (mode & FORMTEXT_ALLTEXT) {
  2030.             if (txIsLineEof(text)) break;
  2031.         } else if ((mode & FORMTEXT_SELECT) && text->fClip) {
  2032.             if (
  2033.                 (txGetAddress(text) >= text->cliptop) ||
  2034.                   (txIsLineEof(text))    //1.99H 空でないEOF行の直前文字まで選択して実行すると飛んだ
  2035.             ) {
  2036.                 txSelectQuit(text);
  2037.                 break;
  2038.             }
  2039.         } else {
  2040.             break;
  2041.         }
  2042.     }
  2043.     //
  2044.     txSetDisp(text);
  2045.     return 0;
  2046. }
  2047.  
  2048. //2.00B MS/VZキーに割り当て
  2049. //2.90 キー割り当て廃止
  2050. //{#MS} +^{Enter}
  2051. //{#VZ} +^{Enter}
  2052. formtext
  2053. {
  2054. // カーソル行または選択範囲内を整形
  2055.     if (text->fClip) {
  2056.         FormText(text,FORMTEXT_FORM|FORMTEXT_SELECT);
  2057.     } else {
  2058.         FormText(text,FORMTEXT_FORM|FORMTEXT_PARA1);
  2059.     }
  2060. }
  2061.  
  2062. formtextAll
  2063. {
  2064. // テキスト全体を整形
  2065.     FormText(text,FORMTEXT_FORM|FORMTEXT_ALLTEXT);
  2066. }
  2067.  
  2068. formtextJointAll
  2069. {
  2070. // テキスト全体を連結整形
  2071.     FormText(text,FORMTEXT_JOINT|FORMTEXT_ALLTEXT);
  2072. }
  2073.  
  2074. uiFormText
  2075. {
  2076.     HDIALOG hd = dialog("テキスト整形");
  2077.     dialogSetContexthelp(hd,TRUE);
  2078.     int x = DTCX * 40;
  2079.     dialogSetGroupRight(hd,x);
  2080.     
  2081.     dialogGroup(hd,"整形内容");
  2082.         dialogControlHelp(hd,-296);
  2083.         dialogRadioID(hd,&ftMode,"整形(&F)","連結(&J)");
  2084.     dialogGroupEnd(hd);
  2085.     
  2086.     dialogGroup(hd,"整形範囲");
  2087.         if (text->fClip) {
  2088.             dialogControlHelp(hd,221);
  2089.             dialogRadioID(hd,&ftArea,"範囲内(&S)","テキスト全体(&A)");
  2090.         } else {
  2091.             dialogControlHelp(hd,221);
  2092.             dialogRadioID(hd,&ftArea,"1段落(&S)","テキスト全体(&A)");
  2093.         }
  2094.     dialogGroupEnd(hd);
  2095.     
  2096.     dialogControlHelp(hd,222);
  2097.     dialogInt(hd,"折り返し桁(&W):",&ftWidth,16,3);
  2098.     
  2099.     dialogControlHelp(hd,223);
  2100.     dialogStr(hd,"段落区切(&P):",ftszParaTop,16,14);
  2101.     
  2102.     if (dialogOpen(hd)) {
  2103.         int arg = 0;
  2104.         if (ftMode == 0) arg |= FORMTEXT_FORM;
  2105.         if (ftMode == 1) arg |= FORMTEXT_JOINT;
  2106.         if (ftArea == 0) {
  2107.             if (text->fClip) {
  2108.                 arg |= FORMTEXT_SELECT;
  2109.             } else {
  2110.                 arg |= FORMTEXT_PARA1;
  2111.             }
  2112.         } else {
  2113.             arg |= FORMTEXT_ALLTEXT;
  2114.         }
  2115.         FormText(text,arg);
  2116.     }
  2117. }
  2118.  
  2119. //##日付の挿入
  2120.  
  2121. #define ITEM_N            6
  2122. #define IDD_YEAR        100
  2123. #define IDD_MONTH        101
  2124. #define IDD_DAY            102
  2125. #define IDD_DAYOFWEEK    103
  2126. #define IDD_HOUR        104
  2127. #define IDD_MINUTE        105
  2128. #define IDD_DATEINC        106    //2.92 日付を増減して挿入する機能を追加
  2129. //
  2130. #define IDD_FORMAT        200
  2131.  
  2132. static void _cdecl cprintf(HWND hctrl,mchar* szformat,...)
  2133. {
  2134.     mchar buff[CCHWORD];
  2135.     vsprintf(buff,szformat,(void*)(&szformat + 1));
  2136.     SendMessage(hctrl,CB_ADDSTRING,0,(LPARAM)buff);
  2137. }
  2138.  
  2139. static void cprintStd(HWND hctrl,int data)
  2140. {
  2141.     cprintf(hctrl,"%d",data);
  2142.     cprintf(hctrl,"%2d",data);
  2143.     cprintf(hctrl,"%02d",data);
  2144. }
  2145.  
  2146. #define FORMAT_DAYOFWEEK_N    5
  2147. static mchar* szFromDayofweek(mchar szdst[CCHWORD],int mode,int day)
  2148. {
  2149.     static mchar* tsz[][7] = {
  2150.         {"日","月","火","水","木","金","土"},
  2151.         {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"},
  2152.         {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"},
  2153.     };
  2154.     switch(mode) {
  2155.         case 0: {
  2156.             sprintf(szdst,"%s曜日",tsz[0][day]);
  2157.             break;
  2158.         }
  2159.         case 1: {
  2160.             sprintf(szdst,"(%s)",tsz[0][day]);
  2161.             break;
  2162.         }
  2163.         case 2: {
  2164.             sprintf(szdst,"%s",tsz[1][day]);
  2165.             break;
  2166.         }
  2167.         case 3: {
  2168.             sprintf(szdst,"%s.",tsz[1][day]);
  2169.             break;
  2170.         }
  2171.         case 4: {
  2172.             sprintf(szdst,"%s",tsz[2][day]);
  2173.             break;
  2174.         }
  2175.     }
  2176.     return szdst;
  2177. }
  2178.  
  2179. #define FORMAT_MONTH_N    5
  2180. static mchar* szFromMonth(mchar szdst[CCHWORD],int mode,int data)
  2181. {
  2182.     static mchar* tsz[13] = {
  2183.         "",
  2184.         "January","February","March","April","May","June",
  2185.         "July","August","September","October","November","December"
  2186.     };
  2187.     switch(mode) {
  2188.         case 0: {
  2189.             sprintf(szdst,"%d",data);
  2190.             break;
  2191.         }
  2192.         case 1: {
  2193.             sprintf(szdst,"%2d",data);
  2194.             break;
  2195.         }
  2196.         case 2: {
  2197.             sprintf(szdst,"%02d",data);
  2198.             break;
  2199.         }
  2200.         case 3: {
  2201.             sprintf(szdst,"%s",tsz[data]);
  2202.             break;
  2203.         }
  2204.         case 4: {
  2205.             sprintf(szdst,"%s",tsz[data]);
  2206.             szdst[3] = 0;
  2207.             break;
  2208.         }
  2209.     }
  2210.     return szdst;
  2211. }
  2212.  
  2213. permanent int dt_format = 0;
  2214. permanent int dt_year = 0;
  2215. permanent int dt_month = 0;
  2216. permanent int dt_day = 0;
  2217. permanent int dt_dayofweek = 0;
  2218. permanent int dt_hour = 0;
  2219. permanent int dt_minute = 0;
  2220.  
  2221. static void insertdateGetTime(HWND hwnd,TIME* _itime)
  2222. {
  2223.     long n = (int)(INT)GetDlgItemInt(hwnd,IDD_DATEINC,NULL,TRUE);
  2224.     TIME itime;
  2225.     itimeGetNow(&itime);
  2226.     itime += n * 86400L;
  2227.     *_itime = itime;
  2228. }
  2229.  
  2230. static void insertdateFlush(HWND hwnd)
  2231. {
  2232.     //2.98 970309 「挿入|日付・時刻」:書式をwzhist.datでカスタマイズできるようにした
  2233.     static mchar _szhistid[] = "uiInsertDate";
  2234.     HSTRBLK sb = historyOpen(_szhistid,4096);
  2235.     if (sb) {
  2236.         HWND hctrl = GetDlgItem(hwnd,IDD_FORMAT);
  2237.         int isel = SendMessage(hctrl,LB_GETCURSEL,0,0);
  2238.         SendMessage(hctrl,LB_RESETCONTENT,0,0);
  2239.         TIME itime;
  2240.         insertdateGetTime(hwnd,&itime);
  2241.         TM tm;
  2242.         itimeToTm(&itime,&tm);
  2243.         //
  2244.         int n = sbGetCount(sb);
  2245.         int i;
  2246.         for (i = n;i--;) {
  2247.             mchar* szformat = sbRead(sb,i);
  2248.             mchar buff[CCHWORD];
  2249.             mchar* dst = buff;
  2250.             mchar* p = szformat;
  2251.             while(*p) {
  2252.                 if (*p == '{') {
  2253.                     int id = 0;
  2254.                     int lch;
  2255.                     BOOL f = FALSE;
  2256.                     if (lch = strmatch(p,"{year}")) {
  2257.                         id = IDD_YEAR;
  2258.                     } else if (lch = strmatch(p,"{month}")) {
  2259.                         id = IDD_MONTH;
  2260.                     } else if (lch = strmatch(p,"{day}")) {
  2261.                         id = IDD_DAY;
  2262.                     } else if (lch = strmatch(p,"{02month}")) {
  2263.                         id = IDD_MONTH;
  2264.                         f = TRUE;
  2265.                     } else if (lch = strmatch(p,"{02day}")) {
  2266.                         id = IDD_DAY;
  2267.                         f = TRUE;
  2268.                     } else if (lch = strmatch(p,"{dayofweek}")) {
  2269.                         id = IDD_DAYOFWEEK;
  2270.                     } else if (lch = strmatch(p,"{hour}")) {
  2271.                         id = IDD_HOUR;
  2272.                     } else if (lch = strmatch(p,"{12hour}")) {
  2273.                         id = IDD_HOUR;
  2274.                         f = TRUE;
  2275.                     } else if (lch = strmatch(p,"{minute}")) {
  2276.                         id = IDD_MINUTE;
  2277.                     } else if (lch = strmatch(p,"{minute}")) {
  2278.                         id = IDD_HOUR;
  2279.                     } else if (lch = strmatch(p,"{ampm}")) {
  2280.                         id = 1;
  2281.                         f = TRUE;
  2282.                     } else if (lch = strmatch(p,"{jampm}")) {
  2283.                         id = 2;
  2284.                         f = TRUE;
  2285.                     }
  2286.                     if (lch) {
  2287.                         p += lch;
  2288.                         if (id) {
  2289.                             if (f) {
  2290.                                 switch(id) {
  2291.                                     case IDD_MONTH: {
  2292.                                         sprintf(dst,"%02d",tm.tm_mon+1);
  2293.                                         dst += strlen(dst);
  2294.                                         break;
  2295.                                     }
  2296.                                     case IDD_DAY: {
  2297.                                         sprintf(dst,"%02d",tm.tm_mday);
  2298.                                         dst += strlen(dst);
  2299.                                         break;
  2300.                                     }
  2301.                                     case IDD_HOUR: {
  2302.                                         sprintf(dst,"%d",tm.tm_hour % 12);
  2303.                                         dst += strlen(dst);
  2304.                                         break;
  2305.                                     }
  2306.                                     case 1: 
  2307.                                     case 2: {
  2308.                                         static mchar *tsz[2][2] = {
  2309.                                             {"AM","PM"},
  2310.                                             {"午前","午後"},
  2311.                                         };
  2312.                                         BOOL h = (tm.tm_hour >= 12);
  2313.                                         sprintf(dst,"%s",tsz[(id-1)][h]);
  2314.                                         dst += strlen(dst);
  2315.                                         break;
  2316.                                     }
  2317.                                 }
  2318.                             } else {
  2319.                                 GetDlgItemText(hwnd,id,dst,CCHWORD - (dst - buff));
  2320.                                 dst += strlen(dst);
  2321.                             }
  2322.                         }
  2323.                     } else {
  2324.                         p = strchr(p,'}');
  2325.                         if (!p) break;
  2326.                     }
  2327.                 } else {
  2328.                     if (iskanji(*p)) {
  2329.                         *dst++ = *p++;
  2330.                         *dst++ = *p++;
  2331.                     } else {
  2332.                         *dst++ = *p++;
  2333.                     }
  2334.                 }
  2335.             }
  2336.             *dst = 0;
  2337.             SendMessage(hctrl,LB_ADDSTRING,0,(LPARAM)buff);
  2338.         }
  2339.         if (isel == LB_ERR) isel = dt_format;
  2340.         SendMessage(hctrl,LB_SETCURSEL,isel,0);
  2341.     }
  2342.     //
  2343.     historyClose(_szhistid,sb);
  2344. }
  2345.  
  2346. static void dateFlush(HWND hwnd)
  2347. {
  2348.     TIME itime;
  2349.     insertdateGetTime(hwnd,&itime);
  2350.     TM tm;
  2351.     itimeToTm(&itime,&tm);
  2352.     int i;
  2353.     for (i = 0;i < ITEM_N;i++) {
  2354.         int id = IDD_YEAR + i;
  2355.         HWND hctrl = GetDlgItem(hwnd,id);
  2356.         int isel = SendMessage(hctrl,CB_GETCURSEL,0,0);
  2357.         SendMessage(hctrl,CB_RESETCONTENT,0,0);
  2358.         int data;
  2359.         switch(id) {
  2360.             case IDD_YEAR: {
  2361.                 data = 1900 + tm.tm_year;
  2362.                 cprintf(hctrl,"%4d",data);
  2363.                 cprintf(hctrl,"%2d",data % 100);
  2364.                 {
  2365.                     mchar buff[CCHWORD];
  2366.                     sprintf(buff,"平成%d",data - 1988);
  2367.                     SendMessage(hctrl,CB_ADDSTRING,0,(LPARAM)buff);
  2368.                 }
  2369.                 if (isel == CB_ERR) isel = dt_year;
  2370.                 break;
  2371.             }
  2372.             case IDD_MONTH: {
  2373.                 data = tm.tm_mon+1;
  2374.                 int i;
  2375.                 for (i = 0;i < FORMAT_MONTH_N;i++) {
  2376.                     mchar buff[CCHWORD];
  2377.                     szFromMonth(buff,i,data);
  2378.                     SendMessage(hctrl,CB_ADDSTRING,0,(LPARAM)buff);
  2379.                 }
  2380.                 if (isel == CB_ERR) isel = dt_month;
  2381.                 break;
  2382.             }
  2383.             case IDD_DAY: {
  2384.                 data = tm.tm_mday;
  2385.                 cprintStd(hctrl,data);
  2386.                 if (isel == CB_ERR) isel = dt_day;
  2387.                 break;
  2388.             }
  2389.             case IDD_DAYOFWEEK: {
  2390.                 data = tm.tm_wday;
  2391.                 int i;
  2392.                 for (i = 0;i < FORMAT_DAYOFWEEK_N;i++) {
  2393.                     mchar buff[CCHWORD];
  2394.                     szFromDayofweek(buff,i,data);
  2395.                     SendMessage(hctrl,CB_ADDSTRING,0,(LPARAM)buff);
  2396.                 }
  2397.                 if (isel == CB_ERR) isel = dt_dayofweek;
  2398.                 break;
  2399.             }
  2400.             case IDD_HOUR: {
  2401.                 data = tm.tm_hour;
  2402.                 cprintStd(hctrl,data);
  2403.                 if (isel == CB_ERR) isel = dt_hour;
  2404.                 break;
  2405.             }
  2406.             case IDD_MINUTE: {
  2407.                 data = tm.tm_min;
  2408.                 cprintStd(hctrl,data);
  2409.                 if (isel == CB_ERR) isel = dt_minute;
  2410.                 break;
  2411.             }
  2412.         }
  2413.         if (isel == CB_ERR) isel = 0;
  2414.         SendMessage(hctrl,CB_SETCURSEL,isel,0);
  2415.     }
  2416.     insertdateFlush(hwnd);
  2417. }
  2418.  
  2419. BOOL dlgprocDate(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  2420. {
  2421.     switch(message) {
  2422.         case WM_INITDIALOG: {
  2423.             dateFlush(hwnd);
  2424.             break;
  2425.         }
  2426.         case WM_COMMAND: {
  2427.             HDIALOG hd = dialogFromHwnd(hwnd);
  2428.             int id = WM_COMMAND_GetId(wParam);
  2429.             int notify = WM_COMMAND_GetNotify(wParam,lParam);
  2430.             if (notify == CBN_SELCHANGE) {
  2431.                 if (IDD_YEAR <= id && id < IDD_YEAR + ITEM_N) {
  2432.                     insertdateFlush(hwnd);
  2433.                 }
  2434.             }
  2435.             if (id == IDOK) {
  2436.                 dateFlush(hwnd);    //現在の時刻にセット
  2437.                 //
  2438.                 HWND hctrl = GetDlgItem(hwnd,IDD_FORMAT);
  2439.                 int isel = SendMessage(hctrl,LB_GETCURSEL,0,0);
  2440.                 dt_format = isel;
  2441.                 mchar buff[CCHWORD];
  2442.                 SendMessage(hctrl,LB_GETTEXT,isel,(LPARAM)buff);
  2443.                 txInsert(text,buff);
  2444.                 //
  2445.                 int i;
  2446.                 for (i = 0;i < ITEM_N;i++) {
  2447.                     int id = IDD_YEAR + i;
  2448.                     HWND hctrl = GetDlgItem(hwnd,id);
  2449.                     int isel = SendMessage(hctrl,CB_GETCURSEL,0,0);
  2450.                     switch(id) {
  2451.                         case IDD_YEAR: dt_year = isel;break;
  2452.                         case IDD_MONTH: dt_month = isel;break;
  2453.                         case IDD_DAY: dt_day = isel;break;
  2454.                         case IDD_DAYOFWEEK: dt_dayofweek = isel;break;
  2455.                         case IDD_HOUR: dt_hour = isel;break;
  2456.                         case IDD_MINUTE: dt_minute = isel;break;
  2457.                     }
  2458.                 }
  2459.             } else if (id == IDD_DATEINC) {
  2460.                 dateFlush(hwnd);
  2461.             }
  2462.             break;
  2463.         }
  2464.     }
  2465.     return FALSE;
  2466. }
  2467.  
  2468. BOOL TXCMDBASE uiInsertDate(TX* text)
  2469. {
  2470. // 日付・時刻の挿入
  2471.     HDIALOG hd = dialog("日付・時刻の挿入");
  2472.     dialogSetHookEx(hd,"\m.dlgprocDate");
  2473.     
  2474.     DTRECT r;
  2475.     dialogSetH(hd);
  2476.     
  2477.     dialogSetGroupBottom(hd,DTCY * 15);
  2478.     
  2479.     dialogGroup(hd,"挿入する日付・時刻(&I)");
  2480.         dialogGetPos(hd,&r);
  2481.         r.cx = DTCX * 28;
  2482.         r.cy = DTCY * 12;
  2483.         __dialogAddItem(hd,"LISTBOX",NULL,IDD_FORMAT,&r,LBS_NOTIFY|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP);
  2484.     dialogGroupEnd(hd);
  2485.     
  2486.     dialogGroup(hd,"詳細");
  2487.         int i;
  2488.         for (i = 0;i < ITEM_N;i++) {
  2489.             mchar* tsz[] = {
  2490.                 "年(&Y):",
  2491.                 "月(&M):",
  2492.                 "日(&D):",
  2493.                 "曜日(&W):",
  2494.                 "時(&H):",
  2495.                 "分(&N):",
  2496.             };
  2497.             dialogCaption(hd,tsz[i]);
  2498.             dialogSetPosLX(hd,10);
  2499.             dialogGetPos(hd,&r);
  2500.             r.cx = DTCX * 14;
  2501.             r.cy = DTCY * 7;
  2502.             __dialogAddItem(hd,"COMBOBOX",NULL,IDD_YEAR + i,&r,CBS_AUTOHSCROLL|CBS_DROPDOWNLIST|WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP|WS_GROUP);
  2503.             dialogLF(hd);
  2504.             dialogSetPosY(hd,r.y + DTCY * 2);
  2505.         }
  2506.     dialogGroupEnd(hd);
  2507.     
  2508.     dialogLF(hd);
  2509.     int n = 0;
  2510.     dialogControlID(hd,IDD_DATEINC);
  2511.     dialogInt(hd,"日付の増減(&A):",&n,20,6);
  2512.     
  2513.     dialogOpen(hd);
  2514.     return TRUE;
  2515. }
  2516.  
  2517. //##文字列の補完
  2518. //1.99B HIST_STRも補完辞書として活用するようにした
  2519. //2.96A 970214 HIST_COMPLETEに学習するようにした
  2520.  
  2521. static mchar _szCompleteHist[] = "HIST_COMPLETE";
  2522. #define SIZE_COMPLETEHIST    1024
  2523.  
  2524. #define IFIND_HIST_LAST            24999
  2525. #define IFIND_END_HISTCOMPLETE    24999
  2526. #define IFIND_TOP_HISTCOMPLETE    20000
  2527. #define IFIND_END_HISTSTR        19999
  2528. #define IFIND_TOP_HISTSTR        15000
  2529. #define IFIND_END_HISTSEARCH    14999
  2530. #define IFIND_TOP_HISTSEARCH    10000
  2531. #define IFIND_HIST_TOP            10000
  2532. #define IFIND_NONE        -1
  2533.  
  2534. static int _completeSearchHist(HHIST h,int ifind,BOOL fPrev,mchar* szdst,mchar* szstr)
  2535. {
  2536.     int top;
  2537.     int end;
  2538.     HSTRBLK sb;
  2539.     
  2540.     if (h == HIST_STR) {
  2541.         top = IFIND_TOP_HISTSTR;
  2542.         end = IFIND_END_HISTSTR;
  2543.         sb = sbFromHist(h);
  2544.     } else if (h == HIST_SEARCH) {
  2545.         top = IFIND_TOP_HISTSEARCH;
  2546.         end = IFIND_END_HISTSEARCH;
  2547.         sb = sbFromHist(h);
  2548.     } else {
  2549.         top = IFIND_TOP_HISTCOMPLETE;
  2550.         end = IFIND_END_HISTCOMPLETE;
  2551.         sb = h;
  2552.     }
  2553.     //
  2554.     if (ifind == end) {
  2555.         ifind = sbGetCount(sb);
  2556.     } else {
  2557.         ifind -= top;
  2558.     }
  2559.     //
  2560.     if (fPrev) {
  2561.         ifind = sbiSearchNext(sb,szstr,ifind);
  2562.     } else {
  2563.         ifind = sbiSearchPrev(sb,szstr,ifind);
  2564.     }
  2565.     //
  2566.     if (ifind == -1) {
  2567.         if (fPrev) {
  2568.             ifind = IFIND_NONE;
  2569.         } else {
  2570.             ifind = 0;
  2571.         }
  2572.     } else {
  2573.         strcpymax(szdst,sbRead(sb,ifind),CCHWORD);
  2574.         ifind += top;
  2575.     }
  2576.     return ifind;
  2577. }
  2578.  
  2579. static int completeSearchHist(int ifind,BOOL fPrev,mchar* szdst,mchar* szstr,HSTRBLK sbComplete)
  2580. {
  2581. #if 1//2.96A 970214 
  2582.     if (IFIND_TOP_HISTCOMPLETE <= ifind && ifind <= IFIND_END_HISTCOMPLETE) {
  2583.         ifind = _completeSearchHist(sbComplete,ifind,fPrev,szdst,szstr);
  2584.         if (ifind != 0) return ifind;
  2585.         ifind = IFIND_END_HISTSTR;
  2586.     }
  2587.     if (IFIND_TOP_HISTSTR <= ifind && ifind <= IFIND_END_HISTSTR) {
  2588.         ifind = _completeSearchHist(HIST_STR,ifind,fPrev,szdst,szstr);
  2589.         if (ifind != 0) return ifind;
  2590.         ifind = IFIND_END_HISTSEARCH;
  2591.     }
  2592.     return _completeSearchHist(HIST_SEARCH,ifind,fPrev,szdst,szstr);
  2593. #else
  2594.     if (IFIND_TOP_HISTSTR <= ifind && ifind <= IFIND_END_HISTSTR) {
  2595.         ifind = _completeSearchHist(HIST_STR,ifind,fPrev,szdst,szstr);
  2596.         if (ifind == 0) {
  2597.             return _completeSearchHist(HIST_SEARCH,IFIND_END_HISTSEARCH,fPrev,szdst,szstr);
  2598.         }
  2599.         return ifind;
  2600.     } else {
  2601.         return _completeSearchHist(HIST_SEARCH,ifind,fPrev,szdst,szstr);
  2602.     }
  2603. #endif
  2604. }
  2605.  
  2606. static int _completeSearch(mchar szdst[CCHWORD],mchar* szstr,int ifind,BOOL fPrev,HSTRBLK sbComplete)
  2607. {
  2608.     szdst[0] = 0;
  2609.     if (ifind == IFIND_NONE) {
  2610.     } else if (ifind >= IFIND_HIST_TOP) {
  2611.         ifind = completeSearchHist(ifind,fPrev,szdst,szstr,sbComplete);
  2612.     } else {
  2613.         tx _txcomplete;
  2614.         tx *text = &_txcomplete;
  2615.         mchar szfilename[CCHPATHNAME];
  2616.         pathFullConfig(szfilename,"complete.dic");
  2617.         if (txInit(text,szfilename)) {
  2618.             if (fPrev) {
  2619.                 txJumpPara(text,ifind);
  2620.             } else {
  2621.                 txJumpPara(text,ifind + 1);
  2622.             }
  2623.             if (
  2624.                 szstr[0] && //2.99D 970402 新規作成で開いた直後、文字列の補完を行うとハングした
  2625.                 txSearchEx(text,szstr,(fPrev ? SEARCH_PREV : SEARCH_CUR)|SEARCH_NOSENSECASE|SEARCH_NOSENSEZENHAN|SEARCH_PARATOP)
  2626.             ) {
  2627.                 txstr sz;
  2628.                 txGetLine(text,sz);
  2629.                 ifind = text->npara;
  2630.                 strcpymax(szdst,sz,CCHWORD);
  2631.             } else {
  2632.                 if (fPrev) {
  2633.                     ifind = IFIND_HIST_TOP;
  2634.                 } else {
  2635.                     ifind = IFIND_NONE;
  2636.                 }
  2637.             }
  2638.         } else {
  2639.             if (fPrev) {
  2640.                 ifind = IFIND_HIST_TOP;
  2641.             } else {
  2642.                 ifind = IFIND_NONE;
  2643.             }
  2644.         }
  2645.         txClose(text);
  2646.     }
  2647.     return ifind;
  2648. }
  2649.  
  2650. static int completeSearch(mchar szdst[CCHWORD],mchar* szstr,int i,BOOL fPrev,HSTRBLK sbComplete)
  2651. {
  2652.     while(1) {
  2653.         i = _completeSearch(szdst,szstr,i,fPrev,sbComplete);
  2654.         if (i == IFIND_NONE) return i;
  2655.         if (szdst[0]) return i;
  2656.     }
  2657. }
  2658.  
  2659. static BOOL _complate(tx* text,BOOL fPrev,HSTRBLK sbComplete)
  2660. {
  2661.     static txstr _szstr;        // 前回検索をかけた文字列
  2662.     static int _ifind;            // 前回検索をかけたインデックス
  2663.     static IFILE _adr = -1;        // 前回検索をかけたアドレス
  2664.     static int _lchInsert;        // 前回挿入したバイト数
  2665.     static BOOL _fPrev = -1;    // 前回の方向
  2666.     static mchar szbuff[CCHWORD];// 前回挿入した文字列
  2667.     BOOL ret = FALSE;
  2668.     txstr szstr;
  2669.     IFILE adr = txGetAddress(text);
  2670.     
  2671.     if (adr == _adr) {
  2672.         if (_ifind == -1) {
  2673.             if (_fPrev == fPrev) {
  2674.                 return FALSE;
  2675.             } else {
  2676.                 if (fPrev) {
  2677.                     _ifind = IFIND_HIST_TOP - 1;
  2678.                 } else {
  2679.                     _ifind = IFIND_HIST_LAST;
  2680.                 }
  2681.             }
  2682.         }
  2683.     } else {
  2684.         if (szbuff[0]) sbAddHist(sbComplete,szbuff);    //2.96A 970214 学習
  2685.         txSelectEx(text,CLIP_CHAR);
  2686.         txLeft(text);
  2687.         txJumpWordTopMi(text);
  2688.         txGetWord(text,szstr);
  2689.         txSelectQuit(text);
  2690.         //1.99A 補完できないときにカーソルが単語の先頭に飛んだ
  2691.         txRightBytes(text,strlen(szstr));
  2692.         //
  2693.         _szstr = szstr;
  2694.         _ifind = IFIND_HIST_LAST;
  2695.         _lchInsert = 0;
  2696.     }
  2697.     {
  2698.         int i = completeSearch(szbuff,_szstr,_ifind,fPrev,sbComplete);
  2699.         if (i >= 0) {
  2700.             _ifind = i;
  2701.             if (_lchInsert) {
  2702.                 txLeftBytes(text,_lchInsert);
  2703.                 txDeleteBytes(text,_lchInsert);
  2704.             } else {
  2705.                 int lchOld = strlen(_szstr);
  2706.                 txLeftBytes(text,lchOld);//1.99A 
  2707.                 txDeleteBytes(text,lchOld);
  2708.             }
  2709.             _lchInsert = strlen(szbuff);
  2710.             txInsert(text,szbuff);
  2711.             ret = TRUE;
  2712.         } else {
  2713.             _ifind = -1;
  2714.         }
  2715.     }
  2716.     _adr = txGetAddress(text);
  2717.     _fPrev = fPrev;
  2718.     return ret;
  2719. }
  2720.  
  2721. static BOOL complate(tx* text,BOOL fPrev)
  2722. {
  2723.     HSTRBLK sb = historyOpen(_szCompleteHist,SIZE_COMPLETEHIST);
  2724.     BOOL ret;
  2725.     text->fUndispSelect++;
  2726.     text->fUndispCursor++;
  2727.     ret = _complate(text,fPrev,sb);
  2728.     text->fUndispSelect--;
  2729.     text->fUndispCursor--;
  2730.     txDispCursor(text);
  2731.     txDispLocate(text);
  2732.     historyClose(_szCompleteHist,sb);
  2733.     return ret;
  2734. }
  2735.  
  2736. //2.00B MS/VZキーに割り当て
  2737. BOOL TXCMDBASE completePrev(TX* text)
  2738. {
  2739. // 文字列補完の前候補
  2740. // 補完した文字列を前候補に戻します。
  2741. //2.99A 970321 {#MS} +^J -> {#MS} +^J +^{F4}
  2742. //{#MS} +^J +^{F4}
  2743. //{#VZ} +^{Tab}
  2744. //{#EMACS} +^{Tab}
  2745.     return complate(text,TRUE);
  2746. }
  2747.  
  2748. //2.99A 970321 {#MS} ^J -> {#MS} ^J +{F4}
  2749. //2.99G 970405  ^{F4} -> +^{F3} (^{F4}はキー割り当てできないため)
  2750. //2.00B MS/VZキーに割り当て
  2751. BOOL TXCMDBASE completeNext(TX* text)
  2752. {
  2753. // 文字列の補完実行(次候補)
  2754. // 英単語を途中まで入力した後実行すると、カーソルの直前単語を補完
  2755. // して完成させます。
  2756. //{#MS} ^J +{F4}
  2757. //{#VZ} ^{Tab}
  2758. //{#EMACS} ^{Tab}
  2759.     return complate(text,FALSE);
  2760. }
  2761.  
  2762. static BOOL completeAddDic(mchar* szstr)
  2763. {
  2764.     if (szstr[0] == 0) return FALSE;
  2765.     BOOL ret = FALSE;
  2766.     TX _txcomplete;
  2767.     TX* text = &_txcomplete;
  2768.     mchar szfilename[CCHPATHNAME];
  2769.     pathFullConfig(szfilename,"complete.dic");
  2770.     if (txInit(text,szfilename)) {
  2771.         BOOL f = FALSE;
  2772.         while(1) {
  2773.             if (txSearchEx(text,szstr,SEARCH_CUR|SEARCH_NOSENSECASE|SEARCH_NOSENSEZENHAN|SEARCH_PARATOP)) {
  2774.                 txstr sz;
  2775.                 txGetLine(text,sz);
  2776.                 if (!stricmp(sz,szstr)) {
  2777.                     f = TRUE;
  2778.                     informationex("%sは既に登録されています",szstr);
  2779.                     break;
  2780.                 }
  2781.                 if (!txNextPara(text)) break;
  2782.             } else {
  2783.                 break;
  2784.             }
  2785.         }
  2786.         if (!f) {
  2787.             txJumpFileTop(text);
  2788.             txInsert(text,szstr);
  2789.             txInsertReturn(text);
  2790.             txSave(text);
  2791.             informationex("%sを登録しました",szstr);
  2792.             ret = TRUE;
  2793.         }
  2794.     }
  2795.     txClose(text);
  2796.     return ret;
  2797. }
  2798.  
  2799. BOOL TXCMDBASE completeAdd(TX* text)
  2800. {
  2801. // 文字列補完辞書への単語登録...
  2802. // 検索文字列ヒストリーに記憶した単語はいずれ消えてしまいます。
  2803. // 恒久的に使用する単語は辞書ファイルに登録してください。
  2804.     HDIALOG hd = dialog("文字列補完辞書への登録");
  2805.     BOOL ret = FALSE;
  2806.     txstr szstr;
  2807.     
  2808.     dialogControlHist(hd,HIST_SEARCH);
  2809.     txGetWord(text,szstr);//2.92 completeAddでtxGetWordするようにした
  2810.     dialogStr(hd,"登録する文字列(&S):",szstr,20,30);
  2811.     if (dialogOpen(hd)) {
  2812.         ret = completeAddDic(szstr);
  2813.     }
  2814.     return ret;
  2815. }
  2816.  
  2817. //##入力支援
  2818. //3.00B1 970522 入力支援:テキストファイルを指定して、そのファイルを辞書として使って入力支援できるようにした
  2819.  
  2820. #include <windowsx.h>
  2821.  
  2822. #define HIST_COMPLETE    HIST_USER2
  2823.  
  2824. #define IDD_TOP_PREV        100
  2825. #define IDD_TOP_NEXT        101
  2826. #define IDD_END_PREV        102
  2827. #define IDD_END_NEXT        103
  2828. #define IDD_TARGET            104
  2829. //#define IDD_LIST            105
  2830. #define IDD_LISTCAPTION        106
  2831. #define IDD_TEXT            107
  2832. #define IDD_TEXTPARA        108    // 109も使用
  2833. #define IDD_HISTSEARCH        110
  2834. #define IDD_GUIDE            111
  2835. #define IDD_WRING            112
  2836. #define IDD_ADDDIC            113
  2837. #define IDD_LIST_PREVIEW    114
  2838. #define IDD_SELECT            115
  2839. #define IDD_REFERTEXTFILE    116
  2840. #define IDD_ALL                117
  2841.  
  2842. permanent BOOL _fSearchText = TRUE;
  2843. permanent BOOL _fSearchHistSearch = TRUE;
  2844. permanent BOOL _fSearchTextPara = FALSE;
  2845. permanent BOOL _fCompleteWring = TRUE;
  2846. permanent txstr p_szCompleteFile;//3.00B1 970522 
  2847. static mchar _szCompleteFileHist[] = "HIST_COMPLETE_FILE";//3.00B1 970522 
  2848.  
  2849. #define IDTIMER_COMPLETE    100
  2850. typedef struct {
  2851.     HSTRBLK sb;
  2852.     BOOL fEdit;
  2853.     BOOL fCanceled;//3.00B1 970522 
  2854.     TX* text;
  2855.     NPARA npara;
  2856.     mchar szTarget[CCHWORD];
  2857. } COMPLETECONTEXT;
  2858.  
  2859. static void myPostMessage(HWND hwnd,int message,WPARAM wParam,LPARAM lParam)
  2860. {
  2861.     MSG msg;
  2862.     if (PeekMessage(&msg,hwnd,message,message,PM_NOREMOVE)) {
  2863.         // 既にポストされている場合は、ポストしない
  2864.     } else {
  2865.         PostMessage(hwnd,message,wParam,lParam);
  2866.     }
  2867. }
  2868.  
  2869. static void FlushTarget(HWND hwnd)
  2870. {
  2871.     txstr szWord;
  2872.     txGetWord(text,szWord);
  2873.     SetDlgItemText(hwnd,IDD_TARGET,szWord);
  2874. }
  2875.  
  2876. static void FlushSelect(TX* text,BOOL fLeft)
  2877. {
  2878.     if (txFlushSelectNow(text)) {
  2879.         if (text->clipendnow <= text->cliptopnow) {
  2880.             if (fLeft) return;
  2881.             txSelectJump(text);
  2882.         }
  2883.         if (!fLeft) return;
  2884.         txSelectJump(text);
  2885.     }
  2886. }
  2887.  
  2888. static BOOL txSearchParaComplete(TX* text,mchar* szFind)
  2889. {
  2890. // szFindと完全に一致する行をtextが含んでいるかどうか返す
  2891.     txJumpFileTop(text);
  2892.     while(1) {
  2893.         int ret;
  2894.         if (ret = txSearchEx(text,szFind,SEARCH_CUR|SEARCH_PARATOP)) {
  2895.             txRightBytes(text,ret - 1);
  2896.             if (txIsCurReturn(text)) return TRUE;
  2897.         } else {
  2898.             return FALSE;
  2899.         }
  2900.     }
  2901. }
  2902.  
  2903. static int SearchTextDic(TX* textDst,TX* text,mchar* szTarget,SEARCHMODE mode,BOOL fReferFile)
  2904. {
  2905.     txstr szPara;
  2906.     if (txSearchEx(text,szTarget,SEARCH_NOSENSECASE|mode)) {
  2907.         if (_fSearchTextPara) {
  2908.             txGetPara(text,szPara);
  2909.             // 行頭のスペースを削除
  2910.             mchar*p = szPara;
  2911.             while(1) {
  2912.                 if (isspace(*p)) {
  2913.                     p++;
  2914.                 } else if (*p == '/' && p[1] == '/') {
  2915.                     p += 2;
  2916.                 } else {
  2917.                     break;
  2918.                 }
  2919.             }
  2920.             if (fReferFile) txInsertChar(textDst,'f');//3.00B1 970522 p_szCompleteFileからのデータであることを示す
  2921.             txInsertf(textDst,"%5d:",text->npara);//2.98 970309 
  2922.             txInsertLine(textDst,p);
  2923.             return TRUE;
  2924.         } else {
  2925.             int lch = strlen(szTarget);
  2926.             IFILE adr = txGetAddress(text);
  2927.             txJumpWordTopMi(text);
  2928.             txSelectEx(text,CLIP_CHAR);
  2929.             txJumpWordEndMi(text);
  2930.             txGetWord(text,szPara);
  2931.             txJumpAddress(text,adr);
  2932.             if (_fCompleteWring && strnicmp(szPara,szTarget,lch)) {
  2933.                 // 絞り込みの場合で、単語頭が一致しない場合
  2934.             } else {
  2935.                 if (!txSearchParaComplete(textDst,szPara)) {
  2936.                     txJumpFileEnd(textDst);
  2937.                     txInsertLine(textDst,szPara);
  2938.                     return TRUE;
  2939.                 }
  2940.             }
  2941.         }
  2942.         return FALSE;
  2943.     }
  2944.     return -1;
  2945. }
  2946.  
  2947.  
  2948. static void GetTextDic(COMPLETECONTEXT* context,TX* text,HWND hwnd,TX* text0,txstr szTarget,BOOL fReferFile)
  2949. {
  2950.     BOOL fSelect = text->fClip;
  2951.     txFlushSelectNow(text);
  2952.     IFILE cliptopnow = text->cliptopnow;
  2953.     IFILE adr = txGetAddress(text);
  2954.     int n = 0;
  2955.     int ly = text->ly;
  2956.     txSetUndisp(text);
  2957.     if (!_fSearchTextPara) {
  2958.         // 単語取得の場合は、2つ、カーソル位置の近くで補完をする
  2959.         SearchTextDic(text0,text,szTarget,SEARCH_PREV,fReferFile);
  2960.         SearchTextDic(text0,text,szTarget,SEARCH_PREV,fReferFile);
  2961.         SearchTextDic(text0,text,szTarget,SEARCH_PREV,fReferFile);
  2962.     }
  2963.     txJumpFileTop(text);
  2964.     {
  2965.         while(1) {
  2966.             int ret = SearchTextDic(text0,text,szTarget,0,fReferFile);
  2967.             if (GetAsyncKeyState(VK_ESCAPE) < 0) {//3.00B1 970522 入力支援:検索に時間がかかるときは{Esc}で中止できるようにした
  2968.                 SetDlgItemText(hwnd,IDD_GUIDE,"(中止しました)");
  2969.                 context->fCanceled = TRUE;
  2970.                 break;
  2971.             }
  2972.             if (ret == TRUE) {
  2973.                 n++;
  2974.                 if (n > 20) {
  2975.                     //あまり多いときは途中でやめないと遅い
  2976.                     SetDlgItemText(hwnd,IDD_GUIDE,"(マッチ数が多いので省略しました)");
  2977.                     break;
  2978.                 }
  2979.             } else if (ret == -1) {
  2980.                 break;
  2981.             }
  2982.         }
  2983.     }
  2984.     if (fSelect) {
  2985.         txJumpAddress(text,cliptopnow);
  2986.         txSetLy(text,ly);
  2987.         txSelectEx(text,CLIP_CHAR);
  2988.         text->fClipMouse = TRUE;
  2989.     } else {
  2990.         txSelectQuit(text);
  2991.         txJumpAddress(text,adr);
  2992.         txSetLy(text,ly);
  2993.     }
  2994.     txSetDispEx(text);
  2995. }
  2996.  
  2997. static void makeCompleteFormText(TX* textDst,TX* text,mchar* szTarget)
  2998. {
  2999.     SEARCHMODE mode = _fCompleteWring ? SEARCH_PARATOP : 0;
  3000.     txstr sz;
  3001.     while(1) {
  3002.         if (txSearchEx(text,szTarget,mode|SEARCH_NOSENSECASE|SEARCH_CUR)) {
  3003.             txGetPara(text,sz);
  3004.             if (!txSearchParaComplete(textDst,sz)) {
  3005.                 txJumpFileEnd(textDst);
  3006.                 txInsertLine(textDst,sz);
  3007.             }
  3008.             txNextPara(text);
  3009.         } else {
  3010.             break;
  3011.         }
  3012.     }
  3013. }
  3014.  
  3015. static void makeCompleteFormStrblk(TX* textDst,HSTRBLK sb,mchar* szTarget)
  3016. {
  3017.     sbSetSenseCase(sb,FALSE);
  3018.     int n = sbGetCount(sb);
  3019.     for (;n--;) {
  3020.         mchar* sz = sbRead(sb,n);
  3021.         mchar* p;
  3022.         if (p = stristr(sz,szTarget)) {
  3023.             if (_fCompleteWring && p != sz) {
  3024.             } else {
  3025.                 if (!txSearchParaComplete(textDst,sz)) {
  3026.                     txJumpFileEnd(textDst);
  3027.                     txInsertLine(textDst,sz);
  3028.                 }
  3029.             }
  3030.         }
  3031.     }
  3032. }
  3033.  
  3034. static BOOL uiCompleteAddDic(mchar* _szStr)
  3035. {
  3036.     HDIALOG hd = dialog("文字列補完辞書への登録");
  3037.     BOOL ret = FALSE;
  3038.     txstr szStr = _szStr;
  3039.     dialogStr(hd,"登録する文字列(&S):",szStr,20,30);
  3040.     if (dialogOpen(hd)) {
  3041.         ret = completeAddDic(szStr);
  3042.     }
  3043.     return ret;
  3044. }
  3045.  
  3046. BOOL dlgprocComplete(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  3047. {
  3048.     HDIALOG hd = dialogFromHwnd(hwnd);
  3049.     COMPLETECONTEXT* context = (LPVOID)dialogGetCustdata(hd);
  3050.     switch(message) {
  3051.         case WM_INITDIALOG: {
  3052.             myPostMessage(hwnd,WM_TXUSER,0,0);
  3053.             // フォーカス順序をリストボックスをテキストボックスの直後にする
  3054.             SetWindowPos(GetDlgItem(hwnd,IDD_LISTCAPTION),GetDlgItem(hwnd,IDD_TARGET),0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
  3055.             SetWindowPos(GetDlgItem(hwnd,IDD_LIST),GetDlgItem(hwnd,IDD_LISTCAPTION),0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
  3056.             //
  3057.             HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
  3058.             TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
  3059.             if (text) {
  3060.                 text->fScrollBarH = TRUE;
  3061.                 text->fScrollBarV = TRUE;
  3062.                 text->fDispLine = FALSE;
  3063.                 text->dlgcode = DLGC_WANTARROWS;
  3064.                 text->fNoCursor = TRUE;
  3065.                 txFlush(text);
  3066.             }
  3067.             break;
  3068.         }
  3069.         case WM_COMMAND: {
  3070.             int id = WM_COMMAND_GetId(wParam);
  3071.             int notify = WM_COMMAND_GetNotify(wParam,lParam);
  3072.             if (id == IDD_LIST) {
  3073.                 if (notify == LBN_DBLCLK) {//2.98 970309 
  3074.                     PostMessage(hwnd,WM_COMMAND,IDOK,0);
  3075.                     return FALSE;
  3076.                 } else if (notify == LBN_SELCHANGE) {
  3077.                     HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
  3078.                     int isel = ListBox_GetCurSel(hctrl);
  3079.                     if (isel >= 0) {
  3080.                         txstr sz(ListBox_GetTextLen(hctrl,isel)+1);
  3081.                         if (sz) {
  3082.                             ListBox_GetText(hctrl,isel,sz);
  3083.                             //
  3084.                             HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
  3085.                             TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
  3086.                             if (text) {
  3087.                                 txSetUndisp(text);
  3088.                                 txDeleteText(text);
  3089.                                 if (_fSearchTextPara) {
  3090.                                     TX* textTarget = context->text;
  3091.                                     mchar*p = strGetWordTop(sz);
  3092.                                     if (*p == 'f') {//3.00B1 970522 p_szCompleteFileからのデータ
  3093.                                         p += strGetWordLen(p);
  3094.                                         p = strGetWordTop(p);
  3095.                                         NPARA npara = atoi(p);
  3096.                                         TX* text = textopen(p_szCompleteFile);
  3097.                                         if (text) {
  3098.                                             txJumpNpara(text,npara);
  3099.                                             txGetPara(text,sz);
  3100.                                         }
  3101.                                         textclose(text);
  3102.                                     } else {
  3103.                                         NPARA npara = atoi(p);
  3104.                                         textTarget->fNoCursor++;
  3105.                                         txSetUndispEx(textTarget);
  3106.                                         txJumpNpara(textTarget,npara);
  3107.                                         txGetPara(textTarget,sz);
  3108.                                     }
  3109.                                     txInsert(text,sz);
  3110.                                     txSetDispEx(textTarget);
  3111.                                     textTarget->fNoCursor--;
  3112.                                     //
  3113.                                     txJumpFileTop(text);
  3114.                                     txSearchEx(text,context->szTarget,SEARCH_CUR|SEARCH_SELECT|SEARCH_NOSENSECASE);
  3115.                                     txJumpWordTop(text);
  3116.                                     txSelectEx(text,CLIP_CHAR);
  3117.                                     txJumpWordEnd(text);
  3118.                                 } else {
  3119.                                     txInsert(text,sz);
  3120.                                 }
  3121.                                 txSetDisp(text);
  3122.                             }
  3123.                         }
  3124.                     }
  3125.                 }
  3126.             }
  3127.             switch(id) {
  3128.                 case IDCANCEL: {//3.00B1 970522 
  3129.                     if (context->fCanceled) {
  3130.                         context->fCanceled = FALSE;
  3131.                         return TRUE;
  3132.                     }
  3133.                     break;
  3134.                 }
  3135.                 case IDOK: {
  3136.                     HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
  3137.                     int isel = ListBox_GetCurSel(hctrl);
  3138.                     if (isel >= 0) {
  3139.                         txstr sz(ListBox_GetTextLen(hctrl,isel)+1);
  3140.                         if (sz) {
  3141.                             ListBox_GetText(hctrl,isel,sz);
  3142.                             if (!context->fEdit) {
  3143.                                 // 補完文字列が変化してなければ...
  3144.                                 txSelectDelete(text);
  3145.                             }
  3146.                             if (_fSearchTextPara) {//2.98 970309 
  3147.                                 HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
  3148.                                 TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
  3149.                                 if (text) {
  3150.                                     TX* textTarget = context->text;
  3151.                                     if (text->fClip) {
  3152.                                         txPrivatePush(text);
  3153.                                         txPrivatePaste(textTarget);
  3154.                                         txPrivateDeleteTop(text);
  3155.                                     } else {
  3156.                                         txInsertText(textTarget,text);
  3157.                                     }
  3158.                                 }
  3159.                             } else {
  3160.                                 txInsert(text,sz);
  3161.                                 // 補完ヒストリに追加
  3162.                                 sbAddHist(context->sb,sz);
  3163.                             }
  3164.                         }
  3165.                     }
  3166.                     break;
  3167.                 }
  3168.                 case IDD_TARGET: {
  3169.                     if (notify == EN_UPDATE) {
  3170.                         context->fEdit = TRUE;
  3171.                         SetTimer(hwnd,IDTIMER_COMPLETE,500,NULL);
  3172.                     }
  3173.                     break;
  3174.                 }
  3175. #if 1//2.98 970309 
  3176.                 case IDD_TOP_PREV: {
  3177.                     HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
  3178.                     TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
  3179.                     if (text) {
  3180.                         FlushSelect(text,TRUE);
  3181.                         txLeftWordMi(text);
  3182.                     }
  3183.                     break;
  3184.                 }
  3185.                 case IDD_TOP_NEXT: {
  3186.                     HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
  3187.                     TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
  3188.                     if (text) {
  3189.                         FlushSelect(text,TRUE);
  3190.                         txRightWordMi(text);
  3191.                     }
  3192.                     break;
  3193.                 }
  3194.                 case IDD_END_PREV: {
  3195.                     HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
  3196.                     TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
  3197.                     if (text) {
  3198.                         FlushSelect(text,FALSE);
  3199.                         txLeftWordMi(text);
  3200.                     }
  3201.                     break;
  3202.                 }
  3203.                 case IDD_END_NEXT: {
  3204.                     HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
  3205.                     TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
  3206.                     if (text) {
  3207.                         FlushSelect(text,FALSE);
  3208.                         txRightWordMi(text);
  3209.                     }
  3210.                     break;
  3211.                 }
  3212.                 case IDD_ALL: {//3.00B1 970522 
  3213.                     HWND hctrl = GetDlgItem(hwnd,IDD_LIST_PREVIEW);
  3214.                     TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
  3215.                     if (text) txSelectAll(text);
  3216.                     break;
  3217.                 }
  3218. #else
  3219.                 case IDD_TOP_PREV: {
  3220.                     FlushSelect(text,TRUE);
  3221.                     txLeft(text);
  3222.                     FlushTarget(hwnd);
  3223.                     myPostMessage(hwnd,WM_TXUSER,id,0);
  3224.                     break;
  3225.                 }
  3226.                 case IDD_TOP_NEXT: {
  3227.                     FlushSelect(text,TRUE);
  3228.                     txRight(text);
  3229.                     FlushTarget(hwnd);
  3230.                     myPostMessage(hwnd,WM_TXUSER,id,0);
  3231.                     break;
  3232.                 }
  3233.                 case IDD_END_PREV: {
  3234.                     FlushSelect(text,FALSE);
  3235.                     txLeft(text);
  3236.                     FlushTarget(hwnd);
  3237.                     myPostMessage(hwnd,WM_TXUSER,id,0);
  3238.                     break;
  3239.                 }
  3240.                 case IDD_END_NEXT: {
  3241.                     FlushSelect(text,FALSE);
  3242.                     txRight(text);
  3243.                     FlushTarget(hwnd);
  3244.                     myPostMessage(hwnd,WM_TXUSER,id,0);
  3245.                     break;
  3246.                 }
  3247. #endif
  3248.                 case IDD_REFERTEXTFILE: {//3.00B1 970522 
  3249.                     if (notify == EN_CHANGE) {
  3250.                         myPostMessage(hwnd,WM_TXUSER,id,0);
  3251.                     }
  3252.                     break;
  3253.                 }
  3254.                 case IDD_WRING:
  3255.                 case IDD_TEXT:
  3256.                 case IDD_TEXTPARA:
  3257.                 case IDD_TEXTPARA+1:
  3258.                 case IDD_HISTSEARCH: {
  3259.                     myPostMessage(hwnd,WM_TXUSER,id,0);
  3260.                     break;
  3261.                 }
  3262.                 case IDD_JUMP: {//2.98 970310 
  3263.                     HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
  3264.                     int isel = ListBox_GetCurSel(hctrl);
  3265.                     if (isel >= 0) {
  3266.                         txstr sz(ListBox_GetTextLen(hctrl,isel)+1);
  3267.                         if (sz) {
  3268.                             ListBox_GetText(hctrl,isel,sz);
  3269.                             txSetUndisp(text);
  3270.                             txSelectQuit(text);
  3271.                             txJumpNpara(text,atoi(strGetWordTop(sz)));
  3272.                             txSetDisp(text);
  3273.                             return FALSE;
  3274.                         }
  3275.                     }
  3276.                     return TRUE;
  3277.                 }
  3278.                 case IDD_ADDDIC: {
  3279.                     HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
  3280.                     int isel = ListBox_GetCurSel(hctrl);
  3281.                     if (isel >= 0) {
  3282.                         txstr sz(ListBox_GetTextLen(hctrl,isel)+1);
  3283.                         if (sz) {
  3284.                             ListBox_GetText(hctrl,isel,sz);
  3285.                             uiCompleteAddDic(sz);
  3286.                         }
  3287.                     } else {
  3288.                         mchar buff[CCHWORD];
  3289.                         GetDlgItemText(hwnd,IDD_TARGET,buff,cchof(buff));
  3290.                         uiCompleteAddDic(buff);
  3291.                     }
  3292.                     return TRUE;
  3293.                 }
  3294.             }
  3295.             return FALSE;
  3296.         }
  3297.         case WM_DESTROY: {
  3298.             KillTimer(hwnd,IDTIMER_COMPLETE);
  3299.             break;
  3300.         }
  3301.         case WM_TIMER: {
  3302.             KillTimer(hwnd,IDTIMER_COMPLETE);
  3303.             myPostMessage(hwnd,WM_TXUSER,IDD_TARGET,0);
  3304.             break;
  3305.         }
  3306.         case WM_TXUSER: {
  3307.             if (wParam == 0) {
  3308.                 // 初めのダイアログデータのセットによるEDITBOXのダーティー処理は無効化
  3309.                 context->fEdit = FALSE;
  3310.                 KillTimer(hwnd,IDTIMER_COMPLETE);
  3311.             }
  3312.             // WM_COMMANDが残っている場合は処理しない。高速化
  3313.             MSG msg;
  3314.             if (PeekMessage(&msg,hwnd,WM_COMMAND,WM_COMMAND,PM_NOREMOVE)) {
  3315.                 myPostMessage(hwnd,WM_TXUSER,wParam,0);
  3316.                 return FALSE;
  3317.             }
  3318.             //
  3319.             dialogRead(hd);
  3320.             //2.98 970309 
  3321.             EnableWindow(GetDlgItem(hwnd,IDD_TEXTPARA),(_fSearchText||p_szCompleteFile[0]));
  3322.             EnableWindow(GetDlgItem(hwnd,IDD_HISTSEARCH),!_fSearchTextPara);
  3323.             EnableWindow(GetDlgItem(hwnd,IDD_WRING),!_fSearchTextPara);
  3324.             EnableWindow(GetDlgItem(hwnd,IDD_TOP_PREV),_fSearchTextPara);
  3325.             EnableWindow(GetDlgItem(hwnd,IDD_TOP_NEXT),_fSearchTextPara);
  3326.             EnableWindow(GetDlgItem(hwnd,IDD_END_PREV),_fSearchTextPara);
  3327.             EnableWindow(GetDlgItem(hwnd,IDD_END_NEXT),_fSearchTextPara);
  3328.             EnableWindow(GetDlgItem(hwnd,IDD_JUMP),_fSearchTextPara && _fSearchTextPara);
  3329.             //
  3330.             switch(wParam) {
  3331.                 case IDD_LIST: break;
  3332.                 default: {
  3333.                     TX _text0;
  3334.                     TX* text0 = &_text0;
  3335.                     if (txInit(text0,NULL)) {
  3336.                         txstr szTarget;
  3337.                         GetDlgItemText(hwnd,IDD_TARGET,szTarget,cchtxstr(szTarget));
  3338.                         {// タブ等は除く
  3339.                             mchar* dst = szTarget;
  3340.                             mchar* src = szTarget;
  3341.                             while(1) {
  3342.                                 mchar c = *src++;
  3343.                                 if (c == 0) break;
  3344.                                 if (iskanji(c) && *src) {
  3345.                                     *dst++ = c;
  3346.                                     *dst++ = *src++;
  3347.                                 } else if (c > ' ') {
  3348.                                     *dst++ = c;
  3349.                                 }
  3350.                             }
  3351.                             *dst = 0;
  3352.                         }
  3353.                         sstrcpy(context->szTarget,szTarget);
  3354.                         if (szTarget[0]) {
  3355.                             SetDlgItemText(hwnd,IDD_GUIDE,"");
  3356.                             if (!_fSearchTextPara) {
  3357.                                 // [1]補完ヒストリから検索
  3358.                                 makeCompleteFormStrblk(text0,context->sb,szTarget);
  3359.                                 // [2]キーワードから検索
  3360.                                 if (text->txKeyword) {
  3361.                                     makeCompleteFormText(text0,text->txKeyword,szTarget);
  3362.                                 }
  3363.                                 // [3]complete.dicから検索
  3364.                                 {
  3365.                                     mchar szfilename[CCHPATHNAME];
  3366.                                     pathFullConfig(szfilename,"complete.dic");
  3367.                                     TX _txcomplete;
  3368.                                     TX* text = &_txcomplete;
  3369.                                     if (txInit(text,szfilename)) {
  3370.                                         makeCompleteFormText(text0,text,szTarget);
  3371.                                         txClose(text);
  3372.                                     }
  3373.                                 }
  3374.                                 // [4]検索ヒストリから検索
  3375.                                 if (_fSearchHistSearch) {
  3376.                                     makeCompleteFormStrblk(text0,sbFromHist(HIST_SEARCH),szTarget);
  3377.                                 }
  3378.                             }
  3379.                             // [5]テキストから検索
  3380.                             if (_fSearchText) {
  3381.                                 GetTextDic(context,context->text,hwnd,text0,szTarget,FALSE);
  3382.                             }
  3383.                             if (p_szCompleteFile[0]) {//3.00B1 970522 
  3384.                                 TX* text = textopen(p_szCompleteFile);
  3385.                                 if (text) {
  3386.                                     GetTextDic(context,text,hwnd,text0,szTarget,TRUE);
  3387.                                 }
  3388.                                 textclose(text);
  3389.                             }
  3390.                         }
  3391.                         listboxFromText(GetDlgItem(hwnd,IDD_LIST),text0);
  3392.                         txClose(text0);
  3393.                         //
  3394.                         HWND hctrl = GetDlgItem(hwnd,IDD_LIST);
  3395.                         int isel = ListBox_GetCurSel(hctrl);
  3396.                         if (isel < 0) ListBox_SetCurSel(hctrl,0);
  3397.                         FORWARD_WM_COMMAND(hwnd,IDD_LIST,NULL,LBN_SELCHANGE,SendMessage);//2.98 970309 
  3398.                         if (wParam != IDD_TARGET && szTarget[0]) {
  3399.                             SetFocus(hctrl);
  3400.                         }
  3401.                     }
  3402.                     break;
  3403.                 }
  3404.             }
  3405.             break;
  3406.         }
  3407.     }
  3408.     return FALSE;
  3409. }
  3410.  
  3411. BOOL TXCMDBASE uiComplete(TX* text)
  3412. {
  3413. // 入力支援
  3414. //2.95 970131 新コマンド
  3415. //2.99A 970321 MS:F4割り当て
  3416. //{#MS} {F4}
  3417.     HSTRBLK sb = historyOpen(_szCompleteHist,SIZE_COMPLETEHIST);
  3418.     HSTRBLK sbFile = historyOpen(_szCompleteFileHist,2048);//3.00B1 970522 
  3419.     if (!sb) return FALSE;
  3420.     COMPLETECONTEXT context;
  3421.     structClear(context);
  3422.     context.sb = sb;
  3423.     context.text = text;
  3424.     //
  3425.     txstr szTarget;
  3426.     if (text->fClip) {
  3427.         txGetWord(text,szTarget);
  3428.         text->fClipMouse = TRUE;
  3429.     } else {
  3430.         if (!txIsCurParaTop(text)) {
  3431.             txSelectEx(text,CLIP_CHAR);
  3432.             text->fClipMouse = TRUE;
  3433.             txLeftWordMi(text);
  3434.             txGetWord(text,szTarget);
  3435.         }
  3436.     }
  3437.     if (szTarget[0] <= ' ') {
  3438.         // 空白や改行なら、補完対象文字列はなしとする
  3439.         szTarget[0] = 0;
  3440.         context.fEdit = TRUE;
  3441.         txSelectQuit(text);
  3442.     }
  3443.     HDIALOG hd = dialog("入力支援");
  3444.     dialogSetHookEx(hd,"\m.dlgprocComplete");
  3445.     dialogSetCustdata(hd,(DWORD)&context);
  3446.     int lxg = 16;
  3447.     int lx = 20;
  3448.     dialogControlID(hd,IDD_TARGET);
  3449.     dialogControlHelp(hd,406);
  3450.     dialogStr(hd,"補完対象(&S):",szTarget,lxg,lx);
  3451. #if 0    // 要らん
  3452.     dialogSetH(hd);
  3453.         dialogSetPosLX(hd,lxg + 1);
  3454.         dialogControlID(hd,IDD_TOP_PREV);
  3455.         dialogButton(hd,"&<",NULL,2);
  3456.         dialogControlID(hd,IDD_TOP_NEXT);
  3457.         dialogButton(hd,"&>",NULL,2);
  3458.         dialogSetPosLX(hd,lxg + lx - 8);
  3459.         dialogControlID(hd,IDD_END_PREV);
  3460.         dialogButton(hd,"< &B",NULL,4);
  3461.         dialogControlID(hd,IDD_END_NEXT);
  3462.         dialogButton(hd,"> &N",NULL,4);
  3463.     dialogSetV(hd);
  3464.     dialogLF(hd);
  3465. #endif
  3466.     
  3467.     dialogControlID(hd,IDD_LISTCAPTION);
  3468.     dialogCaptionDynamic(hd,"補完候補(&I):",20);
  3469.     dialogControlID(hd,IDD_LIST);
  3470.     dialogList(hd,NULL,NULL,40,_fwin40 ? 13 : 10);//2.99C 970326 WZ32で小さかった
  3471.     
  3472.     dialogControlID(hd,IDD_GUIDE);
  3473.     dialogCaptionDynamic(hd,NULL,40);
  3474.     
  3475.     DTRECT rCmd;
  3476.     dialogLFV(hd);
  3477.     dialogGetPos(hd,&rCmd);
  3478.     dialogLF(hd);
  3479. #if 1//2.98 970309 
  3480.     DTRECT r;
  3481.     dialogGetPos(hd,&r);
  3482.     r.cx = DTCX * 60;
  3483.     r.cy = DTCY * 4;
  3484.     __dialogAddItem(hd,TXWS_SZCLASS,"",IDD_LIST_PREVIEW,&r,TXWS_TEXT|TXWS_OPENTEXT|WS_CHILD|WS_VISIBLE|WS_BORDER|WS_VSCROLL|WS_HSCROLL);
  3485.     r.y += r.cy + DTCYINT;
  3486.     dialogSetPos(hd,&r);
  3487.     dialogSetH(hd);
  3488.     dialogControlID(hd,IDD_TOP_PREV);
  3489.     dialogButton(hd,"&<",NULL,10);
  3490.     dialogControlID(hd,IDD_TOP_NEXT);
  3491.     dialogButton(hd,"> &K",NULL,10);
  3492.     //3.00B1 970522 
  3493.     dialogIndent(hd,3);
  3494.     dialogControlID(hd,IDD_ALL);
  3495.     dialogButton(hd,"全て(&A)",NULL,10);
  3496.     //
  3497.     dialogSetPosLX(hd,60 - 21);
  3498.     dialogControlID(hd,IDD_END_PREV);
  3499.     dialogButton(hd,"< &L",NULL,10);
  3500.     dialogControlID(hd,IDD_END_NEXT);
  3501.     dialogButton(hd,"&>",NULL,10);
  3502.     dialogSetV(hd);
  3503. #else
  3504.     dialogControlID(hd,IDD_LIST_PREVIEW);
  3505.     dialogControlStyle(hd,WS_GROUP|ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|ES_AUTOHSCROLL|WS_HSCROLL|WS_VSCROLL);
  3506.     dialogEdit(hd,NULL,NULL,60,4);
  3507.     dialogControlStyle(hd,0);
  3508. #endif
  3509.     //3.00B1 970522 
  3510.     dialogLF(hd);
  3511.     dialogSpaceV(hd);
  3512.     dialogControlHist(hd,sbFile);
  3513.     dialogControlRefer(hd,"-a");
  3514.     dialogControlHelp(hd,511);
  3515.     dialogControlID(hd,IDD_REFERTEXTFILE);
  3516.     dialogStr(hd,"参照テキストファイル(&F):",p_szCompleteFile,17,33);
  3517.     //
  3518.     dialogLFV(hd);
  3519.     dialogSetPos(hd,&rCmd);
  3520.     dialogOK(hd,19);
  3521.     dialogCancel(hd,19);
  3522.     dialogSpaceV(hd);
  3523.     //2.96 970201 
  3524.     dialogControlID(hd,IDD_ADDDIC);
  3525.     dialogControlHelp(hd,407);
  3526.     dialogCmd(hd,"辞書に追加(&D)...",19);//2.98 970309 UI化
  3527.     dialogControlID(hd,IDD_JUMP);
  3528.     dialogCmd(hd,"ジャンプ(&J)",19);//2.98 970310 
  3529.     
  3530.     dialogSpaceV(hd);
  3531.     
  3532.     dialogControlID(hd,IDD_TEXT);
  3533.     dialogControlHelp(hd,408);
  3534.     dialogCheck(hd,"テキストも検索(&T)",&_fSearchText);
  3535.     //2.98 970309 入力支援:「段落の取得」復活
  3536.     // 常用はしないけど、さっき入力したところをもう一度という無計画なとこが、
  3537.     // 元の入力支援のいいとこだったと思うんです(kitamakuraさん)。
  3538.         dialogIndent(hd,2);
  3539.         dialogControlRadioV(hd);
  3540.         dialogControlID(hd,IDD_TEXTPARA);
  3541.         dialogControlHelp(hd,411);
  3542.         dialogCheck(hd,"段落取得(&P)",&_fSearchTextPara);
  3543.         dialogIndent(hd,-2);
  3544.     dialogControlID(hd,IDD_HISTSEARCH);
  3545.     dialogControlHelp(hd,409);
  3546.     dialogCheck(hd,"検索ヒストリも検索(&H)",&_fSearchHistSearch);
  3547.     dialogControlID(hd,IDD_WRING);
  3548.     dialogControlHelp(hd,410);
  3549.     dialogCheck(hd,"絞り込み(&R)",&_fCompleteWring);
  3550.     
  3551.     dialogOpen(hd);
  3552.     historyClose(_szCompleteFileHist,sbFile);
  3553.     historyClose(_szCompleteHist,sb);
  3554. }
  3555.  
  3556. //##慣用句挿入
  3557.  
  3558. #include <windows.h>
  3559. #include "dialog.h"
  3560. #include "outline.h"
  3561.  
  3562. #define IDD_ADD                101
  3563. #define IDD_EDIT            102
  3564. #define IDD_EDITBOX            103
  3565. //2.92 
  3566. #define IDD_ADDCATEGORY        104
  3567. #define IDD_COPY            105
  3568. #define IDD_PASTE            106
  3569. //#define IDD_DEL        104
  3570. //3.00B1 970612 
  3571. #define IDD_INSERTTAB        110
  3572.  
  3573. permanent int tmpl_isel = 0;
  3574.  
  3575. BOOL TXAPI txConvertDic(TX* text)
  3576. {
  3577. // .dicの形式をWZ2.0->WZ3.0へ自動変換
  3578.     txJumpFileTop(text);
  3579.     txstr szline;
  3580.     txGetPara(text,szline);
  3581.     if (szline[0] == '[') {
  3582.         // WZ2.0形式
  3583.         txInsertLine(text,"%sWZ2.0",text->tsztitle[0]);
  3584.         while(1) {
  3585.             txGetPara(text,szline);
  3586.             int lch = strlen(szline);
  3587.             if (szline[0] == '[' && szline[lch - 1] == ']') {
  3588.                 txDeleteChar(text);
  3589.                 txInsert(text,text->tsztitle[1]);
  3590.                 txJumpParaEnd(text);
  3591.                 txDeletePrev(text);
  3592.             }
  3593.             if (!txNextPara(text)) break;
  3594.         }
  3595.         txSave(text);
  3596.         return TRUE;
  3597.     }
  3598.     return FALSE;
  3599. }
  3600.  
  3601. static void txSaveTemplate(TX* text)
  3602. {
  3603.     // del EOF
  3604.     txJumpFileEnd(text);
  3605.     txPrevPara(text);
  3606.     txDeletePara(text);
  3607.     //
  3608.     txSave(text);
  3609. }
  3610.  
  3611. BOOL dlgprocTemplateEdit(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  3612. {
  3613. //3.00B1 970612 new
  3614.     switch(message) {
  3615.         case WM_COMMAND: {
  3616.             int id = WM_COMMAND_GetId(wParam);
  3617.             if (id == IDD_INSERTTAB) {
  3618.                 SendDlgItemMessage(hwnd,IDD_EDITBOX,EM_REPLACESEL,0,"\t");
  3619.                 return TRUE;
  3620.             }
  3621.             break;
  3622.         }
  3623.     }
  3624.     return FALSE;
  3625. }
  3626.  
  3627. BOOL dlgprocTemplate(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  3628. {
  3629.     switch(message) {
  3630.         case WM_INITDIALOG: {
  3631.             EnableWindow(GetDlgItem(hwnd,IDD_PASTE),FALSE);
  3632.             break;
  3633.         }
  3634.         case WM_COMMAND: {
  3635.             int id = WM_COMMAND_GetId(wParam);
  3636.             int notify = WM_COMMAND_GetNotify(wParam,lParam);
  3637.             TX* text = outlineGetTx(hwnd);
  3638.             long cur = outlineGetCursel(hwnd);
  3639.             switch(id) {
  3640.                 case IDOK: {
  3641.                     if (text->fEdit) {
  3642.                         txSaveTemplate(text);
  3643.                     }
  3644.                     tmpl_isel = cur;
  3645.                     break;
  3646.                 }
  3647.                 case IDCANCEL: {
  3648.                     if (text->fEdit) {
  3649.                         int q = question("編集内容を保存しますか?");
  3650.                         if (q == IDYES) {
  3651.                             txSaveTemplate(text);
  3652.                         } else if (q == IDCANCEL) {
  3653.                             return TRUE;
  3654.                         }
  3655.                     }
  3656.                     break;
  3657.                 }
  3658.                 case IDD_COPY: {//2.92 
  3659.                     outlineCopy(hwnd);
  3660.                     EnableWindow(GetDlgItem(hwnd,IDD_PASTE),TRUE);
  3661.                     break;
  3662.                 }
  3663.                 case IDD_PASTE: {//2.92 
  3664.                     txPaste(text);
  3665.                     outlineFlush(hwnd);
  3666.                     outlineSetCursel(hwnd,cur);
  3667.                     break;
  3668.                 }
  3669.                 case IDD_ADD:
  3670.                 case IDD_ADDCATEGORY:
  3671.                 case IDD_EDIT: {
  3672.                     BOOL fEdit = (id == IDD_EDIT);
  3673.                     HEADLINE hl;
  3674.                     outlineGetCurheadline(hwnd,&hl);
  3675.                     BOOL fCategory = (id == IDD_ADDCATEGORY || (fEdit && hl.nest == 1));
  3676.                     //
  3677.                     HDIALOG hd;
  3678.                     if (fEdit) {
  3679.                         if (fCategory) {
  3680.                             hd = dialog("グループ名の変更");
  3681.                         } else {
  3682.                             hd = dialog("慣用句の編集");
  3683.                         }
  3684.                     } else {
  3685.                         if (fCategory) {
  3686.                             hd = dialog("グループの追加");
  3687.                         } else {
  3688.                             hd = dialog("慣用句の追加");
  3689.                         }
  3690.                     }
  3691.                     //
  3692.                     txstr szstr = hl.szstr;
  3693.                     if (fCategory) {
  3694.                         dialogStr(hd,"グループ名(&C):",szstr,12,20);
  3695.                         if (dialogOpen(hd) && szstr != "") {
  3696.                             if (hl.npara == 0) {
  3697.                                 txJumpFileTop(text);
  3698.                             } else {
  3699.                                 txJumpPara(text,hl.npara);
  3700.                             }
  3701.                             //
  3702.                             if (fCategory && fEdit) {
  3703.                                 txDeletePara(text);
  3704.                             }
  3705.                             txInsertLine(text,"%s%s",text->tsztitle[0+!fCategory],szstr);
  3706.                         }
  3707.                     } else {
  3708.                         dialogStr(hd,"慣用句(&T):",szstr,12,20);
  3709.                         //
  3710.                         TX body;
  3711.                         tx* work = &body;
  3712.                         txInitText(work);
  3713.                         txOpenText(work);
  3714.                         if (fEdit) {
  3715.                             outlineCopy(hwnd);
  3716.                             txPaste(work);
  3717.                             txJumpFileTop(work);
  3718.                             txDeletePara(work);
  3719.                         } else if (id == IDD_ADD && textf->fClip) {
  3720.                             //2.97A 970228 テンプレート:選択中の時は内容を取り込む様にした。
  3721.                             txPrivatePush(textf);
  3722.                             txPrivatePaste(work);
  3723.                             txPrivateDeleteTop(work);
  3724.                         }
  3725.                         dialogControlID(hd,IDD_EDITBOX);
  3726.                         dialogEdit(hd,"内容(&C):",work,30,12);
  3727.                         if (fEdit) {//3.00B1 970612 慣用句の挿入:タブを挿入できるようにした
  3728.                             dialogCmdLFV(hd);
  3729.                             dialogOK(hd,14);
  3730.                             dialogCancel(hd,14);
  3731.                             dialogSpaceV(hd);
  3732.                             //
  3733.                             dialogSetHookEx(hd,"\m.dlgprocTemplateEdit");
  3734.                             dialogControlID(hd,IDD_INSERTTAB);
  3735.                             dialogCmd(hd,"タブを挿入(&T)",14);
  3736.                         }
  3737.                         if (dialogOpen(hd) && szstr != "") {
  3738.                             if (fEdit) {
  3739.                                 outlineClear(hwnd);
  3740.                             }
  3741.                             if (id == IDD_ADD) {
  3742.                                 HEADLINE hl;
  3743.                                 outlineGetHeadline(hwnd,&hl,cur+1);
  3744.                                 if (hl.npara == 0) {
  3745.                                     txJumpFileTop(text);
  3746.                                 } else {
  3747.                                     txJumpPara(text,hl.npara);
  3748.                                 }
  3749.                                 cur++;
  3750.                             } else {
  3751.                                 if (hl.npara == 0) {
  3752.                                     txJumpFileTop(text);
  3753.                                 } else {
  3754.                                     txJumpPara(text,hl.npara);
  3755.                                 }
  3756.                             }
  3757.                             txInsertLine(text,"%s%s",text->tsztitle[1],szstr);
  3758.                             txSelectAll(work);
  3759.                             txSelectCopy(work);
  3760.                             txPaste(text);
  3761.                             // 最終行が改行で終っていない場合に対応
  3762.                             txInsertReturn(text);
  3763.                             txUp(text);
  3764.                             txstr szline;
  3765.                             if (txGetLine(text,szline) == 0) {
  3766.                                 txDeletePara(text);
  3767.                             } else {
  3768.                                 txDown(text);
  3769.                             }
  3770.                         }
  3771.                         txClose(work);
  3772.                     }
  3773.                     outlineFlush(hwnd);
  3774.                     outlineSetCursel(hwnd,cur);
  3775.                     return TRUE;
  3776.                 }
  3777.                 case IDD_DEL: {
  3778.                     long cur = outlineGetCursel(hwnd);
  3779.                     outlineClear(hwnd);
  3780.                     outlineFlush(hwnd);
  3781.                     outlineSetCursel(hwnd,cur);
  3782.                     return TRUE;
  3783.                 }
  3784.             }
  3785.             break;
  3786.         }
  3787.         case CON_SELCHANGED: {
  3788.             long cur = outlineGetCursel(hwnd);
  3789.             HEADLINE hl;
  3790.             BOOL fEof = !outlineGetHeadline(hwnd,&hl,cur+1);
  3791.             EnableWindow(GetDlgItem(hwnd,IDD_ADD),!fEof);
  3792.             EnableWindow(GetDlgItem(hwnd,IDD_DEL),!fEof);
  3793.             EnableWindow(GetDlgItem(hwnd,IDD_EDIT),!fEof);
  3794.             EnableWindow(GetDlgItem(hwnd,IDD_COPY),!fEof);
  3795.             EnableWindow(GetDlgItem(hwnd,IDOK),!fEof);
  3796.             break;
  3797.         }
  3798.     }
  3799.     return FALSE;
  3800. }
  3801.  
  3802. static void templateExec(TX* text)
  3803. {
  3804. #if 1//2.92 
  3805.     txSetUndisp(text);
  3806.     {
  3807.         TX _text;
  3808.         TX* work = &_text;
  3809.         txInit(work,NULL);
  3810.         {
  3811.             txClipPaste(work,HCLIP_WIN,FALSE,0);
  3812.             txNextPara(work);
  3813.             //
  3814.             txJumpParaTop(text);
  3815.             txstr szlinetop;
  3816.             TXCHAR ch = txGetChar(text);
  3817.             if (ch == ' ' || ch == '\t' || ch == ' ') {
  3818.                 // インデント対応
  3819.                 txSelectEx(text,CLIP_CHAR);
  3820.                 txRightWordMi(text);
  3821.                 txGetWord(text,szlinetop);
  3822.                 txSelectQuit(text);
  3823.             }
  3824.             IFILE adr = TXRECORD_ERROR;
  3825.             txstr szline;
  3826.             for (BOOL fFirst = TRUE;;fFirst = FALSE) {
  3827.                 if (txIsCurEof(work)) break;
  3828.                 txGetPara(work,szline);
  3829.                 //
  3830.                 if (!fFirst) txInsert(text,szlinetop);
  3831.                 {
  3832.                     mchar* p;
  3833.                     if (p = strstr(szline,"<>")) {
  3834.                         adr = txGetAddress(text) + p - szline;
  3835.                     }
  3836.                 }
  3837.                 txInsert(text,szline);
  3838.                 txInsertReturn(text);
  3839.                 //
  3840.                 if (!txNextPara(work)) break;
  3841.             }
  3842.             if (adr != TXRECORD_ERROR) {
  3843.                 txJumpAddress(text,adr);
  3844.                 txDeleteChar(text);
  3845.                 txDeleteChar(text);
  3846.             }
  3847.         }
  3848.         txClose(work);
  3849.     }
  3850.     txSetDisp(text);
  3851. #else
  3852.     txSetUndisp(text);//1.99I ゴミが残った
  3853.     {
  3854.         BOOL f;
  3855.         txInitText(text2);
  3856.         txOpenText(text2);
  3857.         txClipPaste(text2,HCLIP_WIN,FALSE,0);
  3858.         f = txSearchEx(text2,"<>",SEARCH_CUR);
  3859.         txClose(text2);
  3860.         //
  3861.         txJumpParaTop(text);
  3862.         IFILE cbClip = txClipOp(text,TXCLIPOP_GETSIZE,HCLIP_WIN,0);
  3863.         txClipPaste(text,HCLIP_WIN,FALSE,0);
  3864.         IFILE cbDel = txGetParaTail(text) - txGetParaTop(text);
  3865.         txDeletePara(text);
  3866.         if (f) {
  3867.             if (txSearchEx(text,"<>",SEARCH_CUR)) {
  3868.                 txDeleteChar(text);
  3869.                 txDeleteChar(text);
  3870.             }
  3871.         } else {
  3872.             txRightBytes(text,cbClip - cbDel);
  3873.         }
  3874.     }
  3875.     txSetDisp(text);//1.99I 
  3876. #endif
  3877. }
  3878.  
  3879. //2.00B キー割り当て
  3880. BOOL TXCMDBASE uiInsertTemplate(TX* text)
  3881. {
  3882.     // 慣用句の挿入
  3883. //{#MS} +^T
  3884. //{#VZ} +^T
  3885. //{#MI} +^T
  3886. //{#EMACS} +^T
  3887.     TX _txtemplate;
  3888.     TX *text = &_txtemplate;
  3889.     txInitText(text);
  3890.     mchar szfilename[CCHPATHNAME];
  3891.     pathFullConfig(szfilename,"template.dic");
  3892.     txSetFileName(text,szfilename);
  3893.     txOpenText(text);
  3894.     //2.00E2 設定がなくても正常に動作するように
  3895.     strcpy(text->tsztitle[0],"..");
  3896.     strcpy(text->tsztitle[1],"...");
  3897.     strcpy(text->tsztitle[2],"");
  3898.     //2.92 
  3899.     txConvertDic(text);
  3900.     // add EOF
  3901.     txJumpFileEnd(text);
  3902.     txInsertLine(text,"%s(end)",text->tsztitle[0]);
  3903.     text->fEdit = FALSE;
  3904.     //
  3905.     HDIALOG hd = dialog("慣用句の挿入");
  3906.     DTRECT r;
  3907.     dialogGetPos(hd,&r);
  3908.     r.cx = DTCX * 40;
  3909.     r.cy = DTCY * 12;
  3910. #if 1//2.92 
  3911.     dialogAddTitle(hd,&r);
  3912. #else
  3913.     __dialogAddItem(hd,"LISTBOX",NULL,IDD_TITLELIST,&r,LBS_NOTIFY|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP);
  3914. #endif
  3915.     dialogSetPos(hd,&r);
  3916.     int x = r.x + r.cx + DTCX * 2;
  3917.     r.y += r.cy + DTCY;
  3918.     r.cx = DTCX * 40;
  3919.     r.cy = DTCY * 4;
  3920.     __dialogAddItem(hd,"LISTBOX",NULL,IDD_TITLEVIEW,&r,LBS_NOTIFY|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_CHILD|WS_VISIBLE|WS_TABSTOP);
  3921.     //
  3922.     int cx = 17;
  3923.     dialogLFV(hd);
  3924.     dialogSetPosX(hd,x);
  3925.     dialogOK(hd,cx);
  3926.     dialogCancel(hd,cx);
  3927.     dialogSpaceV(hd);
  3928.     dialogControlID(hd,IDD_ADD);
  3929.     dialogButtonCmd(hd,"追加(&A)...",NULL,cx);
  3930.     dialogControlID(hd,IDD_ADDCATEGORY);
  3931.     dialogButtonCmd(hd,"グループの追加(&B)...",NULL,cx);//2.92 
  3932.     dialogControlID(hd,IDD_EDIT);
  3933.     dialogButtonCmd(hd,"修正(&E)...",NULL,cx);
  3934.     dialogControlID(hd,IDD_DEL);
  3935.     dialogButtonCmd(hd,"削除(&D)",NULL,cx);
  3936.     //2.92 
  3937.     dialogSpaceV(hd);
  3938.     dialogControlID(hd,IDD_COPY);
  3939.     dialogButtonCmd(hd,"コピー(&C)",NULL,cx);
  3940.     dialogControlID(hd,IDD_PASTE);
  3941.     dialogButtonCmd(hd,"貼り付け(&P)",NULL,cx);
  3942.     //
  3943.     CHOOSEOUTLINE co;
  3944.     memset(&co,0,sizeof(CHOOSEOUTLINE));
  3945.     co.text = text;
  3946.     co.szhook = "\m.dlgprocTemplate";
  3947.     co.iselFirst = tmpl_isel;
  3948.     co.fNoTitleHead = TRUE;
  3949.     BOOL ret = FALSE;
  3950.     if (dialogSelectTitle(hd,&co)) {
  3951.         templateExec(textf);
  3952.         ret = TRUE;
  3953.     }
  3954.     txClose(text);
  3955.     return ret;
  3956. }
  3957.  
  3958. //##tssel
  3959.  
  3960. typedef struct {
  3961.     HCLIP hclip;
  3962.     int istack;        // マイナス値は無効を表す
  3963.     int editmode;
  3964. } TSSELPREVIEWCONTEXT;
  3965.  
  3966. BOOL dlgprocTsselPreview(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  3967. {
  3968.     switch(message) {
  3969.         case WM_INITDIALOG: {
  3970.             HDIALOG hd = dialogFromHwnd(hwnd);
  3971.             TSSELPREVIEWCONTEXT* context = (LPVOID)dialogGetCustdata(hd);
  3972.             HWND hctrl = GetDlgItem(hwnd,IDD_PREVIEW);
  3973.             {
  3974.                 TX* text = (LPVOID)SendMessage(hctrl,TXWM_GETTX,0,0);
  3975.                 txSetUndisp(text);
  3976.                 text->width = 80;
  3977.                 text->fScrollBarH = TRUE;
  3978.                 text->fScrollBarV = TRUE;
  3979.                 txSetEditmode(text,context->editmode);
  3980.                 txClipPasteEx(text,context->hclip,context->istack,0,FALSE,CLIP_CHAR);
  3981.                 txFlush(text);
  3982.                 txSetDisp(text);
  3983.             }
  3984.             break;
  3985.         }
  3986.     }
  3987.     return FALSE;
  3988. }
  3989.  
  3990. BOOL dlgprocTssel(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  3991. {
  3992.     HCLIP hclip = HCLIP_TS;
  3993.     switch(message) {
  3994.         case WM_INITDIALOG: {
  3995.             HWND hwndList = GetDlgItem(hwnd,IDD_LIST);
  3996.             int n = txClipOp(text,TXCLIPOP_GETCOUNT,hclip,0);
  3997.             if (n) {
  3998.                 TX textBody;
  3999.                 TX* text = &textBody;
  4000.                 txInitText(text);
  4001.                 txOpenText(text);
  4002.                 txstr szline;
  4003.                 for (int i = 0;i < n;i++) {
  4004.                     txDeleteText(text);
  4005.                     txClipPasteEx(text,hclip,i,0,FALSE,CLIP_CHAR);
  4006.                     txGetLine(text,szline);
  4007.                     SendMessage(hwndList,LB_ADDSTRING,0,(LPARAM)(mchar*)szline);
  4008.                 }
  4009.                 txClose(text);
  4010.             } else {
  4011.                 SendMessage(hwndList,LB_ADDSTRING,0,(LPARAM)"テキストスタックは空です");
  4012.                 EnableWindow(GetDlgItem(hwnd,IDD_INSERT),FALSE);
  4013.                 EnableWindow(GetDlgItem(hwnd,IDD_CONFIRM),FALSE);
  4014. #if 0
  4015.                 EnableWindow(GetDlgItem(hwnd,IDD_DEL),FALSE);
  4016. #endif
  4017.             }
  4018.             ListBox_SetCurSel(GetDlgItem(hwnd,IDD_LIST),0);
  4019.             break;
  4020.         }
  4021.         case WM_COMMAND: {
  4022.             HDIALOG hd = dialogFromHwnd(hwnd);
  4023.             int id = WM_COMMAND_GetId(wParam);
  4024.             int notify = WM_COMMAND_GetNotify(wParam,lParam);
  4025.             TSSELPREVIEWCONTEXT context;
  4026.             context.hclip = hclip;
  4027.             context.istack = ListBox_GetCurSel(GetDlgItem(hwnd,IDD_LIST));
  4028.             context.editmode = text->editmode;
  4029.             if (context.istack == LB_ERR) context.istack = -1;
  4030.             switch(id) {
  4031.                 case IDD_INSERT: {
  4032.                     if (context.istack >= 0) {
  4033.                         IFILE adr = txGetAddress(text);
  4034.                         txSetUndisp(text);
  4035.                         txClipPasteEx(text,hclip,context.istack,0,TRUE,CLIP_CHAR);
  4036.                         txSelect(text);
  4037.                         text->fClipMouse = TRUE;
  4038.                         txJumpAddress(text,adr);
  4039.                         txSetDisp(text);
  4040.                     }
  4041.                     return FALSE;
  4042.                 }
  4043.                 case IDD_CONFIRM: {
  4044.                     HDIALOG hd = dialog("挿入されるデータの確認");
  4045.                     dialogSetHookEx(hd,"\m.dlgprocTsselPreview");
  4046.                     dialogSetCustdata(hd,(DWORD)&context);
  4047.                     DTRECT r;
  4048.                     dialogGetPos(hd,&r);
  4049.                     r.cx = DTCX * 80;
  4050.                     r.cy = DTCY * 10;
  4051.                     __dialogAddItem(hd,TXWS_SZCLASS,"",IDD_PREVIEW,&r,TXWS_TEXT|TXWS_OPENTEXT|WS_VSCROLL|WS_BORDER|WS_CHILD|WS_VISIBLE);
  4052.                     dialogLFV(hd);
  4053.                     dialogClose(hd,10);
  4054.                     dialogOpen(hd);
  4055.                     return TRUE;
  4056.                 }
  4057.             }
  4058.             break;
  4059.         }
  4060.     }
  4061.     return FALSE;
  4062. }
  4063.  
  4064. // CM.(千葉誠)氏作"tssel"に敬意を表し、
  4065. // コマンド名を同じにさせていただきました。96.3 TY。
  4066. BOOL TXCMDBASE tssel(TX* text)
  4067. {
  4068. // テキストスタックから選んでペースト
  4069.     HDIALOG hd = dialog("テキストスタックから挿入");
  4070.     
  4071.     dialogSetHookEx(hd,"\m.dlgprocTssel");
  4072.     dialogControlID(hd,IDD_LIST);
  4073.     _dialogList(hd,NULL,60,12);
  4074.     
  4075.     int lcx = 16;
  4076.     dialogLFV(hd);
  4077.     dialogControlID(hd,IDD_INSERT);
  4078.     dialogCmdDefault(hd,"本文へ挿入",lcx);
  4079. #if 0
  4080.     dialogControlID(hd,IDD_DEL);
  4081.     dialogCmd(hd,"削除(&D)",lcx);
  4082. #endif
  4083.     dialogControlID(hd,IDD_CONFIRM);
  4084.     dialogCmd(hd,"内容確認(&C)...",lcx);
  4085.     dialogControlID(hd,IDCANCEL);
  4086.     dialogCmd(hd,"閉じる",lcx);
  4087.     
  4088.     dialogOpen(hd);
  4089.     return TRUE;
  4090. }
  4091.  
  4092. //##文字の変換
  4093.  
  4094. //2.99C 970324 文字の変換、オートコレクト ダイアログ デザイン改良
  4095. #if 1
  4096.  
  4097. #define IDD_CLEAR        100
  4098. #define IDD_KATA        110
  4099. #define IDD_HIRA        120
  4100. #define IDD_ALPHABET    130
  4101. #define IDD_NUMBER        140
  4102. #define IDD_SPACE        150
  4103. #define IDD_KIGOU        160
  4104. #define IDD_BRACE        170
  4105.  
  4106. static void CheckRadioButtonFirst(HWND hwnd,int idd)
  4107. {
  4108.     CheckRadioButton(hwnd,idd,idd+9,idd);
  4109. }
  4110.  
  4111. BOOL dlgprocConvertChar(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  4112. {
  4113.     switch(message) {
  4114.         case WM_COMMAND: {
  4115.             int id = WM_COMMAND_GetId(wParam);
  4116.             int notify = WM_COMMAND_GetNotify(wParam,lParam);
  4117.             switch(id) {
  4118.                 case IDD_CLEAR: {
  4119.                     CheckRadioButtonFirst(hwnd,IDD_KATA);
  4120.                     CheckRadioButtonFirst(hwnd,IDD_HIRA);
  4121.                     CheckRadioButtonFirst(hwnd,IDD_ALPHABET);
  4122.                     CheckRadioButtonFirst(hwnd,IDD_NUMBER);
  4123.                     CheckRadioButtonFirst(hwnd,IDD_SPACE);
  4124.                     CheckRadioButtonFirst(hwnd,IDD_KIGOU);
  4125.                     CheckDlgButton(hwnd,IDD_BRACE,FALSE);
  4126.                     return TRUE;
  4127.                 }
  4128.             }
  4129.             break;
  4130.         }
  4131.     }
  4132.     return FALSE;
  4133. }
  4134.  
  4135. BOOL TXAPI txuiConvertChar(TX* text,CHARCONVERT* cc,BOOL fAc)
  4136. {
  4137. //2.95 970128 TXAPI化
  4138.     HDIALOG hd;
  4139.     if (fAc) {
  4140.         hd = dialogbig("オートコレクト");
  4141.     } else {
  4142.         hd = dialogbig("文字の変換");
  4143.     }
  4144.     dialogSetHookEx(hd,"\m.dlgprocConvertChar");
  4145.     dialogSetContexthelp(hd,TRUE);
  4146.     
  4147.     BOOL fAutoCollect = cc->fAc;
  4148.     BOOL fJbraceToBrace = cc->fJbraceToBrace;
  4149.     
  4150.     int modeKata = cc->fJkataToKana + cc->fKanaToJkata * 2 + cc->fKanaToJhira * 3;
  4151.     int modeHira = cc->fJhiraToKana;
  4152.     int modeAlphabet = cc->fJalphabetToAnk + cc->fAlphabetToJank * 2;
  4153.     int modeNumber = cc->fJnumberToAnk + cc->fNumberToJank * 2;
  4154.     int modeSpace = cc->fJspaceToAnk + cc->fSpaceToJank * 2;
  4155.     int modeKigou = cc->fJkigouToAnk + cc->fKigouToJank * 2;
  4156.     
  4157.     dialogSetGroupRight(hd,DTCX * 65);
  4158.     if (fAc) {
  4159.         dialogGroup(hd,"オートコレクト");
  4160.             dialogControlHelp(hd,-308);
  4161.             dialogSwitch(hd,&fAutoCollect,"する(&A)","しない(&N)");
  4162.         dialogGroupEnd(hd);
  4163.     }
  4164.     dialogGroup(hd,"文字の変換");
  4165.         dialogSetH(hd);
  4166.         int lxg = 12;
  4167.         dialogCaptionDynamic(hd,"カタカナ(&K):",lxg);
  4168.         dialogControlID(hd,IDD_KATA);
  4169.         dialogRadioID(hd,&modeKata,"そのまま","半角へ","全角へ","ひらがなへ");
  4170.             dialogLF(hd);
  4171.         dialogCaptionDynamic(hd,"ひらがな(&H):",lxg);
  4172.         dialogControlID(hd,IDD_HIRA);
  4173.         dialogRadioID(hd,&modeHira,"そのまま","半角カタカナへ");
  4174.             dialogLF(hd);
  4175.         dialogCaptionDynamic(hd,"アルファベット(&L):",lxg);
  4176.         dialogControlID(hd,IDD_ALPHABET);
  4177.         dialogRadioID(hd,&modeAlphabet,"そのまま","半角へ","全角へ");
  4178.             dialogLF(hd);
  4179.         dialogCaptionDynamic(hd,"数字(&U):",lxg);
  4180.         dialogControlID(hd,IDD_NUMBER);
  4181.         dialogRadioID(hd,&modeNumber,"そのまま","半角へ","全角へ");
  4182.             dialogLF(hd);
  4183.         dialogCaptionDynamic(hd,"記号(&I):",lxg);
  4184.         dialogControlID(hd,IDD_KIGOU);
  4185.         dialogRadioID(hd,&modeKigou,"そのまま","半角へ","全角へ");
  4186.             dialogLF(hd);
  4187.         dialogCaptionDynamic(hd,"空白(&S):",lxg);
  4188.         dialogControlID(hd,IDD_SPACE);
  4189.         dialogRadioID(hd,&modeSpace,"そのまま","半角へ","全角へ");
  4190.             dialogLF(hd);
  4191.         dialogControlID(hd,IDD_BRACE);
  4192.         dialogCheck(hd,"「」を[]へ(&B)",&fJbraceToBrace);
  4193.             dialogLF(hd);
  4194.         dialogSetV(hd);
  4195.     dialogGroupEnd(hd);
  4196.     
  4197.     dialogLFV(hd);
  4198.     dialogOK(hd,12);
  4199.     dialogCancel(hd,12);
  4200.     dialogControlID(hd,IDD_CLEAR);
  4201.     dialogCmd(hd,"クリア(&Z)",12);
  4202.     
  4203.     if (dialogOpen(hd)) {
  4204.         cc->fAc = fAutoCollect;
  4205.         cc->fJbraceToBrace = fJbraceToBrace;
  4206.         cc->fJkataToKana = (modeKata == 1);
  4207.         cc->fKanaToJkata = (modeKata == 2);
  4208.         cc->fKanaToJhira = (modeKata == 3);
  4209.         cc->fJhiraToKana = modeHira;
  4210.         cc->fJalphabetToAnk = (modeAlphabet == 1);
  4211.         cc->fAlphabetToJank = (modeAlphabet == 2);
  4212.         cc->fJnumberToAnk = (modeNumber == 1);
  4213.         cc->fNumberToJank = (modeNumber == 2);
  4214.         cc->fJspaceToAnk = (modeSpace == 1);
  4215.         cc->fSpaceToJank = (modeSpace == 2);
  4216.         cc->fJkigouToAnk = (modeKigou == 1);
  4217.         cc->fKigouToJank = (modeKigou == 2);
  4218.         return TRUE;
  4219.     }
  4220.     return FALSE;
  4221. }
  4222. #else
  4223. BOOL TXAPI txuiConvertChar(TX* text,CHARCONVERT* cc,BOOL fAc)
  4224. {
  4225. //2.95 970128 TXAPI化
  4226.     HDIALOG hd;
  4227.     if (fAc) {
  4228.         hd = dialogbig("オートコレクト");
  4229.     } else {
  4230.         hd = dialogbig("文字の変換");
  4231.     }
  4232.     dialogSetContexthelp(hd,TRUE);
  4233.     BOOL fJkataToKana = cc->fJkataToKana;
  4234.     BOOL fJkanaToKana = cc->fJkanaToKana;
  4235.     BOOL fJankToAnk = cc->fJankToAnk;
  4236.     BOOL fJalphabetToAnk = cc->fJalphabetToAnk;
  4237.     BOOL fJnumberToAnk = cc->fJnumberToAnk;
  4238.     BOOL fJkigouToAnk = cc->fJkigouToAnk;
  4239.     BOOL fJspaceToAnk = cc->fJspaceToAnk;
  4240.     BOOL fKanaToJhira = cc->fKanaToJhira;
  4241.     BOOL fKanaToJkata = cc->fKanaToJkata;
  4242.     BOOL fAnkToJank = cc->fAnkToJank;
  4243.     BOOL fAlphabetToJank = cc->fAlphabetToJank;
  4244.     BOOL fNumberToJank = cc->fNumberToJank;
  4245.     BOOL fKigouToJank = cc->fKigouToJank;
  4246.     BOOL fSpaceToJank = cc->fSpaceToJank;
  4247.     BOOL fJbraceToBrace = cc->fJbraceToBrace;
  4248.     BOOL fAutoCollect = cc->fAc;
  4249.     
  4250.     dialogSetGroupRight(hd,DTCX * 40);
  4251.     if (fAc) {
  4252.         dialogGroup(hd,"オートコレクト");
  4253.             dialogControlHelp(hd,-308);
  4254.             dialogSwitch(hd,&fAutoCollect,"する(&A)","しない(&N)");
  4255.         dialogGroupEnd(hd);
  4256.     }
  4257.     dialogGroup(hd,"半角文字に変換");
  4258.         int id = 310 + fAc;
  4259.         dialogControlHelp(hd,id);
  4260.         dialogCheck(hd,"カタカナ(&K)",&fJkataToKana);
  4261.         dialogControlHelp(hd,id);
  4262.         dialogCheck(hd,"ひらがなとカタカナ(&H)",&fJkanaToKana);
  4263.         dialogControlHelp(hd,id);
  4264.         dialogCheck(hd,"アルファベット(&L)",&fJalphabetToAnk);
  4265.         dialogControlHelp(hd,id);
  4266.         dialogCheck(hd,"数字(&U)",&fJnumberToAnk);
  4267.         dialogControlHelp(hd,id);
  4268.         dialogCheck(hd,"記号(&I)",&fJkigouToAnk);
  4269.         dialogControlHelp(hd,id);
  4270.         dialogCheck(hd,"空白(&S)",&fJspaceToAnk);
  4271.         dialogControlHelp(hd,id);
  4272.         dialogCheck(hd,"「」を[]へ(&B)",&fJbraceToBrace);
  4273.     dialogGroupEnd(hd);
  4274.     dialogGroup(hd,"全角文字に変換");
  4275.         int id = 312 + fAc;
  4276.         dialogControlHelp(hd,id);
  4277.         dialogCheck(hd,"カタカナ(&1)",&fKanaToJkata);
  4278.         dialogControlHelp(hd,id);
  4279.         dialogCheck(hd,"カタカナをひらがなへ(&2)",&fKanaToJhira);
  4280.         dialogControlHelp(hd,id);
  4281.         dialogCheck(hd,"アルファベット(&3)",&fAlphabetToJank);
  4282.         dialogControlHelp(hd,id);
  4283.         dialogCheck(hd,"数字(&4)",&fNumberToJank);
  4284.         dialogControlHelp(hd,id);
  4285.         dialogCheck(hd,"記号(&5)",&fKigouToJank);
  4286.         dialogControlHelp(hd,id);
  4287.         dialogCheck(hd,"空白(&6)",&fSpaceToJank);
  4288.     dialogGroupEnd(hd);
  4289.     if (dialogOpen(hd)) {
  4290.         cc->fAc = fAutoCollect;
  4291.         cc->fJkataToKana = fJkataToKana;
  4292.         cc->fJkanaToKana = fJkanaToKana;
  4293.         cc->fJankToAnk = fJankToAnk;
  4294.         cc->fJalphabetToAnk = fJalphabetToAnk;
  4295.         cc->fJnumberToAnk = fJnumberToAnk;
  4296.         cc->fJkigouToAnk = fJkigouToAnk;
  4297.         cc->fJspaceToAnk = fJspaceToAnk;
  4298.         cc->fKanaToJhira = fKanaToJhira;
  4299.         cc->fKanaToJkata = fKanaToJkata;
  4300.         cc->fAnkToJank = fAnkToJank;
  4301.         cc->fAlphabetToJank = fAlphabetToJank;
  4302.         cc->fNumberToJank = fNumberToJank;
  4303.         cc->fKigouToJank = fKigouToJank;
  4304.         cc->fSpaceToJank = fSpaceToJank;
  4305.         cc->fJbraceToBrace = fJbraceToBrace;
  4306.         return TRUE;
  4307.     }
  4308.     return FALSE;
  4309. }
  4310. #endif
  4311.  
  4312. // 123abc## あああ漢字アアア
  4313. // 123abc## アアア漢字
  4314. // "、'、“”、‘’
  4315.  
  4316. //2.99C 970324 半角文字と全角文字の変換 改良
  4317. permanent DWORD _cc;
  4318. BOOL TXCMDBASE uiConvertChar(TX* text)
  4319. {
  4320. // 半角文字と全角文字の変換
  4321. //2.00Cで追加
  4322.     CHARCONVERT cc = *(CHARCONVERT*)&_cc;
  4323.     if (txuiConvertChar(text,&cc,FALSE)) {
  4324.         _cc = structToDWORD(cc);
  4325.         txCharConvert(text,&cc);
  4326.         return TRUE;
  4327.     }
  4328.     return FALSE;
  4329. }
  4330.  
  4331. BOOL TXCMDBASE uiAutocorrectConfig(TX* text)
  4332. {
  4333. // オートコレクトの設定を行います。
  4334. //2.00Bで追加
  4335. //2.00Cでコマンド名変更
  4336.     if (txuiConvertChar(text,&text->charconvert,TRUE)) {
  4337.         return TRUE;
  4338.     }
  4339.     return FALSE;
  4340. }
  4341.  
  4342. //##漢字コード変換
  4343. //2.00D 
  4344.  
  4345. extern "tx" BOOL kcToSJIS(tx* text,int kc);
  4346.  
  4347. BOOL TXAPI TXCMD txFromEUC(TX* text)
  4348. {
  4349. // テキストをEUCコードとみなして、Shift-JISに変換
  4350. //2.00Dで追加
  4351.     return kcToSJIS(text,KC_EUC);
  4352. }
  4353.  
  4354. BOOL TXAPI TXCMD txFromJIS(TX* text)
  4355. {
  4356. // テキストをJISコードとみなして、Shift-JISに変換
  4357. //2.00Dで追加
  4358.     return kcToSJIS(text,KC_JIS);
  4359. }
  4360.  
  4361. BOOL TXAPI TXCMDBASE txuiFromEUC(TX* text)
  4362. {
  4363. // テキストをEUCコードとみなして、Shift-JISに変換
  4364. // 変換後に保存する文字コードもEUCにするか確認ダイアログを出す
  4365. //2.99A 970321 new
  4366.     if (kcToSJIS(text,KC_EUC)) {
  4367.         int ret = question("保存時の文字コードをEUCにしますか?");
  4368.         if (ret == IDYES) {
  4369.             text->kcSave = KC_EUC;
  4370.         }
  4371.         return TRUE;
  4372.     }
  4373.     return FALSE;
  4374. }
  4375.  
  4376. BOOL TXAPI TXCMDBASE txuiFromJIS(TX* text)
  4377. {
  4378. // テキストをJISコードとみなして、Shift-JISに変換
  4379. // 変換後に保存する文字コードもJISにするか確認ダイアログを出す
  4380. //2.99A 970321 new
  4381.     if (kcToSJIS(text,KC_JIS)) {
  4382.         int ret = question("保存時の文字コードをJISにしますか?");
  4383.         if (ret == IDYES) {
  4384.             text->kcSave = KC_JIS;
  4385.         }
  4386.         return TRUE;
  4387.     }
  4388.     return FALSE;
  4389. }
  4390.  
  4391. //2.90 
  4392. BOOL txClipCopyAll(TX* text)
  4393. {
  4394. //information("%d",txGetTextSize(text));
  4395.     txClipCopy(text,0,txGetTextSize(text),HCLIP_WIN,CLIP_CHAR);
  4396.     return TRUE;
  4397. }
  4398.  
  4399. void txAdjustZenHanSpace(TX* text,BOOL fSet)
  4400. {
  4401. // fSet=TRUE : 全角文字と半角文字の間に空白を一つあけます。
  4402. // fSet=FALSE: 全角文字と半角文字の間の空白を削除します。
  4403. // 範囲選択されているときは範囲内、されていないときはテキスト全体で処理
  4404.     if (text->fClip) {
  4405.         txWalkStart(text);
  4406.     } else {
  4407.         txMarkCur(text);
  4408.         txSetUndisp(text);
  4409.         txJumpFileTop(text);
  4410.     }
  4411.     if (fSet) {
  4412.         while(1) {
  4413.             mchar* p = text->buff + text->cur;
  4414.             mchar c = *p;
  4415.             if (text->fClip && !txIsWalking(text)) break;
  4416.             if (isalnum(c)) {
  4417.                 // 次の文字が漢字なら空白を挿入
  4418.                 if (!txRight(text)) break;
  4419.                 p = text->buff + text->cur;
  4420.                 if (iskanji(*p)) {
  4421.                     txInsertChar(text,' ');
  4422.                 }
  4423.             } else if (iskanji(c)) {
  4424.                 TXCHAR ch = txGetChar(text);
  4425.                 if (strchr("。。.?・!」)…",ch)) {
  4426.                     //3.00A4 970509 英数字と全角文字の間に空白を空ける: 句読点と半角文字の間にも空白が入った
  4427.                     if (!txRight(text)) break;
  4428.                 } else {
  4429.                     // 次の文字がalnumなら空白を挿入
  4430.                     if (!txRight(text)) break;
  4431.                     p = text->buff + text->cur;
  4432.                     if (isalnum(*p)) {
  4433.                         txInsertChar(text,' ');
  4434.                     }
  4435.                 }
  4436.             } else {
  4437.                 if (!txRight(text)) break;
  4438.             }
  4439.         }
  4440.     } else {
  4441.         while(1) {
  4442.             mchar* p = text->buff + text->cur;
  4443.             mchar c = *p;
  4444.             if (text->fClip && !txIsWalking(text)) break;
  4445.             if (isalnum(c)) {
  4446.                 // 次の文字が空白+漢字なら空白を削除
  4447.                 if (!txRight(text)) break;
  4448.                 p = text->buff + text->cur;
  4449.                 if (*p == ' ' && iskanji(p[1])) {
  4450.                     txDeleteChar(text);
  4451.                 }
  4452.             } else if (iskanji(c)) {
  4453.                 // 次の文字が空白+alnumなら空白を削除
  4454.                 if (!txRight(text)) break;
  4455.                 p = text->buff + text->cur;
  4456.                 if (*p == ' ' && isalnum(p[1])) {
  4457.                     txDeleteChar(text);
  4458.                 }
  4459.             } else {
  4460.                 if (!txRight(text)) break;
  4461.             }
  4462.         }
  4463.     }
  4464.     if (text->fClip) {
  4465.         txWalkEnd(text);
  4466.     } else {
  4467.         txJumpMarkCur(text);
  4468.         txSetDisp(text);
  4469.     }
  4470. }
  4471.  
  4472. BOOL TXAPI TXCMDBASE txSetZenHanSpace(TX* text)
  4473. {
  4474. // 英数字と全角文字の間に空白を空ける
  4475. // 範囲選択されているときは範囲内、されてないときはテキスト全体が対象
  4476. //2.98 970309 new「編集|変換|...」
  4477. //3.00A2 970507 TXAPI化
  4478.     txAdjustZenHanSpace(text,TRUE);
  4479.     return TRUE;
  4480. }
  4481.  
  4482. BOOL TXAPI TXCMDBASE txClearZenHanSpace(TX* text)
  4483. {
  4484. // 英数字と全角文字の間の空白を削除
  4485. // 範囲選択されているときは範囲内、されてないときはテキスト全体が対象
  4486. //2.98 970309 new「編集|変換|...」
  4487. //3.00A2 970507 TXAPI化
  4488.     txAdjustZenHanSpace(text,FALSE);
  4489.     return TRUE;
  4490. }
  4491.  
  4492. //3.00B1 970610 罫線の変換が逆だった
  4493. static mchar _szNEC[] = "「」コカヨルスレケンイョホム、ニヌゼソ瘋オメアユ・ハヘツ艷ナ";
  4494. static mchar _szJIS[] = "─━┘└┴┷┛┸┗┻┐┌┬┯│┤┥├┼┝┿┓┰┏┳┃┨┫┠╂┣╋";
  4495.  
  4496. BOOL TXAPI TXCMD txConvertKeisenNecToJis(TX* text)
  4497. {
  4498. // ファイル内のNEC罫線をJISに変換
  4499.     txSetUndispEx(text);
  4500.     txJumpFileTop(text);
  4501.     txSetHigh(text);
  4502.     while(1) {
  4503.         if (text->buff[text->cur] == 0x86) {//3.00C 971013 84->86 「罫線の変換」バグ対処
  4504.             TXCHAR ch = txGetChar(text);
  4505.             mchar* p;
  4506.             if (p = strchr(_szNEC,ch)) {
  4507.                 txDeleteChar(text);
  4508.                 p = _szJIS + (p - _szNEC);
  4509.                 txInsertChar(text,MAKEWORD(p[1],*p));
  4510.             }
  4511.         } else {
  4512.             if (!txRight(text)) break;
  4513.         }
  4514.     }
  4515.     txJumpFileTop(text);
  4516.     txResetHigh(text);
  4517.     txSetDispEx(text);
  4518.     return TRUE;
  4519. }
  4520.  
  4521. BOOL TXAPI TXCMD txConvertKeisenJisToNec(TX* text)
  4522. {
  4523. // ファイル内のJIS罫線をNECに変換
  4524.     txSetUndispEx(text);
  4525.     txJumpFileTop(text);
  4526.     txSetHigh(text);
  4527.     while(1) {
  4528.         if (text->buff[text->cur] == 0x84) {//3.00C 971013 86->84 「罫線の変換」バグ対処
  4529.             TXCHAR ch = txGetChar(text);
  4530.             mchar* p;
  4531.             if (p = strchr(_szJIS,ch)) {
  4532.                 txDeleteChar(text);
  4533.                 p = _szNEC + (p - _szJIS);
  4534.                 txInsertChar(text,MAKEWORD(p[1],*p));
  4535.             }
  4536.         } else {
  4537.             if (!txRight(text)) break;
  4538.         }
  4539.     }
  4540.     txJumpFileTop(text);
  4541.     txResetHigh(text);
  4542.     txSetDispEx(text);
  4543.     return TRUE;
  4544. }
  4545.  
  4546. permanent int modeConvertKeisen;
  4547. BOOL TXCMDBASE uiConvertKeisen(TX* text)
  4548. {
  4549. // 罫線の変換
  4550. //2.99D 970329 new
  4551.     HDIALOG hd = dialog("罫線の変換");
  4552.     
  4553.     dialogControlRadioV(hd);
  4554.     dialogRadioID(hd,&modeConvertKeisen,
  4555.         "JIS罫線をNEC罫線に変換(&N)",
  4556.         "NEC罫線をJIS罫線に変換(&J)"
  4557.     );
  4558.     
  4559.     if (dialogOpen(hd)) {
  4560.         switch(modeConvertKeisen) {
  4561.             case 0:return txConvertKeisenJisToNec(text);
  4562.             case 1:return txConvertKeisenNecToJis(text);
  4563.         }
  4564.     }
  4565.     return FALSE;
  4566. }
  4567.  
  4568.