home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1998 September / VPR9809B.ISO / APUPDATE / VC / Tx300d / TX300D.LZH / STDLIB.C < prev    next >
C/C++ Source or Header  |  1997-06-15  |  94KB  |  3,879 lines

  1. // WZ EDITOR 標準機能 TX-Cライブラリ関数群
  2. // Copyright 1995-96 TY
  3. // 従来の小物TLLをまとめました。
  4.  
  5. #ifdef __TXC__
  6.     #include <windows.h>
  7.     #pragma HEADER+
  8. #else
  9.     #include "tx.h"
  10.     #include <memory.h>
  11.     #include <string.h>
  12.     #include <stdio.h>
  13.     #include <stdlib.h>
  14.     #include <ctype.h>
  15. #endif
  16. #include "_filer.h"
  17. #include <windowsx.h>
  18.  
  19. #ifndef __NOTX__
  20.  
  21. //##text.c
  22. //{###表示}
  23.  
  24. //1.97 static変数を止めtext->addressUndisp,lxUndispへ
  25.  
  26. void TXAPIBASE txSetUndispEx(tx *text)
  27. {
  28. // カーソル位置・画面上のカーソルy座標を保存する、txSetUndisp
  29.     txSetUndisp(text);
  30. }
  31.  
  32. BOOL TXAPIBASE txSetDispEx(tx *text)
  33. {
  34. // カーソル位置・画面上のカーソルy座標を保存する、txSetDisp
  35. // 全表示したかどうか返す
  36.     UNDISPCONTEXT* context = txGetUndispContextPre(text);
  37.     if (context) {
  38.         txJumpAddress(text,context->address);
  39.         txSetLy(text,context->ly);
  40.     }
  41.     return txSetDisp(text);
  42. }
  43.  
  44. void TXAPIBASE txSetUndispExSilent(tx *text)
  45. {
  46. // マウスカーソルの形状を変更しないtxSetUndispEx
  47. // txSetUndispExSilentしたら必ずtxSetDispExSilentを実行してください。
  48. //2.99 970318 new
  49.     text->fNoCursor++;
  50.     txSetUndispEx(text);
  51. }
  52.  
  53. BOOL TXAPIBASE txSetDispExSilent(tx *text)
  54. {
  55. // マウスカーソルの形状を変更しないtxSetDispEx
  56. // 全表示したかどうか返す
  57. //2.99 970318 new
  58.     BOOL ret = txSetDispEx(text);
  59.     text->fNoCursor--;
  60.     return ret;
  61. }
  62.  
  63. void TXAPIBASE txSetUndispSilent(TX* text)
  64. {
  65. // マウスカーソルの形状を変更しないtxSetUndisp
  66. // txSetUndispSilentしたら必ずtxSetDispSilentを実行してください。
  67. //2.99 970314 new
  68.     text->fNoCursor++;
  69.     txSetUndisp(text);
  70. }
  71.  
  72. BOOL TXAPIBASE txSetDispSilent(TX* text)
  73. {
  74. // マウスカーソルの形状を変更しないtxSetDisp
  75. // 全表示したかどうか返す
  76. //2.99 970314 new
  77.     BOOL ret = txSetDisp(text);
  78.     text->fNoCursor--;
  79.     return ret;
  80. }
  81.  
  82. BOOL TXAPI txSetDispExJump(tx *text,BOOL fJump)
  83. {
  84. // txSetDispExと同じだが、fJumpが真のときだけカーソル位置を戻す
  85. // y座標は常に戻す
  86.     UNDISPCONTEXT* context = txGetUndispContextPre(text);
  87.     if (context) {
  88.         if (fJump) txJumpAddress(text,context->address);
  89.         txSetLy(text,context->ly);
  90.     }
  91.     return txSetDisp(text);
  92. }
  93.  
  94.  
  95. void TXAPI txSetUndispEdit(tx *text)
  96. {
  97. // textが編集されてもカーソル位置が変わりにくいtxSetUndisp
  98. // 無事カーソル位置をコンテキストに保存できたか返す
  99. // テキストの論理行数が変わらないときに使えます。
  100. //1.97で追加
  101.     txSetUndisp(text);
  102. }
  103.  
  104. BOOL TXAPI txSetDispEdit(tx *text)
  105. {
  106. // textが編集されてもカーソル位置が変わりにくいtxSetDisp
  107. // 全表示したかどうか返す
  108. //1.97で追加
  109.     UNDISPCONTEXT* context = txGetUndispContextPre(text);
  110.     if (context) {
  111.         txJumpPara(text,context->npara);
  112.         txJumpParaIch(text,context->ich);
  113.         txSetLy(text,context->ly);
  114.     }
  115.     return txSetDisp(text);
  116. }
  117.  
  118. void TXAPI txFlushUI(TX* text)
  119. {
  120. // キー、メニュー、ツールバーの設定をフラッシュする
  121. //2.00E4で追加
  122.     // menu
  123.     SendMessage(text->hwndbase,WM_TXFLUSHMENU,0,0);
  124.     // key
  125.     if (txGetViewmode(text)) {
  126.         //1.99K 
  127.         // viewmodeではキーは変えない
  128.     } else if (text->fNoFlushKey) {
  129.         //2.00E 
  130.     } else {
  131.         text->share->fKeyInited = FALSE;// shareのキャッシングを無効化する
  132.         txKeyLoad(text);
  133.     }
  134.     // toolbar
  135. #if 1//2.96A 970214 ツールバーはフレームウィンドウの設定に左右される
  136.     txFlushToolbar(txGetFrame(text));
  137. #else
  138.     txFlushToolbar(text);
  139. #endif
  140. }
  141.  
  142. //{###情報取得}
  143.  
  144. #ifdef __TXC__
  145.  
  146. int TXAPIBASE TXHIGH txGetParaRear(TX* text,txstr szbuff)
  147. {
  148. // カーソル位置から段落の終わりまでの内容をszbuffに取得
  149. // 表示行が、改行・EOFで終わる場合、その手前までの文字列を取得
  150. //{#RET}取得したバイト数を返す
  151. //3.00A2 970505 new
  152.     return txOp(text,TXOP_GETPARAREAREX,(mchar*)szbuff,cchtxstr(szbuff));
  153. }
  154.  
  155. int TXAPIBASE TXHIGH txGetParaFront(TX* text,txstr szbuff)
  156. {
  157. // 段落先頭からカーソル位置の手前までの内容をszbuffに入れる
  158. // szbuffに取得した文字列のバイト数を返す
  159. // szbuffのサイズが足りない時は、szbuffに収まる分の内容を入れる。
  160. // この場合次の様に、カーソル位置の手前の内容をszbuffに入れる。
  161. //   abcdefghijklmnopqrstuvwxyz
  162. //                   ^カーソル
  163. //   szbuffのサイズ=4 -> szbuff="nop"
  164. //   szbuffのサイズ=8 -> szbuff="jklmnop"
  165. //3.00A2 970505 new
  166.     return txOp(text,TXOP_GETPARAFRONTEX,(mchar*)szbuff,cchtxstr(szbuff));
  167. }
  168.  
  169. int TXAPI TXHIGH txGetCharType(TX* text,mchar *p)
  170. {
  171. // pが示す文字のタイプを返す
  172. // text->fCurWesternが真なら欧文動作する
  173. //  CT_SPACE    (0x00-0x20),全角スペース(0x8140)
  174. //  CT_SYMBOL   '$','_'を除く英記号
  175. //              全角記号(0x8152-0x815Bを除く)
  176. //  CT_KATA     半角カタカナ
  177. //  CT_HIRA     全角ひらがな
  178. //  CT_KANJI    上記以外の全角文字
  179. //  CT_CHAR     上記以外の半角文字
  180. //  CT_LF
  181. //  CT_EOF
  182. //3.00B1 970522 new
  183.     return txOp(text,TXOP_GETCHARTYPE,p,0);
  184. }
  185.  
  186. #endif
  187.  
  188. TXCHAR TXAPIBASE TXHIGH txGetCharPrev(TX* text)
  189. {
  190. // カーソル位置の1文字前の文字コードを返す
  191. // 不明な場合は0を返す
  192. //2.99C 970325 new
  193.     if (text->cur0) {
  194.         mchar* p = text->buff + text->cur0;
  195. //information("%d",txIsCharTop(text,text->cur0 - 1));
  196.         if (text->cur0 == 1) {
  197.             return p[-1];
  198.         }
  199.         if (
  200.             p[-1] == CHAR_LF &&
  201.             p[-2] == CHAR_CR
  202.         ) {
  203.             return CHAR_CRLF;
  204.         } else if (txIsCharTop(text,text->cur0 - 1)) {
  205.             return p[-1];
  206.         } else {
  207.             return MAKEWORD(p[-1],p[-2]);
  208.         }
  209.     }
  210.     return 0;
  211. }
  212.  
  213. int TXAPI pointsFromDisplayPixel(int pixel)
  214. {
  215. // ディスプレイピクセル単位をポイント数に変換
  216. //2.99 970316 new
  217.     HDC hic = CreateIC("display",NULL,NULL,NULL);
  218.     int ret = pixel;
  219.     if (hic) {
  220.         long logPixelsX = GetDeviceCaps(hic,LOGPIXELSX);
  221.         ret = (pixel * 72L) / logPixelsX;
  222.         DeleteDC(hic);
  223.     }
  224.     return ret;
  225. }
  226.  
  227. int TXAPI pointsToDisplayPixel(int points)
  228. {
  229. // ポイント数をディスプレイピクセル単位に変換
  230. //2.99B 970322 new
  231.     HDC hic = CreateIC("display",NULL,NULL,NULL);
  232.     int ret = points;
  233.     if (hic) {
  234.         long logPixelsX = GetDeviceCaps(hic,LOGPIXELSX);
  235.         ret = (points * logPixelsX) / 72L;
  236.         DeleteDC(hic);
  237.     }
  238.     return ret;
  239. }
  240.  
  241. #ifdef __TXC__
  242.  
  243. //{###検索・置換}
  244.  
  245. int TXAPI TXHIGH txSearch(tx *text,mchar *find)
  246. {
  247.     // findをカーソル位置の次から検索
  248.     // このAPIは旧バージョンとの互換性のために存在しています。
  249.     // 新しいマクロではtxSearchExを使って下さい。
  250.     // 検索ヒストリは変更しません
  251.     // 検索オプションはtext->searchmodeを参照します
  252.     // text->searchmodeは「検索|検索」を実行すると変化するので注意してください
  253.     //{#RET}見つかればカーソルを移動し0以外の値、
  254.     // 見つからなければ0を返す
  255.     return txSearchEx(text,find,text->searchmode);
  256. }
  257.  
  258. int TXAPI TXHIGH txSearchPrev(tx *text,mchar *find)
  259. {
  260.     // findをカーソル位置からテキスト先頭まで検索
  261.     // このAPIは旧バージョンとの互換性のために存在しています。
  262.     // 新しいマクロではtxSearchExを使って下さい。
  263.     // ※txSearchContinuePrevには影響しません。
  264.     // 検索オプションはtext->searchmodeを参照します
  265.     // text->searchmodeは「検索|検索」を実行すると変化するので注意してください
  266.     //{#RET}見つかればカーソルを移動し0以外の値、
  267.     // 見つからなければ0を返す
  268.     return txSearchEx(text,find,text->searchmode|SEARCH_PREV);
  269. }
  270.  
  271. //{###ファイル}
  272.  
  273. BOOL TXAPI TXHIGH txSwap1(tx *text)
  274. {
  275. // 後方をloadする必要があればloadする。loadしたかどうかを返す。
  276. //2.99D 970329 new
  277.     return txOp(text,TXOP_TXSWAP1,0,0);
  278. }
  279.  
  280. BOOL TXAPI TXHIGH txSwap2(tx *text)
  281. {
  282. // 前方をloadする必要があればloadする。loadしたかどうかを返す。
  283. //2.99D 970329 new
  284.     return txOp(text,TXOP_TXSWAP2,0,0);
  285. }
  286.  
  287. //{###情報取得}
  288.  
  289. int TXAPI systemfontGetCx(void)
  290. {
  291. // システムフォントの平均幅をディスプレイピクセル単位で返す
  292. //2.99 970316 new
  293.     TEXTMETRIC tm;
  294.     {
  295.         HDC hic = CreateIC("display",NULL,NULL,NULL);
  296.         HFONT hfont0 = SelectObject(hic,GetStockObject(GetSystemFontNo()));
  297.         GetTextMetrics(hic,&tm);
  298.         SelectObject(hic,hfont0);
  299.         DeleteDC(hic);
  300.     }
  301.     return tm.tmAveCharWidth;
  302. }
  303.  
  304. int TXAPI systemfontGetCy(void)
  305. {
  306. // システムフォントの高さをディスプレイピクセル単位で返す
  307. //2.99 970316 new
  308.     TEXTMETRIC tm;
  309.     {
  310.         HDC hic = CreateIC("display",NULL,NULL,NULL);
  311.         HFONT hfont0 = SelectObject(hic,GetStockObject(GetSystemFontNo()));
  312.         GetTextMetrics(hic,&tm);
  313.         SelectObject(hic,hfont0);
  314.         DeleteDC(hic);
  315.     }
  316.     return tm.tmHeight;
  317. }
  318.  
  319. BOOL TXAPI pathGetExtGroup(mchar* szext,mchar szGroup[CCHWORD])
  320. {
  321. // 拡張子szextの属する設定名をszGroupに返す
  322. //2.99 970318 new
  323.     return txOp(text1,TXOP_PATHGETEXTGROUP,(LPARAM)szext,(LPARAM)szGroup);
  324. }
  325.  
  326. //## undo clear
  327.  
  328. BOOL TXAPI txUndoClear(TX* text)
  329. {
  330. //2.99 970316 new
  331.     return txOp(text,TXOP_UNDOCLEAR,0,0);
  332. }
  333.  
  334. //## plugatr API
  335.  
  336. LPVOID TXAPI plugatrNewEx(TX* text,int modePlug,UINT cbEx)
  337. {
  338.     return (LPVOID)txOp(text,TXOP_PLUG_NEWEX,modePlug,cbEx);
  339. }
  340.  
  341. LPVOID TXAPI plugatrNew(TX* text,int modePlug)
  342. {
  343.     return (LPVOID)txOp(text,TXOP_PLUG_NEW,modePlug,0);
  344. }
  345.  
  346. void TXAPI plugatrDelete(TX* text,TYP typ)
  347. {
  348.     txOp(text,TXOP_PLUG_DELETE,typ,0);
  349. }
  350.  
  351. TYP TXAPI plugatrGetTyp(TX* text,LPVOID plugatr)
  352. {
  353.     return (TYP)txOp(text,TXOP_PLUG_GETTYP,plugatr,0);
  354. }
  355.  
  356. LPVOID TXAPI plugatrRead(TX* text,TYP typ)
  357. {
  358.     return (LPVOID)txOp(text,TXOP_PLUG_READ,typ,0);
  359. }
  360.  
  361. int TXAPI plugatrGetModePlug(TX* text,TYP typ)
  362. {
  363.     return (int)txOp(text,TXOP_PLUG_GETMODEPLUG,typ,0);
  364. }
  365.  
  366. UINT TXAPI plugatrGetSize(LPVOID plug)
  367. {
  368.     return (UINT)txOp(text,TXOP_PLUG_GETSIZE,plug,0);
  369. }
  370.  
  371. //## plugatr uty
  372.  
  373. void TXAPI txFlushTableAll(TX* text)
  374. {
  375. // すべての表をフラッシュ
  376. //2.99C 970323 new
  377.     txOp(text,TXOP_TABLEFLUSHALL,0,0);
  378. }
  379.  
  380. BOOL TXAPI txFlushTable(TX* text)
  381. {
  382. // カーソル行の表や桁揃えの幅をフラッシュして表示
  383. // フラッシュしたかどうか返す
  384. //2.99C 970323 WZ.EXE -> macro
  385. //1.90 new
  386.     return txOp(text,TXOP_PLUGTAB_FLUSHCUR,0,0);
  387. }
  388.  
  389. int TXAPI txGetCurPlugmode(TX* text)
  390. {
  391. //2.97A 970301 new
  392.     if (text->editmode == 0) {//2.99C 970324 
  393.         return 0;
  394.     } else {
  395.         CHARATR charatr;
  396.         charatrRead(text,txGetAddress(text),&charatr);
  397.         if (charatr.fLink) {
  398.             return plugatrGetModePlug(text,charatrGetPlug(charatr));
  399.         }
  400.         return 0;
  401.     }
  402. }
  403.  
  404. LPVOID TXAPI txGetCurPlug(TX* text)
  405. {
  406. //2.97A 970301 new
  407.     if (text->editmode == 0) {//2.99C 970324 
  408.         return NULL;
  409.     } else {
  410.         CHARATR charatr;
  411.         charatrRead(text,txGetAddress(text),&charatr);
  412.         if (charatr.fLink) {
  413.             return plugatrRead(text,charatrGetPlug(charatr));
  414.         }
  415.         return NULL;
  416.     }
  417. }
  418.  
  419. PLUGTAB* TXAPI txIsCurParaIncludeTable(TX* text)
  420. {
  421. //2.97A 970301 new
  422.     return txOp(text,TXOP_PLUGTAB_CURPARA,0,0);
  423. }
  424.  
  425. #endif
  426.  
  427. BOOL TXAPI txInsertPlug(TX* text,LPVOID plug)
  428. {
  429. //2.97A 970301 new
  430.     TYP typ = plugatrGetTyp(text,plug);
  431.     CHARATR_LINK charatr;
  432.     structClear(charatr);
  433.     charatr.fLink = TRUE;
  434.     charatr.ibitmap = typ;
  435.     txCurInsertChar(text,CHAR_PLUG);
  436.     charatrWrite(text,txGetAddress(text),(LPVOID)&charatr);
  437.     txInsert(text,"");//2.97A 970303 flush CHAR_PLUG
  438.     txRight(text);
  439.     return TRUE;
  440. }
  441.  
  442. int TXAPI txGetCurPlugTag(TX* text)
  443. {
  444. //2.97A 970301 new
  445.     PLUGHTMLTAG *plug = txGetCurPlug(text);
  446.     if (plug && plug->head.modePlug == PLUG_HTML_TAG) {
  447.         return plug->tag;
  448.     }
  449.     return 0;
  450. }
  451.  
  452. TXBASE_CONTEXT* TXAPI hwndbaseGetContext(HWND hwndbase)
  453. {
  454. //2.93 
  455. // 別プロセスのWZのhwndbaseのTXBASE_CONTEXTにはアクセスできないことに注意!
  456.     return (LPVOID)GetWindowLong(hwndbase,0);
  457. }
  458.  
  459. IFILE TXAPI txGetLineTop(tx *text)
  460. {
  461. // 表示行の行頭のテキストアドレスを返す。
  462. //2.90で追加
  463.     if (text->fHigh) return text->temp1 + text->cur0;//1.99D 
  464.     return text->temp1 + text->cury;
  465. }
  466.  
  467. IFILE TXAPI txGetLineTail(tx *text)
  468. {
  469. // 次の表示行頭のテキストアドレスを返す。
  470. //2.90で追加
  471.     if (text->fHigh) return text->temp1 + text->cur0;//1.99D 
  472.     {
  473.         IBUFF off = text->cury + text->curysize + (text->cur - text->cur0);
  474.         if (off == text->sizebuff && !txIsSwap1(text)) {//EOF
  475.             return text->temp1 + text->cury + text->curysize - 1;
  476.         }
  477.         return text->temp1 + text->cury + text->curysize;
  478.     }
  479. }
  480.  
  481. BOOL TXAPI articleMatch(PARAFORM_ARTICLE* article1,PARAFORM_ARTICLE* article2)
  482. {
  483. //2.90 
  484.     if (article1->fArticleNum && article2->fArticleNum) {
  485.         mchar* p1 = article1->szArticle;
  486.         mchar* p2 = article2->szArticle;
  487.         BOOL ret = TRUE;
  488.         while(1) {
  489.             if (isdigit(*p1)) {
  490.                 p1++;
  491.                 while(isdigit(*p1)) p1++;
  492.             }
  493.             if (isdigit(*p2)) {
  494.                 p2++;
  495.                 while(isdigit(*p2)) p2++;
  496.             }
  497.             if (*p1 == *p2) {
  498.                 if (*p1 == 0) break;
  499.                 p1++;
  500.                 p2++;
  501.             } else {
  502.                 ret = FALSE;
  503.                 break;
  504.             }
  505.         }
  506.         return ret;
  507.     } else {
  508.         if (article1->lchArticle != article2->lchArticle) return FALSE;
  509.         return !strcmp(article1->szArticle,article2->szArticle);
  510.     }
  511. }
  512.  
  513. BOOL TXAPIBASE txIsLineParaTop(tx *text)
  514. {
  515. // カレント表示行が、論理行の先頭行か返す
  516.     mchar c;
  517.     if (text->fHigh) return FALSE;
  518.     if (text->cury == 0) return TRUE;
  519.     c = text->buff[text->cury-1];
  520.     if (c == 0x0A || c == 0x1A || c == 0x0C) return TRUE;
  521.     return FALSE;
  522. }
  523.  
  524. BOOL TXAPIBASE txIsCurParaTop(tx *text)
  525. {
  526. // カーソル位置が、論理行の先頭行か返す
  527.     mchar c;
  528.     if (text->cur0 == 0) return TRUE;
  529.     c = text->buff[text->cur0-1];
  530.     if (c == 0x0A || c == 0x1A || c == 0x0C) return TRUE;
  531.     return FALSE;
  532. }
  533.  
  534. BOOL TXAPIBASE txIsCurLineTop(tx *text)
  535. {
  536. // カーソル位置が、表示行の行頭か返す
  537. //2.90で追加
  538.     mchar c;
  539.     return (text->cur0 == text->cury);
  540. }
  541.  
  542. NLINE TXAPI txGetNlineModal(tx *text)
  543. {
  544. // テキストのカーソル行の行番号を返します
  545. // text->fLineDが真なら表示行番号、偽なら論理行番号を返します
  546. //1.00Cで追加
  547.     if (text->fLineD) {
  548.         return text->nline;
  549.     } else {
  550.         return text->npara;
  551.     }
  552. }
  553.  
  554. #ifdef __TXC__
  555. TX* txFromHwndbase(HWND hwnd)
  556. {
  557.     return (TX*)txOp(NULL,TXOP_TXFROMHWNDBASE,hwnd,NULL);
  558. }
  559. #endif
  560.  
  561. TX* TXAPI txGetFrame(TX* text)
  562. {
  563. //2.93 
  564. //2.96 970205 改良
  565. // textがダイアログ中のコントロールの場合、従来はtext1を返したが
  566. // 正しく、対象の(textの親ウィンドウなどの)textFrameを返す様にした。
  567.     if (text->fFrame) return text;
  568.     if (text->text2 && text->text2->fFrame) return text->text2;//2.93 
  569. #if 1//2.96 970205 
  570.     return txFromHwndbase(text->hwndbase);
  571. #else
  572.     return text1;
  573. #endif
  574. }
  575.  
  576. TX* TXAPI txGetFrameNow(void)
  577. {
  578. // 現在フォーカスのあるtextの、大元のtextを返す
  579. // 高速オープンONのときは、従来のtext1の代わりに使用する
  580. //2.99C 970324 new
  581.     return txGetFrame(textf);
  582. }
  583.  
  584. BOOL TXAPI autosaveGetFileName(tx* text,mchar szfilename[CCHPATHNAME])
  585. {
  586. // オートセーブ先のファイル名を返します。
  587. // オートセーブするかどうかの最低限のチェックも行います。
  588. // 正常にファイル名をセットしたか返します。
  589.     if (text->fAutoSave && text->fFrame) {    //2.95 970131 text==text1 -> text->fFrame
  590.         if (text->autosaveDevice == AUTOSAVE_NOTFD) {
  591.             if (pathGetDriveType(text->szfilename) == DRIVE_REMOVABLE) return FALSE;
  592.         }
  593.         if (
  594.             text->szfilename[0] &&
  595.             !text->ftxuiSaveNamed    //2.00E 無題ファイルを保存すると$~nonameが削除されなかった
  596.         ) {
  597.             if (text->autosaveMode == AUTOSAVE_OVERWRITE) {
  598.                 strcpy(szfilename,text->szfilename);
  599.             } else {
  600.                 mchar* pfilename = pathGetFileName(text->szfilename);
  601.                 mchar* dst;
  602.                 strcpy(szfilename,text->szfilename);
  603.                 dst = pathGetFileName(szfilename);
  604.                 *dst++ = '$';
  605.                 *dst++ = '~';
  606.                 #ifdef __FLAT__
  607.                 strcpy(dst,pfilename);
  608.                 #else
  609.                 {
  610.                     mchar* pext = pathGetExt(text->szfilename);
  611.                     strcpylenmax(dst,pfilename,pext - pfilename,7);
  612.                     dst += strlen(dst);
  613.                     strcpy(dst,pext);
  614.                 }
  615.                 #endif
  616.             }
  617.         } else {
  618. #if 1//2.98 970307 "$~noname"があちこちにできたので、WZフォルダに作るようにした
  619.         // ネットワーク版の場合はユーザフォルダに作る。
  620.         // ネットワーク環境では、"$~noname"があちこちにできるのは、セキュリティ上よくない。
  621.     #if 1//2.99C 970326 無題ファイルのオートセーブがおかしかった
  622.             pathFullConfig(szfilename,"$~noname");
  623.     #else
  624.             mchar szfilename[CCHPATHNAME];
  625.             pathFullConfig(szfilename,"$~noname");
  626.     #endif
  627. #else
  628.             driveGetCurDir(0,szfilename);
  629.             pathSetDir(szfilename);
  630.             pathSetFileName(szfilename,"$~noname");
  631. #endif
  632.         }
  633. //information(szfilename);
  634.         return TRUE;
  635.     } else {
  636.         return FALSE;
  637.     }
  638. }
  639.  
  640. IFILE TXAPI txGetAddressSelectTop(tx *text)
  641. {
  642. // 範囲の先頭アドレスを取得
  643. // 選択中でないときはカーソル位置のアドレスを返す
  644.     if (text->fClip && txFlushSelectNow(text)) {
  645.         if (text->cliptopnow <= text->clipendnow) {
  646.             return text->cliptopnow;
  647.         } else {
  648.             return text->clipendnow;
  649.         }
  650.     } else {
  651.         return txGetAddress(text);
  652.     }
  653. }
  654.  
  655. IFILE TXAPI txGetAddressSelectEnd(tx *text)
  656. {
  657. // 範囲の末尾アドレスを取得
  658. // 選択中でないときはカーソル位置のアドレスを返す
  659.     if (text->fClip && txFlushSelectNow(text)) {
  660.         if (text->clipendnow >= text->cliptopnow) {
  661.             return text->clipendnow;
  662.         } else {
  663.             return text->cliptopnow;
  664.         }
  665.     } else {
  666.         return txGetAddress(text);
  667.     }
  668. }
  669.  
  670. BOOL TXAPI txIsSelectPrev(TX* text)
  671. {
  672. // カーソル位置が範囲選択開始位置より手前にあるときTRUEを返す
  673. //2.97A 970302 new
  674.     if (text->fClip && txFlushSelectNow(text)) {
  675.         if (text->clipendnow < text->cliptopnow) return TRUE;
  676.     }
  677.     return FALSE;
  678. }
  679.  
  680. IFILE TXAPI txGetAddressCurscreen(TX* text)
  681. {
  682. // スクリーントップに表示されている表示行の頭のアドレスを返す
  683. //2.97A 970302 new
  684.     return txOp(text,TXOP_GETADDRESSCURSCREEN,0,0);
  685. }
  686.  
  687. BOOL TXAPI txSetLyCurscreen(TX* text,IFILE adrCurscreen)
  688. {
  689. // 現在のカーソル位置を変えずに、スクリーントップがadrCurscreenになるように
  690. // lyを設定する。lyが設定できない場合は、ly=0としてFALSEを返す。
  691.     return txOp(text,TXOP_SETLYCURSCREEN,adrCurscreen,0);
  692. }
  693.  
  694. int TXAPI txGetModeClipboard(TX* text)
  695. {
  696. // クリップボードのモードを返す
  697. //2.00Eで追加
  698.     if (text->fBinedit) {
  699.         return CLIPBOARD_TS;
  700.     } else {
  701.         return text->modeClipboard;
  702.     }
  703. }
  704.  
  705. mchar* TXAPI txGetTitleFilename(TX* text)
  706. {
  707. // タイトルバーに表示するファイル名を返す
  708. //2.00Eで追加
  709.     if (text->szfilename[0]) {
  710.         if (text->fDispPathFull) {
  711.             return text->szfilename;
  712.         } else {
  713.             return pathGetFileName(text->szfilename);
  714.         }
  715.     } else if (text->mail) {//2.90 
  716.         return text->mail->szCaption;
  717.     } else {
  718.         return "(無題)";
  719.     }
  720. }
  721.  
  722. //{###ファイル}
  723.  
  724. TX* TXAPI txAllocText(DWORD mode)
  725. {
  726. // text構造体を確保し、txInitText,txSetFileName(text,NULL)して返す
  727. // modeにはTXALLOC_XXXが指定できる。
  728. //2.99 970316 new
  729.     BOOL fUndo = ((mode & TXALLOC_UNDO) != 0);
  730.     UINT size = sizeof(TX) + fUndo * 2 * sizeof(TX);
  731.     TX* text = malloc(size);
  732.     TX* p = text + 1;
  733.     if (text) {
  734.         txInitText(text);
  735.         text->fTxAllocText = TRUE;
  736.         txSetFileName(text,NULL);// 標準設定を読込む
  737.         if (fUndo) {//2.90 
  738.             text->fEnableUndo = TRUE;
  739.             text->fUndoAlloced = TRUE;//2.99E 970403 
  740.             text->ttextUndo = (LPVOID)p;
  741.             txInitText(&text[1]);
  742.             txInitText(&text[2]);
  743.             p += sizeof(TX) * 2;
  744.         }
  745.         return text;
  746.     }
  747.     return NULL;
  748. }
  749.  
  750. void TXAPI txFreeText(TX* text)
  751. {
  752. // txAllocTextで得たtextをtxCloseして解放する
  753. //2.99 970316 new
  754.     if (text && text->fTxAllocText) {
  755.         text->fTxAllocText = FALSE;
  756.         txClose(text);
  757.         free(text);
  758.     }
  759. }
  760.  
  761. TX* TXAPIBASE textopen(mchar* szfilename)
  762. {
  763. // szfilenameのファイルをオープンする。
  764. // ファイルの内容を読み込んだtextを返す
  765. // 失敗したらNULLを返す
  766. // テキストを使い終わったら必ずtextcloseしてtextを閉じて下さい。
  767. // szfilenameにはNULLも指定できます。NULLを指定すると空の新規テキストを開きます。
  768. //2.99B 970322 new
  769.     TX* text = txAllocText(0);
  770.     if (text) {
  771.         txSetFileName(text,szfilename);
  772.         if (txOpenText(text)) {
  773.             return text;
  774.         }
  775.         txFreeText(text);
  776.     }
  777.     return NULL;
  778. }
  779.  
  780. void TXAPIBASE textclose(TX* text)
  781. {
  782. // textopenで開いたテキストを閉じる
  783. // textにはNULLも指定できます
  784. //2.99B 970322 new
  785.     txFreeText(text);
  786. }
  787.  
  788. BOOL TXAPI forksw(mchar* szfilename,mchar* sw)
  789. {
  790. // forkと同じですが、起動オプションをswで指定できます。
  791. //2.94 970123 新規API
  792.     TXFORKRESULT result;
  793.     if (forkex(szfilename,sw,0,&result)) return TRUE;
  794.     if (result.text) return TRUE;
  795.     return FALSE;
  796. }
  797.  
  798. BOOL TXAPI fork(mchar* szfilename)
  799. {
  800. // szfilenameのファイルをオープンします。
  801. // 返り値が「真」なら、szfilenameの窓がアクティブになり、text変数は、s
  802. // zfilenameのテキストを示します。
  803. // 返り値が「偽」なら、オープン失敗です。
  804. // [詳細]
  805. // szfilenameにスイッチ指定を含むことはできません。
  806. // 空白を含むファイル名もszfilenameにそのまま指定できます。
  807. // szfilenameは""で括ってあっても構いません。
  808. // szfilenameがNULLまたは""なら、新規ファイルを開きます。
  809. // szfilenameが既にオープンされていたら、その窓をアクティブにします。
  810. // 高速オープンのロジックを使って、必ず、このAPIを呼び出したWZプロセス内で
  811. // szfilenameをオープンします。
  812. // 高速オープン未対応のTXEからこのAPIを呼び出すと必ず失敗します。
  813. // ★WZ3.00,3.00Aにおける注意
  814. // オープンが成功した場合、textにアクセスするにはsleep(1000)のよう
  815. // に一定時間待つ必要があります。待ち時間はマシンに依存します。 
  816. // この制限は将来解除したいと考えています。
  817. // ★WZ3.00Bからsleepで待つ必要がなくなりました。
  818. //2.94 970123 新規API
  819.     return forksw(szfilename,NULL);
  820. }
  821.  
  822. BOOL TXAPI forkstd(mchar* szfilename,mchar* sw)
  823. {
  824. // forkswと同じですが、高速オープンできない場合、
  825. // すなわち、WZを起動する場合または別プロセスのWZで高速オープンする場合も、
  826. // ファイルのオープンを行います。
  827. //2.94 970123 新規API
  828.     return forkex(szfilename,sw,TXFORK_FORKWZ_ENABLE,NULL);
  829. }
  830.  
  831. BOOL TXAPIBASE txOpenFork(TX* text,mchar* szfilenamesw)
  832. {
  833.     // 新しくテキストウィンドウを開き、szfilenameをオープン
  834.     // szfilenameには、次の様にファイル名に続けてスイッチを指定できます
  835.     //        a:\wz\readme.txt /J100
  836.     // 空白を含むファイルは、次のように""で括ってください。
  837.     //        "a:\wz editor\readme.txt" /J100
  838.     //3.00 複数のファイルを指定することはできなくなりました。
  839.     //2.94 970123 EXEから移動
  840.     //3.00A2 970507 txOpenForkは必ず別プロセスのテキストを開く様に仕様変更
  841.     // 既に指定したファイルが開かれている場合で、そのファイルが現在のプロセス内で
  842.     // 開かれている場合は、ファイルのプロセスと現在のプロセスは同じです。
  843. #if 1///3.00A2 970507
  844.     return forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ,NULL);
  845. #else
  846.     return forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ_ENABLE,NULL);
  847. #endif
  848. }
  849.  
  850. BOOL TXAPIBASE txOpenForkFast(TX* text,mchar* szfilenamesw)
  851. {
  852. // txOpenForkと同じですが、高速オープンできる場合は高速オープンします。
  853. // 高速オープンできない場合は、別プロセスでオープンします。
  854. // WZ3.00無印の旧txOpenForkの仕様と同じです。
  855. //3.00A2 970507 new
  856.     return forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ_ENABLE,NULL);
  857. }
  858.  
  859.  
  860. BOOL TXAPI txOpenForkEx(TX* text,mchar* szfilenamesw)
  861. {
  862.     // textが新規テキストなら、それを閉じてからtxOpenFork
  863.     // そうでなければ、txOpenFork
  864.     // スイッチも指定できます
  865.     //2.94 970123 EXEから移動
  866.     //3.00A2 970507 txOpenForkExは必ず別プロセスのテキストを開く様に仕様変更
  867.     // 既に指定したファイルが開かれている場合で、そのファイルが現在のプロセス内で
  868.     // 開かれている場合は、ファイルのプロセスと現在のプロセスは同じです。
  869. #if 1///3.00A2 970507
  870.     return forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ|TXFORK_CLOSE_NULL,NULL);
  871. #else
  872.     return forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ_ENABLE|TXFORK_CLOSE_NULL,NULL);
  873. #endif
  874. }
  875.  
  876. BOOL TXAPI txOpenForkExFast(TX* text,mchar* szfilenamesw)
  877. {
  878. // txOpenForkExと同じですが、高速オープンできる場合は高速オープンします。
  879. // WZ3.00無印の旧txOpenForkExの仕様と同じです。
  880. //3.00A2 970507 new
  881.     return forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ_ENABLE|TXFORK_CLOSE_NULL,NULL);
  882. }
  883.  
  884. HWND TXAPIBASE txOpen(TX* text,mchar* szfilenamesw)
  885. {
  886.     // 新しくテキストウィンドウを開き、szfilenameを読み込みます。
  887.     // 新規ファイルを開く時は、szfilenameに""を指定してください。
  888.     // szfilenameには、次の様にファイル名に続けてスイッチを指定できます
  889.     //        a:\wz\readme.txt /J100
  890.     // 空白を含むファイルは、次のように""で括ってください。
  891.     //        "a:\wz editor\readme.txt" /J100
  892.     // ファイルを複数指定することはできません。
  893.     // テキストウィンドウがオープンされて
  894.     // キー入力待ち状態になるまで待ってから、テキストウィンドウの
  895.     // ウィンドウハンドル(text->hwndbaseに相当)を返します。
  896.     // 既にszfilenameのテキストウィンドウがオープンされていたら、
  897.     // 新しいテキストウィンドウは開かずに、オープンされているテキストウィンドウを
  898.     // アクティブウィンドウにして、そのウィンドウハンドルを返します。
  899.     // 失敗すれば、NULLを返します
  900.     //1.01Aで追加
  901.     //2.94 970123 EXEから移動
  902.     //3.00A2 970507 txOpenは必ず別プロセスのテキストを開く様に仕様変更。
  903.     // 既に指定したファイルが開かれている場合で、そのファイルが現在のプロセス内で
  904.     // 開かれている場合は、ファイルのプロセスと現在のプロセスは同じです。
  905. #if 1///3.00A2 970507
  906.     TXFORKRESULT result;
  907.     if (forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ|TXFORK_SYNC,&result)) {
  908.         return result.hwnd;
  909.     }
  910.     if (result.fAlrearyOpen) return result.hwnd;//3.00B1 970612 txOpenで既にファイルがオープンされていたときそのhwndが返らなかった
  911.     return NULL;
  912. #else
  913.     TXFORKRESULT result;
  914.     if (forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ_ENABLE|TXFORK_SYNC,&result)) {
  915.         return result.hwnd;
  916.     }
  917.     return NULL;
  918. #endif
  919. }
  920.  
  921. HWND TXAPI txOpenFast(TX* text,mchar* szfilenamesw)
  922. {
  923. // txOpenと同じですが、高速オープンできる場合は高速オープンします。
  924. // 高速オープンできない場合は、別プロセスでオープンします。
  925. // WZ3.00無印の旧txOpenの仕様と同じです。
  926. // 3.00Aでは、高速オープンした場合は、次のプログラムはハングする危険があります。
  927. //   HWND hwnd = txOpenFast(text,szfilename);
  928. //   wndtxCall(hwnd,szcmd);
  929. // この場合は、次の様にsleepを入れて下さい。
  930. //   HWND hwnd = txOpenFast(text,szfilename);
  931. //   sleep(1);
  932. //   wndtxCall(hwnd,szcmd);
  933. // 3.00Bでは上記の制限は解消されました。
  934. //3.00A2 970507 new
  935.     TXFORKRESULT result;
  936.     if (forkex(szfilenamesw,NULL,TXFORK_OLDARG|TXFORK_FORKWZ_ENABLE|TXFORK_SYNC,&result)) {
  937.         return result.hwnd;
  938.     }
  939.     if (result.fAlrearyOpen) return result.hwnd;//3.00B1 970612 txOpenで既にファイルがオープンされていたときそのhwndが返らなかった
  940.     return NULL;
  941. }
  942.  
  943. BOOL TXAPI txInit(TX* text,mchar* szfilename)
  944. {
  945. // 次のプログラムと等価
  946. // txInitText(text);
  947. // txSetFileName(text,szfilename);
  948. // return txOpenText(text);
  949. //2.00Eで追加
  950.     txInitText(text);
  951.     txSetFileName(text,szfilename);
  952.     return txOpenText(text);
  953. }
  954.  
  955. void TXAPI txInitTextBinary(tx* text)
  956. {
  957. // txInitTextの様にtext構造体を初期化する。
  958. // バイナリ用として初期化する
  959. // この後、txSetFileNameすると意味がなくなる。
  960.     txInitText(text);
  961.     text->fNoConfig = TRUE;
  962.     text->fAppendEof = FALSE;
  963.     text->fBinary = TRUE;
  964.     txOpenText(text);
  965.     txSetHigh(text);
  966. }
  967.  
  968. void TXAPI txOpenTextBinary(tx* text,mchar* szfilename,UINT cbRecord,UINT cbHeader)
  969. {
  970. // txInitTextの様にtext構造体を初期化する。
  971. // バイナリ用として初期化する
  972. // この後、txSetFileNameすると意味がなくなる。
  973. // cbRecord,cbHeaderは最大32KB程度まで。
  974.     txInitText(text);
  975.     text->fNoConfig = TRUE;
  976.     text->fAppendEof = FALSE;
  977.     text->fBinary = TRUE;
  978.     text->fTempMem = TRUE;//2.97 970216 WZ32でテンプラリ作成だと、linkatrが大きいと表示が異様に遅くなる。WZ16は仕方ない。
  979.     if (szfilename) {
  980.         strcpy(text->szfilename,szfilename);
  981.     }
  982.     txOpenText(text);
  983.     txSetHigh(text);
  984.     //
  985.     text->cbRecord = cbRecord;
  986.     text->cbHeader = cbHeader;
  987. }
  988.  
  989. void TXAPI txInitTextText(tx* text)
  990. {
  991. // txInitTextの様にtext構造体を初期化する。
  992. // テキスト用(Eofつけない)として初期化する
  993. // この後、txSetFileNameすると意味がなくなる。
  994.     txInitText(text);
  995.     text->fNoConfig = TRUE;
  996.     text->fAppendEof = FALSE;
  997.     txOpenText(text);
  998. }
  999.  
  1000. #define SIZEBUFF    1024
  1001.  
  1002. // カーソル位置にsizeバイトの0を挿入
  1003. static BOOL txInsertBytes(tx *text,IFILE size)
  1004. {
  1005.     BYTE buff[SIZEBUFF];
  1006.     memset(buff,0,sizeof(buff));
  1007.     while(size) {
  1008.         IMEM len = SIZEBUFF;
  1009.         if (size < len) len = size;
  1010.         txInsertBuff(text,buff,len);
  1011.         size -= len;
  1012.     }
  1013.     return TRUE;
  1014. }
  1015.  
  1016. // テキストサイズをsizeバイト拡大
  1017. // 拡大によってできた領域は0で埋められる
  1018. static BOOL txExpand(tx *text,IFILE size)
  1019. {
  1020.     txJumpFileEnd(text);
  1021.     return txInsertBytes(text,size);
  1022. }
  1023.  
  1024. IFILE TXAPI txRecordGetAddress(tx* text,TXRECORD irecord)
  1025. {
  1026.     return text->cbHeader + irecord * text->cbRecord;
  1027. }
  1028.  
  1029. // ヘッダエリアを確保
  1030. static BOOL txHeaderAlloc(TX* text)
  1031. {
  1032.     IFILE size = txGetTextSize(text);
  1033.     IFILE address = text->cbHeader;
  1034.     if (address > size) return txExpand(text,address - size);
  1035.     return TRUE;
  1036. }
  1037.  
  1038. BOOL TXAPI txHeaderRead(TX* text,LPVOID pHeader)
  1039. {
  1040.     if (!txHeaderAlloc(text)) {
  1041.         memset(pHeader,0,text->cbHeader);
  1042.         return FALSE;
  1043.     }
  1044.     txJumpFileTop(text);
  1045.     memcpy(pHeader,text->buff + text->cur,text->cbHeader);
  1046.     return TRUE;
  1047. }
  1048.  
  1049. BOOL TXAPI txHeaderWrite(TX* text,LPVOID pHeader)
  1050. {
  1051.     if (!txHeaderAlloc(text)) return FALSE;
  1052.     text->fEdit = TRUE;
  1053.     txJumpFileTop(text);
  1054.     memcpy(text->buff + text->cur,pHeader,text->cbHeader);
  1055.     return TRUE;
  1056. }
  1057.  
  1058. static BOOL txRecordIsExist(tx* text,TXRECORD irecord)
  1059. {
  1060.     if (!text) return FALSE;
  1061. #if 1//1.93 
  1062.     {
  1063.         IFILE size = txGetTextSize(text);
  1064.         IFILE address = txRecordGetAddress(text,irecord);
  1065.         if (address < size) return TRUE;
  1066.     }
  1067.     return FALSE;
  1068. #else
  1069.     {
  1070.         IFILE size = txGetTextSize(text);
  1071.         IFILE address = txRecordGetAddress(text,irecord);
  1072.         if (address > size) return FALSE;
  1073.     }
  1074.     return TRUE;
  1075. #endif
  1076. }
  1077.  
  1078. static void myerror(int line)
  1079. {
  1080.     attention("err stdlib %d",line);
  1081. }
  1082.  
  1083. static BOOL txRecordExpand(tx* text,TXRECORD irecord)
  1084. {
  1085. // レコード数をirecordまで拡大
  1086.     if (!text) return FALSE;
  1087.     if ((long)irecord < 0) {
  1088.         // irecordがマイナス値になっている
  1089.         myerror(__LINE__);
  1090.         return FALSE;
  1091.     }
  1092.     {
  1093.         IFILE size = txGetTextSize(text);
  1094.         IFILE address = txRecordGetAddress(text,irecord);
  1095.         if (address > size) return txExpand(text,address - size);
  1096.     }
  1097.     return TRUE;
  1098. }
  1099.  
  1100. BOOL TXAPI txRecordSeek(tx* text,TXRECORD irecord)
  1101. {
  1102. // レコード数をirecordまで拡大してtxJumpAddressする
  1103.     if (txRecordExpand(text,irecord)) {
  1104.         txJumpAddress(text,txRecordGetAddress(text,irecord));
  1105.         return TRUE;
  1106.     }
  1107.     return FALSE;
  1108. }
  1109.  
  1110. BOOL TXAPI txRecordIsInsideBuff(tx* text)
  1111. {
  1112. // textやpRecordがNULLならFALSEを返す
  1113. // irecordのレコードが存在しないときもNULLを返す
  1114. // うまくいったらカーソルをレコード先頭に設定し、レコード先頭のテキストバッファアドレスを返す
  1115. //1.98で追加
  1116.     UINT cbRecord = text->cbRecord;
  1117.     if (text->sizebuff - text->cur >= cbRecord) return TRUE;
  1118.     return FALSE;
  1119. }
  1120.  
  1121. LPVOID TXAPI txRecordReadP(tx* text,TXRECORD irecord)
  1122. {
  1123. // textやpRecordがNULLならFALSEを返す
  1124. // irecordのレコードが存在しないときもNULLを返す
  1125. // うまくいったらirecordを指すメモリポインタを返します。
  1126. // 返せない時はNULLを返します。
  1127. //2.97 970216 仕様変更
  1128.     if (!text) return NULL;
  1129.     if (!txRecordIsExist(text,irecord)) return NULL;
  1130.     txRecordExpand(text,irecord + 1);
  1131. #if 1//2.97 970216 
  1132. {
  1133.     IFILE adr = txRecordGetAddress(text,irecord);
  1134.     IMEM cbGap = text->cur - text->cur0;
  1135.     if (text->temp1 <= adr && adr + text->cbRecord <= text->temp1 + text->sizebuff - cbGap) {
  1136.         // テキストバッファ内にある
  1137.         IMEM off = (adr - text->temp1);
  1138.         if (off < text->cur0) {
  1139.             if (off + text->cbRecord <= text->cur0) {
  1140.                 return text->buff + off;
  1141.             } else {
  1142.                 // gapにまたがるときは、従来ルーチンを使用
  1143.             }
  1144.         } else {
  1145.             return text->buff + off + cbGap;
  1146.         }
  1147.     }
  1148.     txJumpAddress(text,adr);
  1149.     if (text->sizebuff - text->cur >= text->cbRecord) return text->buff + text->cur;
  1150.     return NULL;
  1151. }
  1152. #else
  1153.     txJumpAddress(text,txRecordGetAddress(text,irecord));
  1154.     return text->buff + text->cur;
  1155. #endif
  1156. }
  1157.  
  1158. BOOL TXAPI txRecordReadEx(tx* text,TXRECORD irecord,UINT offset,LPVOID pMem,UINT cbMem)
  1159. {
  1160. // レコードのoffsetオフセットからcbMemサイズの内容をpMemにロードする
  1161. // textやpMemがNULLならFALSEを返す
  1162. // irecordのレコードが存在しないときは、pMemを0で初期化しTRUEを返します
  1163.     if (!text || !pMem) return FALSE;
  1164.     if (!txRecordIsExist(text,irecord)) {
  1165.         memset(pMem,0,cbMem);
  1166.         return TRUE;
  1167.     }
  1168.     txRecordExpand(text,irecord + 1);
  1169. #if 1//2.97 970216 txJumpAddressの使用を控えて高速化 for linkatr
  1170. {
  1171.     mchar* p = txRecordReadP(text,irecord);
  1172.     if (p) {
  1173.         memcpy(pMem,p + offset,cbMem);
  1174.         return TRUE;
  1175.     } else {
  1176.         LPBYTE pRecord = malloc(text->cbRecord);
  1177.         BOOL ret = FALSE;
  1178.         if (pRecord) {
  1179.             if (txRecordRead(text,irecord,pRecord)) {
  1180.                 memcpy(pMem,pRecord + offset,cbMem);
  1181.                 ret = TRUE;
  1182.             }
  1183.             free(pRecord);
  1184.         }
  1185.         return ret;
  1186.     }
  1187. }
  1188. #else
  1189.     txJumpAddress(text,txRecordGetAddress(text,irecord));
  1190.     if (txRecordIsInsideBuff(text)) {
  1191.         memcpy(pMem,text->buff + text->cur + offset,cbMem);
  1192.     } else {
  1193.         LPBYTE pRecord = malloc(text->cbRecord);
  1194.         BOOL ret = FALSE;
  1195.         if (pRecord) {
  1196.             if (txRecordRead(text,irecord,pRecord)) {
  1197.                 memcpy(pMem,pRecord + offset,cbMem);
  1198.                 ret = TRUE;
  1199.             }
  1200.             free(pRecord);
  1201.         }
  1202.         return ret;
  1203.     }
  1204.     return TRUE;
  1205. #endif
  1206. }
  1207.  
  1208. BOOL TXAPI txRecordRead(tx* text,TXRECORD irecord,LPVOID pRecord)
  1209. {
  1210. // textやpRecordがNULLならFALSEを返す
  1211. // irecordのレコードが存在しないときは、pRecordを0で初期化しTRUEを返します
  1212.     if (!text || !pRecord) return FALSE;
  1213.     if (!txRecordIsExist(text,irecord)) {
  1214.         memset(pRecord,0,text->cbRecord);
  1215.         return TRUE;
  1216.     }
  1217.     txRecordExpand(text,irecord + 1);
  1218. #if 1//2.97 970216 txJumpAddressの使用を控えて高速化 for linkatr
  1219. {
  1220.     IFILE adr = txRecordGetAddress(text,irecord);
  1221.     IMEM cbGap = text->cur - text->cur0;
  1222.     if (text->temp1 <= adr && adr + text->cbRecord <= text->temp1 + text->sizebuff - cbGap) {
  1223.         IMEM off = (adr - text->temp1);
  1224.         if (off < text->cur0) {
  1225.             if (off + text->cbRecord <= text->cur0) {
  1226.                 memcpy(pRecord,text->buff + off,text->cbRecord);
  1227.                 return TRUE;
  1228.             } else {
  1229.                 UINT cb = text->cur0 - off;
  1230.                 memcpy(pRecord,text->buff + off,cb);
  1231.                 memcpy((LPBYTE)pRecord + cb,text->buff + text->cur,text->cbRecord - cb);
  1232.                 return TRUE;
  1233.             }
  1234.         } else {
  1235.             memcpy(pRecord,text->buff + off + cbGap,text->cbRecord);
  1236.             return TRUE;
  1237.         }
  1238.     }
  1239.     txJumpAddress(text,adr);
  1240.     if (txRecordIsInsideBuff(text)) {
  1241.         memcpy(pRecord,text->buff + text->cur,text->cbRecord);
  1242.     } else {
  1243.         UINT cb = text->sizebuff - text->cur;
  1244.         memcpy(pRecord,text->buff + text->cur,cb);
  1245.         if (!txSwapNext(text)) return FALSE;
  1246.         memcpy((LPBYTE)pRecord + cb,text->buff + text->cur,text->cbRecord - cb);
  1247.     }
  1248.     return TRUE;
  1249. }
  1250. #else
  1251.     txJumpAddress(text,txRecordGetAddress(text,irecord));
  1252.     if (txRecordIsInsideBuff(text)) {
  1253.         memcpy(pRecord,text->buff + text->cur,text->cbRecord);
  1254.     } else {
  1255.         UINT cb = text->sizebuff - text->cur;
  1256.         memcpy(pRecord,text->buff + text->cur,cb);
  1257.         if (!txSwapNext(text)) return FALSE;
  1258.         memcpy((LPBYTE)pRecord + cb,text->buff + text->cur,text->cbRecord - cb);
  1259.     }
  1260.     return TRUE;
  1261. #endif
  1262. }
  1263.  
  1264. BOOL TXAPI txRecordWriteEx(tx* text,TXRECORD irecord,UINT offset,LPVOID pMem,UINT cbMem)
  1265. {
  1266. // レコードのoffsetオフセットからcbMemサイズの内容をpMemにセットする
  1267. // textやpMemがNULLならFALSEを返す
  1268. // irecordのレコードが存在しないときは、pMemを0で初期化しTRUEを返します
  1269.     if (!text || !pMem) return FALSE;
  1270.     txRecordExpand(text,irecord + 1);
  1271.     txJumpAddress(text,txRecordGetAddress(text,irecord));
  1272.     text->fEdit = TRUE;
  1273.     if (txRecordIsInsideBuff(text)) {
  1274.         memcpy(text->buff + text->cur + offset,pMem,cbMem);
  1275.     } else {
  1276.         LPBYTE pRecord = malloc(text->cbRecord);
  1277.         BOOL ret = FALSE;
  1278.         if (pRecord) {
  1279.             if (txRecordRead(text,irecord,pRecord)) {
  1280.                 memcpy(pRecord + offset,pMem,cbMem);
  1281.                 if (txRecordWrite(text,irecord,pRecord)) {
  1282.                     ret = TRUE;
  1283.                 }
  1284.             }
  1285.             free(pRecord);
  1286.         }
  1287.         return ret;
  1288.     }
  1289.     return TRUE;
  1290. }
  1291.  
  1292. BOOL TXAPI txRecordWrite(tx* text,TXRECORD irecord,LPVOID pRecord)
  1293. {
  1294. // textやpRecordがNULLならFALSEを返す
  1295. // irecordまでで存在しないレコードがあるときは、その部分のデータは0で初期化されます。
  1296.     if (!text || !pRecord) return FALSE;
  1297.     txRecordExpand(text,irecord + 1);
  1298.     txJumpAddress(text,txRecordGetAddress(text,irecord));
  1299.     text->fEdit = TRUE;
  1300.     if (txRecordIsInsideBuff(text)) {
  1301.         memcpy(text->buff + text->cur,pRecord,text->cbRecord);
  1302.     } else {
  1303.         UINT cb = text->sizebuff - text->cur;
  1304.         memcpy(text->buff + text->cur,pRecord,cb);
  1305.         if (!txSwapNext(text)) return FALSE;
  1306.         memcpy(text->buff + text->cur,(LPBYTE)pRecord + cb,text->cbRecord - cb);
  1307.     }
  1308.     return TRUE;
  1309. }
  1310.  
  1311. BOOL TXAPI txRecordInsert(tx* text,TXRECORD irecord,TXRECORD nrecord)
  1312. {
  1313.     if (!text) return FALSE;
  1314.     text->fEdit = TRUE;
  1315.     txRecordExpand(text,irecord);
  1316.     txJumpAddress(text,txRecordGetAddress(text,irecord));
  1317.     txInsertBytes(text,(DWORD)nrecord * text->cbRecord);
  1318.     return TRUE;
  1319. }
  1320.  
  1321. BOOL TXAPI txRecordDelete(tx* text,TXRECORD irecord,TXRECORD nrecord)
  1322. {
  1323.     if (!text) return FALSE;
  1324.     if (!txRecordIsExist(text,irecord)) return TRUE;//1.90 
  1325.     text->fEdit = TRUE;
  1326.     txRecordExpand(text,irecord);
  1327.     txJumpAddress(text,txRecordGetAddress(text,irecord));
  1328.     txDeleteBytes(text,(DWORD)nrecord * text->cbRecord);
  1329.     return TRUE;
  1330. }
  1331.  
  1332. TXRECORD TXAPI txRecordGetCount(tx* text)
  1333. {
  1334.     if (!text) return 0;
  1335.     {
  1336.         IFILE size = txGetTextSize(text);
  1337.         if (size <= text->cbHeader) return 0;
  1338.         return (size - text->cbHeader) / text->cbRecord;
  1339.     }
  1340. }
  1341.  
  1342. TXRECORD TXAPI txRecordAdd(tx* text,LPVOID pRecord)
  1343. {
  1344. // 追加したレコード番号を返す
  1345. // 追加できなかったらTXRECORD_ERRORを返す
  1346.     if (!text) return TXRECORD_ERROR;
  1347.     {
  1348.         TXRECORD i = txRecordGetCount(text);
  1349.         txRecordWrite(text,i,pRecord);
  1350.         return i;
  1351.     }
  1352. }
  1353.  
  1354. BOOL TXAPI txRecordConvertSize(TX* text,UINT cbRecordOld)
  1355. {
  1356. // レコードのサイズをcbRecordOldから現在の値に変更します。
  1357. // 拡大の場合は、レコードの末尾に0を追加して拡大します
  1358. // 縮小の場合は、レコードの末尾をカットします
  1359. //2.00D で追加
  1360.     TXRECORD n;
  1361.     TXRECORD i;
  1362.     BOOL ret = FALSE;
  1363.     UINT cbRecordNew = text->cbRecord;
  1364.     //
  1365.     text->cbRecord = cbRecordOld;
  1366.     n = txRecordGetCount(text);
  1367.     if (cbRecordNew > cbRecordOld) {
  1368.         // 拡大
  1369.         IFILE ifile = text->cbHeader + cbRecordOld;
  1370.         UINT cbExpand = cbRecordNew - cbRecordOld;
  1371.         LPBYTE p = memAllocZeroinit(cbExpand);
  1372.         if (p) {
  1373.             for (i = 0;i < n;i++) {
  1374.                 txJumpAddress(text,ifile);
  1375.                 txInsertBuff(text,p,cbExpand);
  1376.                 ifile += cbRecordNew;
  1377.             }
  1378.             memFree(p);
  1379.             ret = TRUE;
  1380.         }
  1381.     } else if (cbRecordNew < cbRecordOld) {
  1382.         // 縮小
  1383.         IFILE ifile = text->cbHeader + cbRecordNew;
  1384.         UINT cbReduce = cbRecordOld - cbRecordNew;
  1385.         for (i = 0;i < n;i++) {
  1386.             txJumpAddress(text,ifile);
  1387.             txDeleteBytes(text,cbReduce);
  1388.             ifile += cbRecordNew;
  1389.         }
  1390.         ret = TRUE;
  1391.     }
  1392.     text->cbRecord = cbRecordNew;
  1393.     return ret;
  1394. }
  1395.  
  1396. //{###範囲選択}
  1397.  
  1398. static IFILE _curwalkstart;
  1399. static int _lywalkstart;    //1.00C
  1400. static int _fselectjump;    //1.00C
  1401.  
  1402. static BOOL txIsWalkable(tx *text)
  1403. {
  1404.     if (
  1405.         text->fClip == CLIP_CHAR ||
  1406.         text->fClip == CLIP_LINE ||
  1407.         text->fClip == CLIP_PARA ||
  1408.         text->fClip == CLIP_ALL || //1.00B すべて選択に対応
  1409.         text->fClip == CLIP_WORD ||
  1410.         text->fClip == CLIP_SENTENCE
  1411.     ) {
  1412.         return TRUE;
  1413.     }
  1414.     return FALSE;
  1415. }
  1416.  
  1417. BOOL TXAPIBASE txWalkStart(tx *text)
  1418. {
  1419. // 範囲内walkを開始します
  1420. // この関数を呼び出してからtxIsWalking(text)が真の間まで、
  1421. // カーソルをテキスト後方に動かして範囲内のwalkができます
  1422.     if (!txIsWalkable(text)) return FALSE;
  1423.     _lywalkstart = text->ly;
  1424.     _fselectjump = FALSE;
  1425.     txSetUndisp(text);
  1426.     if (text->fClip == CLIP_ALL) {//1.00B すべて選択に対応
  1427.         _curwalkstart = txGetAddress(text);
  1428.         txJumpFileTop(text);
  1429.     } else {
  1430. #if 1//1.00F
  1431.         txFlushSelectNow(text);
  1432.         if (text->clipendnow > text->cliptopnow) {
  1433.             _fselectjump = TRUE;
  1434.             txSelectJump(text);
  1435.         } else {
  1436.             txSelectToChar(text);
  1437.         }
  1438.         _curwalkstart = txGetAddress(text);
  1439. #else
  1440.         if (text->temp1 + text->cur0 > text->cliptop) {
  1441.             _fselectjump = TRUE;
  1442.             txSelectJump(text);
  1443.         }
  1444.         txFlushCurSelect(text);
  1445.         _curwalkstart = txGetAddress(text);
  1446. #endif
  1447.     }
  1448.     return TRUE;
  1449. }
  1450.  
  1451. BOOL TXAPIBASE txIsWalking(tx *text)
  1452. {
  1453. // カーソルが範囲内にあるか返します
  1454.     if (text->fClip == CLIP_ALL) return !txIsCurEof(text);//1.00B すべて選択に対応
  1455.     return text->temp1 + text->cur0 < text->cliptop;
  1456. }
  1457.  
  1458. BOOL TXAPIBASE txWalkEnd(tx *text)
  1459. {
  1460. // 範囲内walkを終わります
  1461. // カーソル位置を、範囲の先頭にセットします
  1462.     if (!txIsWalkable(text)) return FALSE;
  1463.     text->ly = _lywalkstart;
  1464.     txJumpAddress(text,_curwalkstart);
  1465.     if (_fselectjump) txSelectJump(text);
  1466.     txSetDisp(text);
  1467.     return TRUE;
  1468. }
  1469.  
  1470. BOOL TXAPIBASE txWalkStartPrev(tx *text)
  1471. {
  1472. // 前方範囲内walkを開始します
  1473. // この関数を呼び出してからtxIsWalkingPrev(text)が真の間まで、
  1474. // カーソルをテキスト前方に動かして範囲内のwalkができます
  1475.     if (!txIsWalkable(text)) return FALSE;
  1476.     _lywalkstart = text->ly;
  1477.     _fselectjump = FALSE;
  1478.     if (text->fClip == CLIP_ALL) {//1.00B すべて選択に対応
  1479.         _curwalkstart = txGetAddress(text);
  1480.         txJumpFileTop(text);
  1481.     } else {
  1482.         txSetUndisp(text);
  1483. #if 1//1.00F
  1484.         txFlushSelectNow(text);
  1485.         if (text->clipendnow < text->cliptopnow) {
  1486.             _fselectjump = TRUE;
  1487.             txSelectJump(text);
  1488.         } else {
  1489.             txSelectToChar(text);
  1490.         }
  1491.         _curwalkstart = txGetAddress(text);
  1492. #else
  1493.         if (text->temp1 + text->cur0 < text->cliptop) {
  1494.             _fselectjump = TRUE;
  1495.             txSelectJump(text);
  1496.         }
  1497.         txFlushCurSelect(text);
  1498.         _curwalkstart = text->cliptop;
  1499. #endif
  1500.     }
  1501.     return TRUE;
  1502. }
  1503.  
  1504. BOOL TXAPIBASE txIsWalkingPrev(tx *text)
  1505. {
  1506. // カーソルが前方範囲内にあるか返します
  1507.     if (text->fClip == CLIP_ALL) {//1.00B すべて選択に対応
  1508.         return (txGetAddress(text) != 0);
  1509.     }
  1510.     return text->temp1 + text->cur0 > text->cliptop;
  1511. }
  1512.  
  1513. BOOL TXAPI txkeySelectWin(TX* text)
  1514. {
  1515. //2.95 970125 
  1516.     if (text->modeEditor == ME_WIN) {
  1517.         if (
  1518.             (text->fKeyVkShift == 0 && GetKeyState(VK_SHIFT) < 0) ||
  1519.             text->fKeyVkShift == 2
  1520.         ) {
  1521.             if (text->fClip && text->fClipMouse) {
  1522.                 // 既に選択中
  1523.             } else {
  1524.                 if (text->modeKeyClip == MC_WZ) {
  1525.                     txSelectEx(text,CLIP_WZ);
  1526.                 } else if (text->modeKeyClip == MC_VZ) {
  1527.                     txSelectEx(text,CLIP_VZ);
  1528.                 } else {
  1529.                     txSelectEx(text,CLIP_CHAR);
  1530.                 }
  1531.                 text->fClipMouse = TRUE;
  1532.             }
  1533.             return TRUE;
  1534.         } else {
  1535.             //2.96 970202 txkeyJumpLineTopでSHIFTが押されていないとき選択が解除されてなかった
  1536.             if (text->fClip && text->fClipMouse) {
  1537.                 txSelectQuit(text);
  1538.             }
  1539.         }
  1540.     }
  1541.     return FALSE;
  1542. }
  1543.  
  1544. //{###編集}
  1545.  
  1546. int TXAPI txkeyOverWriteChar(TX* text,TXCHAR ch)
  1547. {
  1548. //2.96 970209 新API
  1549.     if (text->fClipMouse) txSelectDelete(text);//2.96 970209 
  1550.     if (txGetFreeCursor(text)) txInsertSpaceFreeCursor(text);//1.01A 
  1551.     return txOverWriteChar(text,ch);
  1552. }
  1553.  
  1554. int TXAPI txkeyInsert(TX* text,mchar* szstr)
  1555. {
  1556. //2.96 970209 新API
  1557.     if (text->fClipMouse) txSelectDelete(text);//2.96 970209 
  1558.     if (txGetFreeCursor(text)) txInsertSpaceFreeCursor(text);//1.01A キーボードマクロ再生時に、フリーカーソルが効かなかった
  1559.     return txInsert(text,szstr);
  1560. }
  1561.  
  1562. //{###カット&ペースト}
  1563.  
  1564. //2.00E7 プライベートテキストスタックのカットアンドペースト系コマンド(txPrivateXXX)追加
  1565. //2.98 970305 edit.cから移動
  1566.  
  1567. BOOL TXAPIBASE txPrivatePop(tx *text)
  1568. {
  1569. // プライベートテキストスタックからポップ
  1570. // カーソルは移動しません
  1571. //2.00E7で追加
  1572.     BOOL ret = txClipPaste(text,HCLIP_PRIVATE,FALSE,0);
  1573.     clipDeleteTop(HCLIP_PRIVATE);
  1574.     return ret;
  1575. }
  1576.  
  1577. BOOL TXAPIBASE txPrivatePopJump(TX* text)
  1578. {
  1579. // プライベートテキストスタックからポップ
  1580. // カーソルを、ペーストしたバイト数、移動します。
  1581. //3.00A2 970506 new
  1582.     BOOL ret = txClipPaste(text,HCLIP_PRIVATE,TRUE,0);
  1583.     clipDeleteTop(HCLIP_PRIVATE);
  1584.     return ret;
  1585. }
  1586.  
  1587. BOOL TXAPIBASE txPrivateDeleteTop(TX* text)
  1588. {
  1589. // プライベートテキストスタックの先頭を削除
  1590. //2.92で追加
  1591.     return clipDeleteTop(HCLIP_PRIVATE);
  1592. }
  1593.  
  1594. BOOL TXAPIBASE txPrivatePaste(tx *text)
  1595. {
  1596. // プライベートテキストスタックからペースト
  1597. // カーソルを、ペーストしたバイト数、移動します。
  1598. //2.00E7で追加
  1599.     return txClipPaste(text,HCLIP_PRIVATE,TRUE,0);
  1600. }
  1601.  
  1602. void TXAPIBASE txPrivateClear(tx *text)
  1603. {
  1604. // プライベートテキストスタックをクリア
  1605. //2.00E7で追加
  1606.     clipClear(HCLIP_PRIVATE);
  1607. }
  1608.  
  1609. BOOL TXAPIBASE TXHIGH txPrivatePush(tx *text)
  1610. {
  1611. // 範囲内をプライベートテキストスタックへプッシュ
  1612. //2.00E7で追加
  1613.     if (text->fClip) {
  1614.         return txClipSelectCopy(text,HCLIP_PRIVATE);
  1615.     } else {
  1616.         return FALSE;
  1617.     }
  1618. }
  1619.  
  1620. //{###ジャンプ}
  1621.  
  1622. void TXAPIBASE txJumpSelectTop(tx *text)
  1623. {
  1624. // 範囲の先頭へジャンプ
  1625.     if (text->temp1 + text->cur0 > text->cliptop) {
  1626.         txSelectJump(text);
  1627.     }
  1628. }
  1629.  
  1630. void TXAPIBASE txJumpSelectEnd(tx *text)
  1631. {
  1632. // 範囲の末尾へジャンプ
  1633.     if (text->temp1 + text->cur0 < text->cliptop) {
  1634.         txSelectJump(text);
  1635.     }
  1636. }
  1637.  
  1638. int TXAPIBASE txJumpNpara(TX* text,NPARA npara)
  1639. {
  1640. // テキストのnpara段落の、段落の先頭へジャンプ
  1641. //2.00Bで追加
  1642.     int ret = txJumpPara(text,npara);
  1643.     txJumpParaTop(text);
  1644.     return ret;
  1645. }
  1646.  
  1647. //{###マクロ}
  1648.  
  1649. DWORD TXAPIBASE call(mchar *szmacro)
  1650. {
  1651. // マクロを呼び出す。返り値を返す。
  1652. // szmacroは大文字小文字を区別しません
  1653. // 例:call("launcher");
  1654. // 例:call("launcher.root");
  1655. // 参考:callは、マクロを通常の関数呼び出しで呼び出すのではなく、新しく
  1656. // マクロコンテキストを作成して、このコンテキスト上でマクロを実行します。
  1657. // マクロの実行が終るとコンテキストは終了し、callの次の命令の実行に戻ります。
  1658.     DWORD ret = 0;
  1659.     // ロジックはcallmacroと同じ
  1660.     if (strchr(szmacro,'(')) {
  1661.         // 引数つき
  1662.         macroCallStr(szmacro,&ret);
  1663.     } else {
  1664.         // 引数なし
  1665.         // textfを引数として渡して呼び出す
  1666.         extern tx *textf;
  1667.         macroCall(szmacro,&ret,1,textf);
  1668.     }
  1669.     return ret;
  1670. }
  1671.  
  1672. #ifdef __TXC__
  1673.  
  1674. //{###情報取得}
  1675.  
  1676. UINT TXAPI txFormChar(TX* text,mchar* str,UINT offset)
  1677. {
  1678. // strからoffsetバイト目に最も近い文字の先頭のオフセットを返す
  1679. //2.99C 970325 new
  1680.     return txOp(text,TXOP_TXFORMCHAR,(LPARAM)str,(LPARAM)offset);
  1681. }
  1682.  
  1683. BOOL TXAPI txIsCharTop(TX* text,IBUFF off)
  1684. {
  1685. // offが文字の先頭かどうか返す
  1686. //2.99C 970325 new
  1687.     return txOp(text,TXOP_TXISCHARTOP,off,0);
  1688. }
  1689.  
  1690. int TXAPI txGetWordWhole(TX* text,txstr str)
  1691. {
  1692. // 範囲選択されているとき(txIsClipInPara=真のとき)はtxGetWordと同じ
  1693. // そうでなければカーソル位置の単語を取得
  1694. // txGetWordと異なるのは、txGetWordは単語の途中にカーソルがあるときは
  1695. // カーソル位置から単語の終わりまでを取得するが、txGetWordWholeは、
  1696. // 単語の始まりから終わりまでを取得する
  1697. //3.00B1 970612 new
  1698.     if (txIsClipInPara(text)) return txGetWord(text,str);
  1699.     //
  1700.     text->fUndisp++;
  1701.     txSelectEx(text,CLIP_WORD);
  1702.     int ret = txGetWord(text,str);
  1703.     txSelectQuit(text);
  1704.     text->fUndisp--;
  1705.     return ret;
  1706. }
  1707.  
  1708. int TXAPI txGetWordEx(TX* text,txstr str)
  1709. {
  1710. // txGetWordと同じです。
  1711. #if 1///3.00A 970428 txGetWordEx=txGetWordとした
  1712.     return txGetWord(text,str);
  1713. #else
  1714.     // 単語をstrに取得する
  1715.     // 1行内の範囲選択中なら、範囲内の文字をstrに取得
  1716.     //{#RET}取得したバイト数を返す
  1717.     // txGetWordは検索で見つけて選択されている時は選択中とみなさないが、
  1718.     // このAPIは選択中とみなす。
  1719.     //2.99C 970324 new
  1720.     if (text->fClipSearch) {
  1721.         BOOL fClipSearch0 = text->fClipSearch;
  1722.         text->fClipSearch = FALSE;
  1723.         int ret = txGetWord(text,str);
  1724.         text->fClipSearch = fClipSearch0;
  1725.         return ret;
  1726.     } else {
  1727.         return txGetWord(text,str);
  1728.     }
  1729. #endif
  1730. }
  1731.  
  1732. //{###マクロ}
  1733.  
  1734. BOOL TXAPI txVarSet(TX* text,mchar* szName,DWORD data)
  1735. {
  1736. // textローカル変数
  1737. // 変数名szName、値dataをセット
  1738. // 変数名に、'@'文字は使わないで下さい。
  1739. // 変数名の長さは最大40文字程度です。変数名が長すぎるとFALSEを返します。
  1740. // セットできたかどうか返す
  1741. // 3.00B以降ではtextローカル変数はメモリの許す限り使えます。WZ16では1400個まで使えます。
  1742. // 3.00,3.00Aでは、textローカル変数は255個使用可能です。
  1743. // textローカル変数が満杯になったら、古い変数から順に忘れていきます(ガベージコレクト)
  1744. // 大事な変数は、txVarSetNogarbageを使ってガベージコレクトの対象から外せます。
  1745.     return txOp(text,TXOP_VARSET,(LPARAM)szName,data);
  1746. }
  1747.  
  1748. DWORD TXAPI txVarGet(TX* text,mchar* szName)
  1749. {
  1750. // textローカル変数
  1751. // 変数名szNameの値をゲット
  1752. // ゲットできなれけば0を返す
  1753.     return txOp(text,TXOP_VARGET,(LPARAM)szName,0);
  1754. }
  1755.  
  1756. BOOL TXAPI txVarIsExist(TX* text,mchar* szName)
  1757. {
  1758. // textローカル変数
  1759. // 変数名szNameの変数が存在するかどうか返す
  1760.     return txOp(text,TXOP_VARISEXIST,(LPARAM)szName,0);
  1761. }
  1762.  
  1763. BOOL TXAPI txVarSetNogarbage(TX* text,mchar* szName,BOOL fNoGarbage)
  1764. {
  1765. // textローカル変数
  1766. // 変数名szNameの変数はガベージコレクトの対象にしない
  1767. #if 1//3.00B2 970615 txVarSetNogarbageは使われなくなりました
  1768.     return FALSE;
  1769. #else
  1770.     return txOp(text,TXOP_VARSETNOGARBAGE,(LPARAM)szName,fNoGarbage);
  1771. #endif
  1772. }
  1773.  
  1774. //{###設定}
  1775.  
  1776. void TXAPI txInitConfig(TX* text)
  1777. {
  1778. // textの設定をシステム既定値にする
  1779. // 折り返し幅はMAXWIDTH、書式文字列は標準の設定の初期値、
  1780. // 縦書きやバイナリ無効、タブサイズ8、フォントサイズはシステムフォントサイズ
  1781. // フォントはMSゴシックかMSPゴシック、プロポーショナルOFF、行番号や
  1782. // アンダーライン、制御文字表示オフ、色は標準の色、オートセーブOFF
  1783. // バックアップOFF、キー配列は標準のキー配列、行間1など。
  1784. //2.99B 970322 new
  1785.     txConfigOp(text,TXCONFIGOP_TXINITCONFIG,0);
  1786. }
  1787.  
  1788. //{###編集}
  1789.  
  1790. int TXAPIBASE txInsertf(tx *text,mchar *_format,...)
  1791. {
  1792. // printfの書式の使えるtxInsert
  1793. // CCHLINE文字を越える内容を挿入することはできません
  1794.     mchar buff[CCHLINE];
  1795.     if (_format) {
  1796.         vsprintf(buff,_format,(void*)(&_format + 1));
  1797.     } else {
  1798.         buff[0] = 0;
  1799.     }
  1800.     return txInsert(text,buff);
  1801. }
  1802.  
  1803. #endif  // __TXC__
  1804.  
  1805. BOOL TXAPIBASE txCurInsertReturn(TX* text)
  1806. {
  1807. // 改行を挿入し、カーソルを進めない
  1808. //2.99C 970326 new
  1809.     return txCurInsertBuff(text,"\x0D\x0A",2);
  1810. }
  1811.  
  1812. int TXAPI txInsertLine(TX *text,mchar *_format,...)
  1813. {
  1814. // txInsertfと同じですが、改行コードを追加して挿入します
  1815. //2.90 
  1816.     mchar buff[CCHLINE];
  1817.     if (_format) {
  1818.         vsprintf(buff,_format,(void*)(&_format + 1));
  1819.     } else {
  1820.         buff[0] = 0;
  1821.     }
  1822.     txInsert(text,buff);
  1823.     return txInsertReturn(text);
  1824. }
  1825.  
  1826. //2.00E2 tFontstyle[i]を返す。印刷スタイル使用に対応
  1827. FONTSTYLE* txGetFontstyleI(TX* text,int i)
  1828. {
  1829.     LPRINT* lp = text->lp;
  1830.     FONTSTYLE* fs = NULL;
  1831.     
  1832.     if (i == FONTTX_MARGIN) {
  1833.         // lp
  1834.         fs = &lp->fontstyleMargin;
  1835.     } else if (
  1836.         text->lp &&    //2.99E 970403 txInitText変更の影響
  1837.         txGetUsePrintFontstyle(text) && FONTTX_BODY <= i && i <= FONTTX_H6
  1838.     ) {
  1839.         //2.00D 
  1840.         fs = &lp->tFontstyle[i - FONTTX_BODY];
  1841.     } else if (text->tFontstyle) {
  1842.         // text
  1843.         fs = text->tFontstyle + i;
  1844.     }
  1845.     return fs;
  1846. }
  1847.  
  1848. int TXAPI paraatrGetAlign(TX* text,PARAATR* paraatr)
  1849. {
  1850. #if 1    //1.99G 左寄せが、ALIGN_NONEとALIGN_LEFTの2種類あって、
  1851.         // 混乱していた。左寄せを<CENTER>としていたりしていた。
  1852.         // ALIGN_NONEは返さず代わりにALIGN_LEFTを返すようにした。
  1853.     int ret = paraatr->modeAlign;
  1854.     if (paraatr->modeTitle) {
  1855.     #if 1//2.00E2 
  1856.         FONTSTYLE* fs = txGetFontstyleI(text,FONTTX_H1 + paraatr->modeTitle - 1);
  1857.     #else
  1858.         FONTSTYLE* fs = &text->tFontstyle[FONTTX_H1 + paraatr->modeTitle - 1];
  1859.     #endif
  1860.         if (fs->modeAlign) {
  1861.             ret = fs->modeAlign;
  1862.         }
  1863.     }
  1864.     if (ret) return ret;
  1865.     return ALIGN_LEFT;
  1866. #else
  1867.     if (paraatr->modeTitle) {
  1868.         FONTSTYLE* fs = &text->tFontstyle[FONTTX_H1 + paraatr->modeTitle - 1];
  1869.         if (fs->modeAlign) {
  1870.             return fs->modeAlign;
  1871.         }
  1872.     }
  1873.     return paraatr->modeAlign;
  1874. #endif
  1875. }
  1876.  
  1877. int TXAPI paraatrGetNest(TX* text,PARAATR* paraatr)
  1878. {
  1879.     if (text->fHTML) {
  1880.         // lcxIndentRightは、TAG_BLOCKQUOTE対応の為
  1881.         return (paraatr->lcxIndent - paraatr->lcxIndentRight) / LCXINDENT_STD;
  1882.     } else {
  1883.         if (text->tabsize) {
  1884.             return paraatr->lcxIndent / text->tabsize;
  1885.         }
  1886.     }
  1887.     return 0;
  1888. }
  1889.  
  1890. int TXAPI paraatrGetArticle(TX* text,PARAATR* paraatr)
  1891. {
  1892.     switch(paraatr->modeArticle) {
  1893.         case ARTICLE_AUTO: {
  1894.             int nest = paraatrGetNest(text,paraatr);
  1895.             if (nest <= 1) return ARTICLE_DISC;
  1896.             if (nest == 2) return ARTICLE_CIRCLE;
  1897.             if (nest == 3) return ARTICLE_SQUARE;
  1898.             break;
  1899.         }
  1900.         case ARTICLE_ALL: {
  1901.             return ARTICLE_DISC;
  1902.         }
  1903.     }
  1904.     return paraatr->modeArticle;
  1905. }
  1906.  
  1907. BOOL TXAPIBASE txInsertText(TX* text,TX* textInsert)
  1908. {
  1909. //1.97 カーソル位置にtextInsertを挿入する
  1910. #if 1//2.00E 長時間wzlockするには問題がある様で、高速/詳細モードのファイルを3つ以上プロジェクトなどで一斉に開くとハングアップした
  1911.     txSetUndisp(textInsert);
  1912.     txSelectAll(textInsert);
  1913.     txClipSelectCopy(textInsert,HCLIP_PRIVATE);
  1914.     txClipPaste(text,HCLIP_PRIVATE,TRUE,CLIP_CHAR);
  1915.     clipDeleteTop(HCLIP_PRIVATE);
  1916.     txSelectQuit(textInsert);
  1917.     txSetDisp(textInsert);
  1918.     return TRUE;
  1919. #else
  1920.     wzlock(LOCK_CLIPTS);
  1921.     txSetUndisp(textInsert);//1.99C 
  1922.     #if 1    // txSelectAllのバグが直った
  1923.     txSelectAll(textInsert);
  1924.     #else
  1925.     txSelectQuit(textInsert);
  1926.     txJumpFileTop(textInsert);
  1927.     txSelect(textInsert);
  1928.     txJumpFileEnd(textInsert);
  1929.     #endif
  1930.     txSelectTsPush(textInsert);
  1931.     txClipPaste(text,HCLIP_TS,TRUE,CLIP_CHAR);
  1932.     clipDeleteTop(HCLIP_TS);
  1933.     wzunlock(LOCK_CLIPTS);
  1934.     //
  1935.     txSelectQuit(textInsert);//1.99C 
  1936.     txSetDisp(textInsert);//1.99C 
  1937.     return TRUE;
  1938. #endif
  1939. }
  1940.  
  1941. BOOL TXAPIBASE txInsertTextSelect(TX* text,TX* textInsert)
  1942. {
  1943. // カーソル位置にtextInsertの範囲選択部分を挿入する
  1944. // textInsertが範囲選択されていないときはtxInsertTextと同じ
  1945. //2.00Bで追加
  1946.     if (textInsert->fClip) {
  1947. #if 1    //2.00E wzlockをしない
  1948.         txClipSelectCopy(textInsert,HCLIP_PRIVATE);
  1949.         txClipPaste(text,HCLIP_PRIVATE,TRUE,CLIP_CHAR);
  1950.         clipDeleteTop(HCLIP_PRIVATE);
  1951.         return TRUE;
  1952. #else
  1953.         wzlock(LOCK_CLIPTS);
  1954.         txSelectTsPush(textInsert);
  1955.         txClipPaste(text,HCLIP_TS,TRUE,CLIP_CHAR);
  1956.         clipDeleteTop(HCLIP_TS);
  1957.         wzunlock(LOCK_CLIPTS);
  1958.         return TRUE;
  1959. #endif
  1960.     } else {
  1961.         return txInsertText(text,textInsert);
  1962.     }
  1963. }
  1964.  
  1965. BOOL TXAPI TXCMD txTsPopJump(tx *text)
  1966. {
  1967. // テキストスタックからポップ
  1968. // カーソルを貼り付けしたデータの末尾の次の文字へ移動します
  1969. //2.00Bで追加
  1970.     BOOL ret = FALSE;
  1971.     wzlock(LOCK_CLIPTS);
  1972.     ret = txClipPaste(text,HCLIP_TS,TRUE,CLIP_CHAR);
  1973.     clipDeleteTop(HCLIP_TS);
  1974.     wzunlock(LOCK_CLIPTS);
  1975.     return ret;
  1976. }
  1977.  
  1978. //{###情報取得}
  1979.  
  1980. BOOL TXAPI paraatr2Read(TX* text,NLINE npara,PARAATR2* paraatr2)
  1981. {
  1982. //2.90 
  1983.     if (!text->txparaatr2) {
  1984.         memset(paraatr2,0,sizeof(PARAATR2));
  1985.         return TRUE;
  1986.     }
  1987.     return txRecordRead(text->txparaatr2,npara,paraatr2);
  1988. }
  1989.  
  1990. BOOL TXAPI paraatr2Write(TX* text,NLINE npara,PARAATR2* paraatr2)
  1991. {
  1992. //2.90 
  1993.     return txRecordWrite(text->txparaatr2,npara,paraatr2);
  1994. }
  1995.  
  1996. //1.90 WZ.EXE内で使えるようにした
  1997. int TXAPI TXHIGH txCmpCur(tx *text,mchar *szstr)
  1998. {
  1999. // カーソル位置が文字列szstrと等しいか返す
  2000. // 等しければszstrの長さ、等しくなければ0を返す
  2001. // 比較できない場合もある。この場合は0を返す
  2002.     int len = strlen(szstr);
  2003.     if (text->cur + len <= text->sizebuff) {//1.90 
  2004.         if (!memcmp(text->buff + text->cur,szstr,len)) return len;
  2005.     }
  2006.     return 0;
  2007. }
  2008.  
  2009. int TXAPI TXHIGH txCmpCurI(tx *text,mchar *szstr)
  2010. {
  2011. // カーソル位置が文字列szstrと等しいか返す
  2012. // 等しければszstrの長さ、等しくなければ0を返す
  2013. // 比較できない場合もある。この場合は0を返す
  2014. // 英大/小を区別しないで調べる
  2015. //2.92で追加
  2016.     int len = strlen(szstr);
  2017.     if (text->cur + len <= text->sizebuff) {//1.90 
  2018.         if (!strnicmp(text->buff + text->cur,szstr,len)) return len;
  2019.     }
  2020.     return 0;
  2021. }
  2022.  
  2023. int TXAPI TXHIGH txCmpCurLen(tx *text,mchar *szstr,int lch)
  2024. {
  2025. // カーソル位置が長さlchの文字列szstrと等しいか返す
  2026. // 等しければlch、等しくなければ0を返す
  2027. // 比較できない場合もある。この場合は0を返す
  2028. //1.95で追加
  2029.     if (text->cur + lch <= text->sizebuff) {//1.90 
  2030.         if (!memcmp(text->buff + text->cur,szstr,lch)) return lch;
  2031.     }
  2032.     return 0;
  2033. }
  2034.  
  2035. int TXAPI TXHIGH txCmpCurLenI(tx *text,mchar *szstr,int lch)
  2036. {
  2037. // カーソル位置が長さlchの文字列szstrと等しいか返す
  2038. // 等しければlch、等しくなければ0を返す
  2039. // 比較できない場合もある。この場合は0を返す
  2040. // 英大/小を区別しないで調べる
  2041. //2.92で追加
  2042.     if (text->cur + lch <= text->sizebuff) {//1.90 
  2043.         if (!strnicmp(text->buff + text->cur,szstr,lch)) return lch;
  2044.     }
  2045.     return 0;
  2046. }
  2047.  
  2048. //1.90 WZ.EXE内で使えるようにした
  2049. int TXAPI TXHIGH txCmpCurPrev(tx *text,mchar *szstr)
  2050. {
  2051. // カーソル位置の手前の文字列が文字列szstrと等しいか返す
  2052. // 等しければszstrの長さ、等しくなければ0を返す
  2053. // 比較できない場合もある。この場合は0を返す
  2054. //1.90 で追加
  2055.     int len = strlen(szstr);
  2056.     if (text->cur0 >= len) {
  2057.         if (!memcmp(text->buff + text->cur0 - len,szstr,len)) return len;
  2058.     }
  2059.     return 0;
  2060. }
  2061.  
  2062. //{###情報取得}
  2063.  
  2064. BOOL TXAPI txIsSwap1(tx *text)
  2065. {
  2066. // テキストバッファスワップ
  2067. // txSwap1でスワップするデータがあるか返す
  2068.     if (text->temp2 > 0 || !text->fReadAll) return TRUE;
  2069.     return FALSE;
  2070. }
  2071.  
  2072. BOOL TXAPI txIsSwap2(tx *text)
  2073. {
  2074. // テキストバッファスワップ
  2075. // txSwap2でスワップするデータがあるか返す
  2076.     if (text->temp1 > 0) return TRUE;
  2077.     return FALSE;
  2078. }
  2079.  
  2080. BOOL TXAPI txIsBinary(tx *text)
  2081. {
  2082. // テキストがバイナリファイルか調べる
  2083. // text->fOpenが真ならファイルの内容も調べ、
  2084. // コントロールコードが入っていたらTRUEを返す
  2085. // text->fOpenが偽ならファイルの拡張子を調べる
  2086.     #define BINCHECKSIZE    200
  2087.     long size = text->sizebuff - text->cur;
  2088.     mchar *p = text->buff + text->cur;
  2089.     // 開いた後だとファイル名でチェックしても遅い
  2090.     // 拡張子でチェック
  2091.     {
  2092.         mchar *szext = pathGetExt(text->szfilename);
  2093.         if (!stricmp(szext,".exe")) return TRUE;
  2094.         if (!stricmp(szext,".com")) return TRUE;
  2095.         if (!stricmp(szext,".bmp")) return TRUE;
  2096.         if (!stricmp(szext,".wri")) return TRUE;
  2097.         if (!stricmp(szext,".rec")) return TRUE;
  2098.         if (!stricmp(szext,".hlp")) return TRUE;
  2099.         if (!stricmp(szext,".ico")) return TRUE;
  2100.         if (!stricmp(szext,".lch")) return TRUE;
  2101.         if (!stricmp(szext,".tll")) return TRUE;
  2102.         if (!stricmp(szext,".txm")) return TRUE;//1.00C
  2103.         if (!stricmp(szext,".txe")) return TRUE;//1.00C
  2104.         if (!stricmp(szext,".3ll")) return TRUE;//1.00H3 
  2105.         if (!stricmp(szext,".3xm")) return TRUE;//1.00H3 
  2106.         if (!stricmp(szext,".3xe")) return TRUE;//1.00H3 
  2107.         if (!strnicmp(szext,".~",2)) return TRUE;   // TX-UNDO
  2108.     }
  2109.     if (text->fOpen) {
  2110.         // 開いてチェック
  2111.         if (size > BINCHECKSIZE) {
  2112.             size = BINCHECKSIZE;
  2113.         } else {
  2114.             p = text->buff;
  2115.             size = text->cur0;
  2116.             if (size > BINCHECKSIZE) size = BINCHECKSIZE;
  2117.         }
  2118. //printf("%u,%u\n",size,(p - text->buff));
  2119.         while(size > 0) {
  2120.             mchar c = *p++;
  2121.             size--;
  2122.             if (iskanji(c)) {
  2123.                 c = *p++;
  2124.                 size--;
  2125.                 if (!iskanji2(c)) return TRUE;
  2126.             } else if (
  2127.                 isspace(c) ||
  2128.                 c == 0x1B ||
  2129.                 ' ' <= c
  2130.             ) {
  2131.                 // OK
  2132.             } else {
  2133.                 return TRUE;
  2134.             }
  2135.         }
  2136.     }
  2137.     return FALSE;
  2138. }
  2139.  
  2140. BYTE TXAPI txGetCharW(tx *text,IBUFF off)
  2141. {
  2142. // off(text->cur0 <= off < text->sizebuff)の文字の幅(1or2)を返す
  2143. //2.00B GetCharW -> txGetCharWに名称変更
  2144.     mchar c = text->buff[off];
  2145.     if (!text->buff) return 0;
  2146.     if (text->fBinedit) return 1;
  2147.     if (iskanji(c) && !text->fCurWestern) return 2;
  2148.     return 1;
  2149. }
  2150.  
  2151. BYTE TXAPI TXHIGH txGetCharSize(tx *text,IBUFF off)
  2152. {
  2153. // offの文字のバイト数を返す
  2154. // EOFなら0を返す
  2155. //2.00B GetCharSize -> txGetCharSizeに名称変更
  2156.     if (!text->buff) return 0;
  2157.     {
  2158.         mchar c = text->buff[off];
  2159.         
  2160.         if (c == 0x1A && off + 1 == text->sizebuff && !txIsSwap1(text)) {
  2161.             // EOF
  2162.             return 0;
  2163.         } else {
  2164.             if (text->fBinedit) return 1;
  2165.             if (
  2166.                 (iskanji(c) && !text->fCurWestern) ||
  2167.                 (c == 0x0D && text->buff[off + 1] == 0x0A)
  2168.             ) {
  2169.                 if (off + 1 < text->sizebuff) {
  2170.                     return 2;
  2171.                 }
  2172.             }
  2173.             return 1;
  2174.         }
  2175.     }
  2176. }
  2177.  
  2178. BOOL TXAPI txGetFreeCursor(TX* text)
  2179. {
  2180. // フリーカーソルがONかどうか返します
  2181. //2.00Eで追加
  2182.     return (text->modeFreeCursor == 1 && !text->fBinedit);
  2183. }
  2184.  
  2185. BOOL TXAPIBASE TXHIGH_THROUGH txIsCurFree(tx *text)
  2186. {
  2187. // カーソルがフリー領域内にあるかどうか返します。
  2188. //1.00H4 仕様変更。以前は、フリーカーソルが"off","VZ"のときは必ずFALSEを返して
  2189. // いましたが、カーソルがtxJumpLineTailした状態にあるときはTRUEを返します。
  2190.     if (text->fHigh) return FALSE;//1.00B 行末でhelpをtxAnkToJankするとhelppになっていた
  2191. #if 1//1.00H4 フリーカーソルオフで、折り返しのある表示でtxJumpLineTailしてtxRightWordするとおかしくなった
  2192.     if (text->cur0 - text->cury == text->curysize) return TRUE;
  2193.     if (!txGetFreeCursor(text)) return FALSE;
  2194. #else
  2195.     if (!txGetFreeCursor(text)) return FALSE;
  2196.     if (text->cur0 - text->cury == text->curysize) return TRUE;
  2197. #endif
  2198.     {
  2199.         int size = txGetCharSize(text,text->cur);
  2200.         if (size == 0 || text->cur0 - text->cury + size == text->curysize) {
  2201.             if (text->lfEditProp) {//1.91A lfProp->lfEditProp
  2202.                 //1.01A プロポーショナル時のフリーカーソル判別が間違っていた
  2203.                 int xtail = txGetXLineTail(text);
  2204.                 if (text->x >= xtail) return TRUE;
  2205.             } else {
  2206.                 //1.00C EOF行のフリーカーソル動作改善
  2207.                 int lxtail = txGetLxLineTail(text);
  2208.                 if (text->lx >= lxtail) return TRUE;
  2209.             }
  2210.         }
  2211.     }
  2212.     return FALSE;
  2213. }
  2214.  
  2215. //{###編集}
  2216.  
  2217. //1.90 
  2218. // text->lfEditPropが真なら必ずNULL以外の値を返す。
  2219. // そうでなければNULLを返すこともある
  2220. LPBYTE TXAPI txGetTcxcharStd(tx* text)
  2221. {
  2222.     if (text->editmode == 2) {
  2223.         return text->tfonttx[FONTTX_BODY].tcxChar;
  2224.     } else {
  2225.         return text->tfonttx[FONTTX_TEXT].tcxChar;
  2226.     }
  2227. }
  2228.  
  2229. int TXAPI txGetIfonttxStd(TX* text)
  2230. {
  2231. //2.99D 970329 new
  2232.     if (text->editmode == 2) {
  2233.         return FONTTX_BODY;
  2234.     } else {
  2235.         return FONTTX_TEXT;
  2236.     }
  2237. }
  2238.  
  2239. FONTTX* TXAPI txGetFonttxStd(tx* text)
  2240. {
  2241.     if (!text->tfonttx) return NULL;
  2242.     if (text->editmode == 2) {
  2243.         return &text->tfonttx[FONTTX_BODY];
  2244.     } else {
  2245.         return &text->tfonttx[FONTTX_TEXT];
  2246.     }
  2247. }
  2248.  
  2249. int TXAPI TXHIGH_THROUGH txInsertSpaceFreeCursor(tx *text)
  2250. {
  2251. // 表示行末以降、カーソル位置までスペース挿入
  2252.     if (text->fHigh) return FALSE;//1.99D 
  2253.     if (txIsCurFree(text)) {//1.00C EOF行のフリーカーソル動作改善
  2254.         int len;
  2255.         mchar buff[CCHLINE];
  2256.         
  2257.         if (text->lfEditProp) {
  2258.             //1.00H6 
  2259.             int xTail = txGetXLineTail(text);
  2260.             LPBYTE tcxChar = txGetTcxcharStd(text);
  2261.             if (!tcxChar) return FALSE;//1.97
  2262.             len = (text->x - xTail) / tcxChar[0x20];
  2263.             if (len == 0 && txIsCurEof(text)) {
  2264.                 //EOF上で文字挿入すると半角スペースも一つ入っちゃう
  2265.                 return FALSE;
  2266.             }
  2267.         } else {
  2268.             int lxtail = txGetLxLineTail(text);
  2269.             len = text->lx - lxtail;
  2270.         }
  2271.         if (txIsLineReturn(text)) {
  2272.             //1.00H3
  2273.             text->fNomoveBase++;
  2274.             text->fUndispCursor++;
  2275.             txJumpLineEnd(text);
  2276.             text->fNomoveBase--;
  2277.             text->fUndispCursor--;
  2278.             len++;
  2279.             if (len >= 0) {
  2280.                 memset(buff,' ',len);
  2281.                 buff[len] = 0;
  2282.                 txInsert(text,buff);
  2283.             }
  2284.             return len;
  2285.         } else {
  2286. #if 1    //1.00F 右方向キーを押し続けてフリー域に入って文字を挿入すると、
  2287.         //行末文字の前に挿入されてしまっていた。行末に入るようにした。
  2288.             if (text->cur0 - text->cury < text->curysize) {
  2289.                 txRight(text);
  2290.                 return TRUE;
  2291.             }
  2292.             return FALSE;
  2293. #else
  2294.             if (len >= 0) {
  2295.                 memset(buff,' ',len);
  2296.                 buff[len] = 0;
  2297.                 txInsert(text,buff);
  2298.             }
  2299. #endif
  2300.         }
  2301.     }
  2302.     return 0;
  2303. }
  2304.  
  2305. //{###情報取得}
  2306.  
  2307. BOOL TXAPIBASE txIsLineLf(tx *text)
  2308. {
  2309. // カーソル位置の表示行が改行で終わっているかどうか返します。
  2310. // txIsLineReturnと異なりEOF行の場合はFALSEを返します。
  2311. //{#RET}CR+LF・LFなら真、そうでなければ偽を返します
  2312. //1.00Dで追加
  2313.     if (text->fHigh) return FALSE;//1.99D 
  2314.     {
  2315.         int len = text->curysize - (text->cur0 - text->cury);
  2316.         
  2317.         if (len > 0) {
  2318.             mchar c = text->buff[text->cur + len - 1];
  2319.             if (c == 0x0A) return TRUE;
  2320.             return FALSE;
  2321.         }
  2322.         if (text->curysize > 0) {
  2323.             mchar c = text->buff[text->cur0 - 1];
  2324.             if (c == 0x0A) return TRUE;
  2325.             return FALSE;
  2326.         }
  2327.         return FALSE;
  2328.     }
  2329. }
  2330.  
  2331. BOOL TXAPIBASE txIsClipInPara(tx *text)
  2332. {
  2333. // 論理行一行内の範囲選択中ならTRUEを返す
  2334.     if (
  2335.         text->fClip == CLIP_CHAR ||
  2336.         text->fClip == CLIP_WORD ||
  2337.         text->fClip == CLIP_LINE ||
  2338.         text->fClip == CLIP_PARA
  2339.     ) { //1.00E 以前はif(text->fClip)で判定してたが、CLIP_ALLのとき誤動作する
  2340. #if 1//1.99E CLIP_PARAの時に変だったので全面変更
  2341.         if (text->fBinedit) {
  2342.             //2.00E バイナリ編集時は選択範囲が16バイト以下ならTRUEを返す
  2343.             return (txGetAddressSelectEnd(text) - txGetAddressSelectTop(text) <= 16);
  2344.         } else {
  2345.             IFILE paratop = txGetParaTop(text);
  2346.             IFILE paraend = txGetParaEnd(text);
  2347.             txFlushSelectNow(text);
  2348.             {
  2349.                 IFILE cliptop = text->cliptopnow;
  2350.                 IFILE clipend = text->clipendnow;
  2351.                 if (cliptop > clipend) {
  2352.                     cliptop = text->clipendnow;
  2353.                     clipend = text->cliptopnow;
  2354.                 }
  2355.                 return (paratop <= cliptop && clipend <= paraend);
  2356.             }
  2357.         }
  2358. #else
  2359.         IFILE paratail = text->cliptopparatail;
  2360.         //1.99A EOF行でFALSEを返していて、txGetWordなどに影響していた
  2361.         // cliptopparatailは次の段落の先頭を差すが、EOF行では段落末を差すため
  2362.         if (paratail == txGetTextSize(text)) {
  2363.             paratail++;
  2364.         }
  2365.         //
  2366.         if (text->cliptoppara <= text->temp1 + text->cur0 && text->temp1 + text->cur0 < paratail) {//1.00F
  2367.             return TRUE;
  2368.         }
  2369.         //1.00C SelectVzで文字選択モードから行選択モードに移る際、カーソルがフリーカーソル域にあるとおかしかった
  2370.         if (txIsCurFree(text) && text->temp1 + text->cur0 < paratail) return TRUE;//1.00F
  2371. #endif
  2372.     }
  2373.     return FALSE;
  2374. }
  2375.  
  2376. int TXAPI GetSystemFontNo(void)
  2377. {
  2378. // 定義済みのシステムフォントの番号を返す
  2379. //2.00Eで追加
  2380.     if (_fwin40/* && _platform == WINDOWS95 2.98A */) {
  2381. #ifdef __FLAT__
  2382.         return DEFAULT_GUI_FONT;
  2383. #endif
  2384.     }
  2385.     return SYSTEM_FONT;
  2386. }
  2387.  
  2388. //{###検索・置換}
  2389.  
  2390. BOOL TXAPI TXHIGH txSearchPara(tx *text,mchar *szfind)
  2391. {
  2392. // カーソル行も検索範囲に含めて行単位の検索をします
  2393. // 行の頭がszfindと一致したら、カーソルを行頭にセットしてTRUEを返します
  2394. // 次候補を検索するには、txNextParaしてから呼び出して下さい
  2395. // 大文字小文字区別あり、全角半角区別ありで検索します。
  2396. #if 1//1.92
  2397.     return txSearchEx(text,szfind,SEARCH_NOESC|SEARCH_CUR|SEARCH_PARATOP);
  2398. #else
  2399.     static searcharg arg;
  2400.     {
  2401.         static BOOL finit;
  2402.         if (!finit) {
  2403.             finit = TRUE;
  2404.             arg.sizeStruct = sizeof(arg);
  2405.             arg.fSearchSenseCase = TRUE;
  2406.             arg.fSearchSenseZenhan = TRUE;
  2407.             arg.fSearchEscapeNo = TRUE;
  2408.             arg.fSearchCur = TRUE;
  2409.         }
  2410.     }
  2411.     
  2412.     txJumpParaTop(text);
  2413.     #if 1
  2414.     arg.szFind = szfind;
  2415.     while(1) {
  2416.         if (!txSearchArg(text,&arg)) return FALSE;
  2417.         if (txGetParaTop(text) == txGetAddress(text)) return TRUE;
  2418.         if (!txNextPara(text)) return FALSE;
  2419.     }
  2420.     #else
  2421.     while(1) {
  2422.         if (!strncmp(text->buff + text->cur,szfind,len)) return TRUE;
  2423.         if (!txNextPara(text)) return FALSE;
  2424.     }
  2425.     #endif
  2426. #endif
  2427. }
  2428.  
  2429. //{###時間}
  2430. //現在時間を調べたりする機能を提供します。
  2431.  
  2432. void TXAPIBASE wait(DWORD ms)
  2433. {
  2434. // msミリ秒何もしません。
  2435.     DWORD tm0 = GetCurrentTime();
  2436.     while(GetCurrentTime() - tm0 < ms);
  2437. }
  2438.  
  2439. #ifdef __TXC__
  2440.  
  2441. //##time.c
  2442.  
  2443. DWORD TXAPI wtmGetNow(void)
  2444. {
  2445. // Windows時間を返す
  2446.     return GetCurrentTime();
  2447. }
  2448.  
  2449. void TXAPI itimeGetNow(TIME *time)
  2450. {
  2451. // 現在時刻をtimeに得る
  2452. //1.00Cで追加
  2453.     timeGet(time);
  2454. }
  2455.  
  2456. void TXAPI itimeToTm(TIME *time,TM *tm)
  2457. {
  2458. // time(整数)をtm(年月日時分秒)に変換する
  2459. //1.00Cで追加
  2460.     timeGetLocal(tm,time);
  2461. }
  2462.  
  2463. void TXAPI itimeFromTm(TIME *time,TM *tm)
  2464. {
  2465. // tm(年月日時分秒)をtime(整数)に変換する
  2466. //1.00Cで追加
  2467.     TIME timeWork = -1;
  2468.     timeGetLocal(tm,&timeWork);
  2469.     *time = timeWork;
  2470. }
  2471.  
  2472. TIME _time;
  2473. TM _tm;
  2474.  
  2475. static void time()
  2476. {
  2477.     timeGet(&_time);
  2478.     timeGetLocal(&_tm,&_time);
  2479. }
  2480.  
  2481. int TXAPIBASE timeGetYear(void)
  2482. {
  2483. // 年を返す
  2484.     time();
  2485.     return _tm.tm_year;
  2486. }
  2487.  
  2488. int TXAPIBASE timeGetMonth(void)
  2489. {
  2490. // 月を返す
  2491.     time();
  2492.     return _tm.tm_mon+1;
  2493. }
  2494.  
  2495. int TXAPIBASE timeGetDay(void)
  2496. {
  2497. // 日を返す
  2498.     time();
  2499.     return _tm.tm_mday;
  2500. }
  2501.  
  2502. int TXAPIBASE timeGetDayofweek(void)
  2503. {
  2504. // 曜日を返す(日曜が0)
  2505.     time();
  2506.     return _tm.tm_wday;
  2507. }
  2508.  
  2509. mchar TXAPIBASE *timeGetYoubi(void)
  2510. {
  2511. // 文字列で曜日を返す(日曜が"日")
  2512.     static mchar *szwday[] = {"日","月","火","水","木","金","土",};
  2513.     return szwday[timeGetDayofweek()];
  2514. }
  2515.  
  2516. int TXAPIBASE timeGetHour(void)
  2517. {
  2518. // 時を返す
  2519.     time();
  2520.     return _tm.tm_hour;
  2521. }
  2522.  
  2523. int TXAPIBASE timeGetMinute(void)
  2524. {
  2525. // 分を返す
  2526.     time();
  2527.     return _tm.tm_min;
  2528. }
  2529.  
  2530. int TXAPIBASE timeGetSecond(void)
  2531. {
  2532. // 秒を返す
  2533.     time();
  2534.     return _tm.tm_sec;
  2535. }
  2536.  
  2537. //##beep.c
  2538. //{###音}
  2539. //ビープ音を鳴らします。
  2540.  
  2541. void TXAPIBASE beep(void)
  2542. {
  2543. // 標準ビープサウンドを再生します
  2544. #if 1
  2545.     //2.90 音が鳴らないPCがある
  2546.     MessageBeep(MB_OK);
  2547. #else
  2548.     MessageBeep(-1);
  2549. #endif
  2550. }
  2551.  
  2552. void TXAPI beepAsterisk(void)
  2553. {
  2554. // アスタリスクビープサウンドを再生します
  2555.     MessageBeep(MB_ICONASTERISK);
  2556. }
  2557.  
  2558. void TXAPI beepExclamation(void)
  2559. {
  2560. // 絶叫ビープサウンドを再生します
  2561.     MessageBeep(MB_ICONEXCLAMATION);
  2562. }
  2563.  
  2564. void TXAPI beepHand(void)
  2565. {
  2566. // HANDビープサウンドを再生します
  2567.     MessageBeep(MB_ICONHAND);
  2568. }
  2569.  
  2570. void TXAPI beepQuestion(void)
  2571. {
  2572. // ?ビープサウンドを再生します
  2573.     MessageBeep(MB_ICONQUESTION);
  2574. }
  2575.  
  2576. void TXAPI beepDefault(void)
  2577. {
  2578. // デフォルトのビープサウンドを再生します
  2579.     MessageBeep(MB_OK);
  2580. }
  2581.  
  2582. //##dat.c
  2583. //{###ファイル操作}
  2584.  
  2585. #export
  2586.  
  2587. #ifdef __FLAT__//1.00F datReadNumI etc追加
  2588.     #define datReadNumI            datReadNum
  2589.     #define datWriteNumI        datWriteNum
  2590. #else
  2591.     #define datReadNumI            datReadNumW
  2592.     #define datWriteNumI        datWriteNumW
  2593. #endif
  2594.  
  2595. #endexport
  2596.  
  2597. BOOL TXAPI fileWriteStr(HFILE hf,mchar *sz)
  2598. {
  2599.     int len = strlen(sz);
  2600.     
  2601.     return (_lwrite(hf,sz,len) == len);
  2602. }
  2603.  
  2604. BOOL TXAPI fileWriteNum(HFILE hf,int num)
  2605. {
  2606.     mchar buff[20];
  2607.     int len;
  2608.     
  2609.     sprintf(buff,"%d",num);
  2610.     len = strlen(buff);
  2611.     return (_lwrite(hf,buff,len) == len);
  2612. }
  2613.  
  2614. BOOL TXAPI datReadNum(mchar *szRecord,mchar *szName,int *num)
  2615. {
  2616.     #include "dat.ci"
  2617. }
  2618.  
  2619. BOOL TXAPI datReadNumW(mchar *szRecord,mchar *szName,WORD *num)
  2620. {
  2621.     #include "dat.ci"
  2622. }
  2623.  
  2624. BOOL TXAPI datReadNumB(mchar *szRecord,mchar *szName,BYTE *num)
  2625. {
  2626.     #include "dat.ci"
  2627. }
  2628.  
  2629. // szDst:mchar[CCHPATHNAME]
  2630. BOOL TXAPI datRead(mchar *szRecord,mchar *szName,mchar *szDst)
  2631. {
  2632.     mchar *p = szRecord;
  2633.     int len = strlen(szName);
  2634.     
  2635.     if (!memcmp(p,szName,len) && p[len] == '=') {
  2636.         p += len + 1;
  2637.         while(1) {
  2638.             if (*p < ' ') {
  2639.                 *szDst = 0;
  2640.                 break;
  2641.             }
  2642.             *szDst++ = *p++;
  2643.         }
  2644.         return TRUE;
  2645.     }
  2646.     return FALSE;
  2647. }
  2648.  
  2649. void TXAPI datWrite(HFILE hf,mchar *szName,mchar *szData)
  2650. {
  2651.     if (szName[0] == '[' && szData == NULL) {
  2652.         fileWriteStr(hf,szName);
  2653.     } else {
  2654.         fileWriteStr(hf,szName);
  2655.         _lwrite(hf,"=",1);
  2656.         fileWriteStr(hf,szData);
  2657.     }
  2658.     fileWriteStr(hf,"\n");
  2659. }
  2660.  
  2661. void TXAPI datWriteNum(HFILE hf,mchar *szName,int data)
  2662. {
  2663.     mchar buff[20];
  2664.     
  2665.     fileWriteStr(hf,szName);
  2666.     sprintf(buff,"=%d\n",data);
  2667.     fileWriteStr(hf,buff);
  2668. }
  2669.  
  2670. //
  2671. //    for C program
  2672. //
  2673.  
  2674. void TXAPI datWriteNumC(HFILE hf,mchar *szName,int data)
  2675. {
  2676.     mchar buff[20];
  2677.     
  2678.     fileWriteStr(hf,szName);
  2679.     sprintf(buff," = %d;\n",data);
  2680.     fileWriteStr(hf,buff);
  2681. }
  2682.  
  2683. void TXAPI datWriteStrC(HFILE hf,mchar *szName,mchar *szData)
  2684. {
  2685.     mchar buff[250];
  2686.     
  2687.     sprintf(buff,"strcpy(%s,\\\"%s\");\n",szName,szData);
  2688.     _lwrite(hf,buff,strlen(buff));
  2689. }
  2690.  
  2691. #endif// __TXC__
  2692.  
  2693. #endif// __NOTX__
  2694.  
  2695. //##str.c
  2696. //{###文字列操作}
  2697.  
  2698. mchar * TXAPIBASE strGetWordTop(mchar *szStr)
  2699. {
  2700. // 文字列szStrの先頭部分のスペース・タブをスキップし、
  2701. // その次の文字のポインタを返します
  2702. // スキップ中にNULL文字が現れたら、NULL文字へのポインタを返します
  2703.     while(*szStr == '\t' || *szStr == ' ') szStr++;
  2704.     return szStr;
  2705. }
  2706.  
  2707. int TXAPIBASE strGetWordLen(mchar *szStr)
  2708. {
  2709. // 文字列szStrのスペース・タブまでの文字列のバイト数を返します
  2710. // ""内、0x0C-0x0C内のデリミタは無視する
  2711. //2.00Eから、()内,[]内のデリミタは無視しない
  2712.     mchar *p = szStr;
  2713.     BOOL fdq = FALSE;
  2714.     BOOL fff = FALSE;
  2715.     int nBrace = 0;
  2716.     int len = 0;
  2717.     
  2718.     while(1) {
  2719.         mchar c = p[len];
  2720.         
  2721.         if (iskanji(c)) {//1.00B '['や']'が漢字2バイト目にマッチすることがある
  2722.             if (p[len + 1]) {
  2723.                 len += 2;
  2724.             } else {
  2725.                 break;
  2726.             }
  2727. #if 1//1.00F ""内、0x0C..0x0C内のデリミタも無視する
  2728.         } else if (c == '"') {
  2729.             fdq ^= 1;
  2730.             len++;
  2731.         } else if (c == 0x0C) {
  2732.             fff ^= 1;
  2733.             len++;
  2734. #endif
  2735. #if 0//2.00E5 // ファイル名に閉じていない()や[]が使えなかった
  2736.         } else if (c == '(' || c == '[') {
  2737.             nBrace++;
  2738.             len++;
  2739.         } else if (c == ')' || c == ']') {
  2740.             nBrace--;
  2741.             len++;
  2742. #endif
  2743.         } else if (c == '\t' || c == ' ') {
  2744.             if (nBrace || fdq || fff) {
  2745.                 len++;
  2746.             } else {
  2747.                 break;
  2748.             }
  2749.         } else if (c < ' ') {
  2750.             break;
  2751.         } else {
  2752.             len++;
  2753.         }
  2754.     }
  2755.     return len;
  2756. }
  2757.  
  2758. int TXAPI strGetLineLen(mchar *szStr)
  2759. {
  2760. // 文字列szStrの改行までの文字列のバイト数を返します
  2761.     mchar *p = szStr;
  2762.     int len = 0;
  2763.     
  2764.     while(1) {
  2765.         mchar c = p[len];
  2766.         
  2767.         if (c == 0x0D || c == 0x0A || c == 0) {
  2768.             break;
  2769.         } else {
  2770.             len++;
  2771.         }
  2772.     }
  2773.     return len;
  2774. }
  2775.  
  2776. mchar * TXAPI strGetWord(mchar szbuff[CCHPATHNAME],mchar *szstr)
  2777. {
  2778. // strGetWordLen(strGetWordTop(szStr))して、結果をszbuffにコピーします
  2779. // szbuffに入りきらなければ、szbuff[0] = 0とします
  2780. // szStrの次の語を指すポインタを返します(先頭にスペースがついています)
  2781.     mchar* top = strGetWordTop(szstr);
  2782.     int len = strGetWordLen(top);
  2783.     if (len >= CCHPATHNAME) {
  2784.         szbuff[0] = 0;
  2785.     } else {
  2786.         memcpy(szbuff,top,len);
  2787.         szbuff[len] = 0;
  2788.     }
  2789.     return top + len;
  2790. }
  2791.  
  2792.  
  2793. int TXAPI strNum(mchar *p,int *num)
  2794. {
  2795. // 文字列pの先頭が数字列なら、数値に変換して*numに代入します
  2796. // 変換した文字数を返します。
  2797. // 変換しなかった場合は、*numに0を代入します
  2798.     int len = 0;
  2799.     
  2800.     *num = 0;
  2801.     while(1) {
  2802.         mchar c = p[len];
  2803.         
  2804.         if (isdigit(c)) {
  2805.             *num *= 10;
  2806.             *num += c - '0';
  2807.             len++;
  2808.         } else {
  2809.             return len;
  2810.         }
  2811.     }
  2812. }
  2813.  
  2814. mchar * TXAPI strGetLast(mchar *szstr)
  2815. {
  2816. // 文字列szstrの最後の文字へのポインタを返す
  2817. // szstrが0なら、0を返す
  2818. // szstrが""なら、""へのポインタを返す
  2819.     mchar *p = szstr;
  2820.     mchar *p0 = p;
  2821.     mchar c;
  2822.     
  2823.     if (!p) return NULL;
  2824.     while(c = *p) {
  2825.         p0 = p;
  2826.         if (iskanji(c)) {
  2827.             p += 2;
  2828.         } else {
  2829.             p++;
  2830.         }
  2831.     }
  2832.     return p0;
  2833. }
  2834.  
  2835. int TXAPI strGetCharSize(mchar *szstr)
  2836. {
  2837. // szstr位置の文字のバイト数を返します
  2838. // 文字が0(ヌル文字)なら、0、漢字なら2、それ以外は1を返します
  2839.     if (iskanji(szstr[0]) && szstr[1]) return 2;
  2840.     if (szstr[0]) return 1;
  2841.     return 0;
  2842. }
  2843.  
  2844. int TXAPI _hextoint(int c)
  2845. {
  2846.     if (isdigit(c)) {
  2847.         return c - '0';
  2848.     } else if ('A' <= c && c <= 'F') {
  2849.         return c - 'A' + 10;
  2850.     } else if ('a' <= c && c <= 'f') {
  2851.         return c - 'a' + 10;
  2852.     }
  2853.     return 0;
  2854. }
  2855.  
  2856. // 16進2桁をintに変換。szhexが2桁ない場合は-1を返す
  2857. //1.00C 検索/置換/タイトル文字列で、「\x16進数2桁」で制御文字を指定できるようにした
  2858. int TXAPI hextoint(mchar *szhex)
  2859. {
  2860.     if (szhex[0] && szhex[1]) {
  2861.         return _hextoint(szhex[0]) * 16 + _hextoint(szhex[1]);
  2862.     }
  2863.     return -1;
  2864. }
  2865.  
  2866. mchar * TXAPI strfromesc(mchar *szstr)
  2867. {
  2868. // szstr内の\によるエスケープ文字を通常文字に変換します。
  2869. // '\s'->' '、'\t'->タブ、'\n'->改行、'\X'->Xに変換します。
  2870. //1.92 '\xXX'->16進データに変換します。
  2871. // szstrを返します
  2872.     mchar *src = szstr;
  2873.     mchar *dst = szstr;
  2874.     int c;
  2875.     
  2876.     while(c = *src++) {
  2877.         if (iskanji(c)) {
  2878.             *dst++ = c;
  2879.             *dst++ = *src++;
  2880.         } else if (c == '\\') {
  2881.             c = *src++;
  2882.             if (c == 's') {
  2883.                 *dst++ = ' ';
  2884.             } else if (c == 't') {
  2885.                 *dst++ = '\t';
  2886.             } else if (c == 'n') {
  2887.                 *dst++ = 0x0D;
  2888.                 *dst++ = 0x0A;
  2889.             } else if (c == 'x' || c == 'X') {
  2890.                 int d = hextoint(src);
  2891.                 if (d == -1) break;
  2892.                 *dst++ = d;
  2893.                 src += 2;
  2894.             } else {
  2895.                 *dst++ = c;
  2896.             }
  2897.         } else {
  2898.             *dst++ = c;
  2899.         }
  2900.     }
  2901.     *dst = 0;
  2902.     return szstr;
  2903. }
  2904.  
  2905. static int inttohex(int c)
  2906. {
  2907.     if (c >= 10) return c - 10 + 'A';
  2908.     return c + '0';
  2909. }
  2910.  
  2911. mchar * TXAPI strtoesc(mchar *szstr)
  2912. {
  2913. // スペースなどを\によるエスケープ文字に変換します
  2914. // ' '->'\s'、タブ->'\t'、改行(CR+LF)->'\n'に変換します。
  2915. //1.92 "0x01" - "0x1F"は"\x01" - "\x1F"に変換します。
  2916. //3.00B1 970612 "\"は"\\"に変換します。
  2917. // szstrを返します
  2918. // 文字列の長さが長くなりますので、szstrのバッファサイズは十分な大きさをとって下さい
  2919.     mchar *src = szstr;
  2920.     mchar szbuff[CCHLINE];
  2921.     mchar *dst = szbuff;
  2922.     int c;
  2923.     
  2924.     while(c = *src++) {
  2925.         if (iskanji(c)) {
  2926.             *dst++ = c;
  2927.             *dst++ = *src++;
  2928.         } else if (c == '\\') {//3.00B1 970612 
  2929.             *dst++ = '\\';
  2930.             *dst++ = '\\';
  2931.         } else if (c == ' ') {
  2932.             *dst++ = '\\';
  2933.             *dst++ = 's';
  2934.         } else if (c == '\t') {
  2935.             *dst++ = '\\';
  2936.             *dst++ = 't';
  2937.         } else if (c == 0x0D && *src == 0x0D) {
  2938.             *dst++ = '\\';
  2939.             *dst++ = 'n';
  2940.             src++;
  2941.         } else if (c < 0x20) {
  2942.             *dst++ = '\\';
  2943.             *dst++ = 'x';
  2944.             *dst++ = inttohex(c / 16);
  2945.             *dst++ = inttohex(c & 0x0F);
  2946.         } else {
  2947.             *dst++ = c;
  2948.         }
  2949.     }
  2950.     *dst = 0;
  2951.     strcpy(szstr,szbuff);
  2952.     return szstr;
  2953. }
  2954.  
  2955. int TXAPI formstrex(mchar *str,BOOL fCurWestern)
  2956. {
  2957. //文字列strの終わりが漢字第1バイトやCR+LFの第1バイトで切れていたら、それを削除する
  2958. //fCurWesternがTRUEなら、漢字は英字2文字として扱います。
  2959. //調整後の文字列の長さを返す
  2960. //2.00Bで追加
  2961.     mchar *p = str;
  2962.     
  2963.     while(1) {
  2964.         if (iskanji(*p) && !fCurWestern) {
  2965.             if (p[1]) {
  2966.                 p += 2;
  2967.             } else {
  2968.                 *p = 0;
  2969.                 break;
  2970.             }
  2971.         } else if (*p == 0x0D) {
  2972.             if (p[1] == 0x0A) {
  2973.                 p += 2;
  2974.             } else {
  2975.                 *p = 0;
  2976.                 break;
  2977.             }
  2978.         } else if (*p) {
  2979.             p++;
  2980.         } else {
  2981.             break;
  2982.         }
  2983.     }
  2984.     return p - str;
  2985. }
  2986.  
  2987. int TXAPI formstr(mchar *str)
  2988. {
  2989. //文字列strの終わりが漢字第1バイトやCR+LFの第1バイトで切れていたら、それを削除する
  2990. //調整後の文字列の長さを返す
  2991. //1.00Cで追加 txGetWordなどでバッファがあふれて、改行コードや漢字が途中で切れることがあったのを修正
  2992. //1.97 TX-Cのライブラリにも追加
  2993.     return formstrex(str,FALSE);
  2994. }
  2995.  
  2996. static UINT formchar2(mchar* str,UINT off)
  2997. {
  2998.     while (off--) {
  2999.         if (str[off] < 0x40) return off;
  3000.     }
  3001.     return 0;
  3002. }
  3003.  
  3004. UINT TXAPI formchar(mchar *str,UINT offset)
  3005. {
  3006. // 文字列topのオフセットoffsetが文字の第1バイトであるかどうかを調べます
  3007. // 第1バイトであればoffsetをそのまま返します
  3008. // そうでなければoffset未満でoffsetに最も近い文字の第1バイトのオフセットを返します
  3009. //2.00Bで追加
  3010.     if (offset) {
  3011.         UINT off,off0;
  3012.         
  3013. #if 1//1.00F2 formchar 高速化
  3014.         off = formchar2(str,offset);
  3015. #else
  3016.         off = 0;
  3017. #endif
  3018.         while(1) {
  3019.             mchar c = str[off];
  3020.             
  3021.             off0 = off;
  3022.             
  3023.             if (iskanji(c)) {
  3024.                 off++;
  3025.                 if (iskanji2(str[off])) {
  3026.                     off++;
  3027.                 }
  3028.             } else if (c == 0x0D) {
  3029.                 off++;
  3030.                 if (str[off] == 0x0A) {
  3031.                     off++;
  3032.                 }
  3033.             } else {
  3034.                 off++;
  3035.             }
  3036.             
  3037.             if (off > offset) {
  3038.                 return off0;
  3039.             }
  3040.         }
  3041.     } else {
  3042.         return 0;
  3043.     }
  3044. }
  3045.  
  3046. mchar * TXAPI strcpymax(mchar *szdst,mchar *szsrc,int lchmax)
  3047. {
  3048. // szdstにszstrを最大lchmax-1文字コピーする
  3049. // コピー後、szdstの末尾にヌルターミネータを追加する
  3050. // szdstを返す
  3051.     int lch = strlen(szsrc);
  3052.     if (lch >= lchmax) {
  3053.         lch = lchmax - 1;
  3054.         memcpy(szdst,szsrc,lch);
  3055.         szdst[lch] = 0;
  3056.         formstr(szdst);//1.97 
  3057.     } else {
  3058.         memcpy(szdst,szsrc,lch);
  3059.         szdst[lch] = 0;
  3060.     }
  3061.     return szdst;
  3062. }
  3063.  
  3064. int TXAPI strmatchplain(mchar *szstr,mchar *szid)
  3065. {
  3066. // szstrの先頭がszidならszidの長さ、そうでなければ0を返す
  3067. // szidの\も特別扱いせずに比較
  3068. //3.00B1 970612 new
  3069.     int lch = strlen(szid);
  3070.     if (!strncmp(szstr,szid,lch)) return lch;
  3071.     return 0;
  3072. }
  3073.  
  3074. int TXAPI strimatchplain(mchar *szstr,mchar *szid)
  3075. {
  3076. // szstrの先頭がszidならszidの長さ、そうでなければ0を返す
  3077. // szidの\も特別扱いせずに比較
  3078. // 大小文字は区別しないで比較
  3079. //3.00B1 970612 new
  3080.     int lch = strlen(szid);
  3081.     if (!strnicmp(szstr,szid,lch)) return lch;
  3082.     return 0;
  3083. }
  3084.  
  3085. int TXAPI strmatch(mchar *szstr,mchar *szid)
  3086. {
  3087. // szstrの先頭がszidならszidの長さ、そうでなければ0を返す
  3088. // szidの\tはタブ、\sは空白、\xはxとして比較
  3089. // マッチしたszstrの長さを返す
  3090.     int len = 0;
  3091.     while(1) {
  3092.         mchar c1 = *szstr++;
  3093.         mchar c2 = *szid++;
  3094.         
  3095.         if (c2 == 0) return len;
  3096.         if (c1 == 0) return 0;
  3097.         if (c2 == '\\') {
  3098.             c2 = *szid++;
  3099.             if (
  3100.                 (c1 == c2) ||
  3101.                 (c1 == '\t' && c2 == 't') ||
  3102.                 (c1 == ' ' && c2 == 's')
  3103.             ) {
  3104.                 // OK
  3105.             } else {
  3106.                 return 0;
  3107.             }
  3108.         } else if (c1 != c2) {
  3109.             return 0;
  3110.         } else if (iskanji(c1)) {
  3111.             c1 = *szstr++;
  3112.             c2 = *szid++;
  3113.             if (c1 != c2) return 0;
  3114.             len++;
  3115.         }
  3116.         len++;
  3117.     }
  3118. }
  3119.  
  3120. int TXAPI strimatch(mchar *szstr,mchar *szid)
  3121. {
  3122. // strmatchと同じですが、
  3123. // 大小文字は区別しないで比較
  3124.     int len = 0;
  3125.     while(1) {
  3126.         mchar c1 = *szstr++;
  3127.         mchar c2 = *szid++;
  3128.         
  3129.         if (c2 == 0) return len;
  3130.         if (c1 == 0) return 0;
  3131.         if (c2 == '\\') {
  3132.             c2 = *szid++;
  3133.             if (
  3134.                 (c1 == c2) ||
  3135.                 (c1 == '\t' && c2 == 't') ||
  3136.                 (c1 == ' ' && c2 == 's')
  3137.             ) {
  3138.                 // OK
  3139.             } else {
  3140.                 return 0;
  3141.             }
  3142.         } else if (toupper(c1) != toupper(c2)) {
  3143.             return 0;
  3144.         } else if (iskanji(c1)) {
  3145.             c1 = *szstr++;
  3146.             c2 = *szid++;
  3147.             if (c1 != c2) return 0;
  3148.             len++;
  3149.         }
  3150.         len++;
  3151.     }
  3152. }
  3153.  
  3154. int TXAPI strisid(mchar *szstr,mchar *szid)
  3155. {
  3156. // szstrの先頭がszidと等しく、デリミタが続いている場合、
  3157. // マッチしたszstrの長さを返します。
  3158. // 例:strcmpid("abcd","abc")は0
  3159. // 例:strcmpid("abcd aaa","abcd")は4
  3160. // そうでなければ0を返します。
  3161.     int len = strlen(szid);
  3162.     if (!strncmp(szstr,szid,len)) {
  3163.         mchar c = szstr[len];
  3164.         if (isspace(c) || c == 0) return len;
  3165.     }
  3166.     return 0;
  3167. }
  3168.  
  3169. mchar * TXAPIBASE strcpylen(mchar *dst,mchar *src,int len)
  3170. {
  3171. // srcからdstにlenバイトの文字をコピーします。
  3172. // dst[len] = 0として、dstを返します。
  3173.     memcpy(dst,src,len);
  3174.     dst[len] = 0;
  3175.     return dst;
  3176. }
  3177.  
  3178. mchar * TXAPI strcpylenmax(mchar *dst,mchar *src,int len,int lcxmax)
  3179. {
  3180. // strcpylenと同じですが、
  3181. // lenがlchmax以上なら最大lchmax-1文字コピーし、
  3182. // 末尾にヌルターミネータを追加します。
  3183.     if (len >= lcxmax) {
  3184.         len = lcxmax - 1;
  3185.         memcpy(dst,src,len);
  3186.         dst[len] = 0;
  3187.         formstr(dst);//1.97 
  3188.     } else {
  3189.         memcpy(dst,src,len);
  3190.         dst[len] = 0;
  3191.     }
  3192.     return dst;
  3193. }
  3194.  
  3195. mchar * TXAPI strsetlen(mchar *dst,BYTE c,int len)
  3196. {
  3197. // dstにcをlen個セットします。
  3198. // dst[len] = 0として、dstを返します。
  3199.     memset(dst,c,len);
  3200.     dst[len] = 0;
  3201.     return dst;
  3202. }
  3203.  
  3204. int TXAPI strsize(mchar *szstr)
  3205. {
  3206. // strlen(szstr) + 1を返します
  3207.     return (strlen(szstr) + 1) * sizeof(mchar);
  3208. }
  3209.  
  3210. int TXAPI strlensize(mchar *szstr)
  3211. {
  3212. // strlen(szstr)を返します
  3213.     return strlen(szstr) * sizeof(mchar);
  3214. }
  3215.  
  3216. mchar* TXAPI strskiptab(mchar* szstr,int n)
  3217. {
  3218. // szstrのn個目のタブの次の文字へのポインタを返します
  3219. // nに負の値を指定すると、szstrの最後のタブ文字の次の文字へのポインタを返します
  3220. // タブ文字が見つからなければ、szstrのNULL文字へのポインタを返します
  3221. //1.90で新設
  3222.     mchar* p = szstr;
  3223.     if (n < 0) {
  3224.         mchar*p1;
  3225.         while(p1 = strchr(p,'\t')) {
  3226.             p = p1 + 1;
  3227.         }
  3228.     } else {
  3229.         while(n--) {
  3230.             mchar*p1 = strchr(p,'\t');
  3231.             if (p1) {
  3232.                 p = p1 + 1;
  3233.             } else {
  3234.                 break;
  3235.             }
  3236.         }
  3237.     }
  3238.     if (p != szstr) return p;
  3239.     p += strlen(p);
  3240.     return p;
  3241. }
  3242.  
  3243. #ifdef __TXC__
  3244. // txstr support
  3245.  
  3246. mchar* TXAPIBASE txstrcpylen(txstr dst,mchar *src,int len)
  3247. {
  3248. // strcpylenのtxstr版
  3249. // srcからdstにlenバイトの文字をコピーします。
  3250. // dst[len] = 0として、dstを返します。
  3251. //2.90で追加
  3252.     strcpylenmax(dst,src,len,cchtxstr(dst));
  3253.     return (mchar*)dst;
  3254. }
  3255.  
  3256. friend txstr _strmid(txstr dst,mchar *str,int sizeoffset,int size)
  3257. {
  3258.     int len = strlen(str);
  3259.     
  3260.     if (sizeoffset >= len) {
  3261.         dst = "";
  3262.         return dst;
  3263.     }
  3264.     if (sizeoffset + size > len) size = len - sizeoffset;
  3265.     memcpy((mchar *)dst,&str[sizeoffset],size);
  3266.     dst[size] = 0;
  3267.     return dst;
  3268. }
  3269.  
  3270. friend txstr _strleft(txstr dst,mchar *str,int sizeleft)
  3271. {
  3272.     int len = strlen(str);
  3273.     
  3274.     if (sizeleft >= len) {
  3275.         dst = str;
  3276.     } else {
  3277.         memcpy((mchar *)dst,(mchar *)str,len);
  3278.         dst[sizeleft] = 0;
  3279.     }
  3280.     return dst;
  3281. }
  3282.  
  3283. friend txstr _inttostr(txstr dst,int num)
  3284. {
  3285.     sprintf(dst,"%d",num);
  3286.     return dst;
  3287. }
  3288.  
  3289. friend txstr _chartostr(txstr dst,int ch)
  3290. {
  3291.     sprintf(dst,"%c",ch);
  3292.     return dst;
  3293. }
  3294.  
  3295. mchar *strright(mchar *str,int sizeright)
  3296. {
  3297.     mchar *p = ((mchar *)str);
  3298.     int size = strlen(p);
  3299.     
  3300.     if (sizeright < size) {
  3301.         return p + size - sizeright;
  3302.     } else {
  3303.         return p;
  3304.     }
  3305. }
  3306.  
  3307. mchar *strrear(mchar *str,int sizeleft)
  3308. {
  3309.     return ((mchar *)str) + sizeleft;
  3310. }
  3311.  
  3312. #endif//__TXC__
  3313.  
  3314. //##hfile.c
  3315.  
  3316. #ifdef __TXC__
  3317.  
  3318. #export
  3319.     #ifndef SEEK_SET
  3320.         #define SEEK_SET    0
  3321.         #define SEEK_CUR    1
  3322.         #define SEEK_END    2
  3323.     #endif
  3324. #endexport
  3325.  
  3326. #endif
  3327.  
  3328. //{###ファイル操作}
  3329. //ファイルを直接読み書きする機能を提供します。
  3330.  
  3331. //##hfile based
  3332.  
  3333. HFILE TXAPI hfileOpen(mchar *szfilename)
  3334. {
  3335. // szfilenameのファイルを読込みモードでオープンし、ファイルハンドルを返します。
  3336. // ファイル操作が終わったらhfileCloseしてください。
  3337.     return _lopen(szfilename,OF_READ);
  3338. }
  3339.  
  3340. HFILE TXAPI hfileOpenWrite(mchar *szfilename)
  3341. {
  3342. // szfilenameのファイルを読み書きモードでオープンし、ファイルハンドルを返します。
  3343. // ファイル操作が終わったらhfileCloseしてください。
  3344. //2.96A 970213 新API
  3345.     return _lopen(szfilename,OF_READWRITE);
  3346. }
  3347.  
  3348. HFILE TXAPI hfileCreate(mchar *szfilename)
  3349. {
  3350. // szfilenameのファイルを作成し、ファイルハンドルを返します。
  3351. // ファイル操作が終わったらhfileCloseしてください。
  3352.     return _lcreat(szfilename,0);
  3353. }
  3354.  
  3355. BOOL TXAPI hfileClose(HFILE hfile)
  3356. {
  3357. // ファイルをクローズします
  3358.     if (_lclose(hfile)) return FALSE;
  3359.     return TRUE;
  3360. }
  3361.  
  3362. #ifdef __TXC__
  3363.  
  3364. long TXAPI hfileRead(HFILE hfile,LPVOID pmem,long size)
  3365. {
  3366. // ファイルからsizeバイト、pmemにロードします。
  3367. // ロードしたバイト数を返します。
  3368. //1.00Dで65535バイト以上ロードできるように改良 aaa
  3369.     return _hread(hfile,pmem,size);
  3370. }
  3371.  
  3372. long TXAPI hfileWrite(HFILE hfile,LPVOID pmem,long size)
  3373. {
  3374. // ファイルにsizeバイト、pmemの内容を書き込みます。
  3375. // 書き込んだバイト数を返します。
  3376. //1.00Dで65535バイト以上書き込みできるように改良
  3377.     return _hwrite(hfile,pmem,size);
  3378. }
  3379.  
  3380. LONG TXAPI hfileSeek(HFILE hfile,LONG lOffset,int nOrigin)
  3381. {
  3382. // 読み書きする位置を変更します。
  3383. // nOriginにSEEK_SETを指定すると、先頭からlOffsetバイト目に、
  3384. // nOriginにSEEK_CURを指定すると、現在位置+lOffsetに、
  3385. // nOriginにSEEK_ENDを指定すると、ファイル末尾+lOffsetバイトに、変更します。
  3386.     return _llseek(hfile,lOffset,nOrigin);
  3387. }
  3388.  
  3389. #endif
  3390.  
  3391. BOOL TXAPI hfileCopy(HFILE hfDst,HFILE hfSrc,DWORD size)
  3392. {
  3393. // hfSrcからhfDstにsizeバイトコピーします。
  3394. // sizeバイトコピーできたかどうか返します。
  3395.     LPBYTE buff = memAlloc(32768);
  3396.     BOOL ret = TRUE;
  3397.     
  3398.     if (buff) {
  3399.         while(size) {
  3400.             WORD sizeRead = 32768;    // 32kずつ読む
  3401.             
  3402.             if ((DWORD)sizeRead > size) sizeRead = (WORD)size;
  3403.             if (_lread(hfSrc,buff,sizeRead) != sizeRead) ret = FALSE;
  3404.             if (_lwrite(hfDst,buff,sizeRead) != sizeRead) ret = FALSE;
  3405.             size -= sizeRead;
  3406.         }
  3407.         memFree(buff);
  3408.     } else {
  3409.         ret = FALSE;
  3410.     }
  3411.     return ret;
  3412. }
  3413.  
  3414. #ifdef __TXC__
  3415. extern "tx" {
  3416. #endif
  3417. DOSFILETIME _hfileDate(HFILE hfile,DOSFILETIME date);
  3418. #ifdef __TXC__
  3419. }
  3420. #endif
  3421.  
  3422. DOSFILETIME TXAPI hfileGetDate(HFILE hfile)
  3423. {
  3424. // ファイルの日付を返します。
  3425. // 返り値の下位WORD:時間(bit0-4:秒数/2,bit5-10:分,bit11-15:時)
  3426. // 返り値の上位WORD:日付(bit0-4:日,bit5-8:月,bit9-15:年-1980)
  3427. //2.00B WZ32でもサポート
  3428.     return _hfileDate(hfile,0);
  3429. }
  3430.  
  3431. DOSFILETIME TXAPI hfileSetDate(HFILE hfile,DOSFILETIME date)
  3432. {
  3433. // ファイルの日付を設定します。
  3434. // dateにはhfileGetDateで返された日付を指定できます。
  3435. // または次の様に指定します。
  3436. // dateの下位WORD:時間(bit0-4:秒数/2,bit5-10:分,bit11-15:時)
  3437. // dateの上位WORD:日付(bit0-4:日,bit5-8:月,bit9-15:年-1980)
  3438. //2.00B WZ32でもサポート
  3439.     return _hfileDate(hfile,date);
  3440. }
  3441.  
  3442. //##filename based
  3443.  
  3444. BOOL TXAPI fileRename(mchar *_szsrc,mchar *_szdst)
  3445. {
  3446. // szsrcのファイル名をszdstに変更します。
  3447. // ファイル名は""でくくってあっても構いません。
  3448.     mchar szsrc[CCHPATHNAME];
  3449.     mchar szdst[CCHPATHNAME];
  3450.     //1.00H2 
  3451.     strcpy(szsrc,_szsrc);
  3452.     pathFormLong(szsrc);
  3453.     strcpy(szdst,_szdst);
  3454.     pathFormLong(szdst);
  3455.     if (rename(szsrc,szdst)) return FALSE;
  3456.     return TRUE;
  3457. }
  3458.  
  3459. BOOL TXAPI fileDelete(mchar *_szfilename)
  3460. {
  3461. // ファイルを削除します。
  3462. // ファイル名は""でくくってあっても構いません。
  3463.     mchar szfilename[CCHPATHNAME];
  3464.     strcpy(szfilename,_szfilename);
  3465.     pathFormLong(szfilename);//1.00H2 
  3466.     if (remove(szfilename)) return FALSE;
  3467.     return TRUE;
  3468. }
  3469.  
  3470. BOOL TXAPI fileCopy(mchar *_szsrc,mchar *_szdst)
  3471. {
  3472. // szsrcのファイルをszdstにコピーします。コピーできたか返します。
  3473. // 同じファイルにコピーする場合は、コピーせずTRUEを返します。
  3474. // ファイル名は""でくくってあっても構いません。
  3475. // szdstにはパスではなくてファイル名を指定してください。
  3476.     mchar szsrc[CCHPATHNAME];
  3477.     mchar szdst[CCHPATHNAME];
  3478.     strcpy(szsrc,_szsrc);
  3479.     pathFormLong(szsrc);
  3480.     strcpy(szdst,_szdst);
  3481.     pathFormLong(szdst);
  3482. //information("[%s][%s]",szsrc,szdst);
  3483.     if (!stricmp(szsrc,szdst)) return TRUE;//srcとdstが同じ
  3484. #ifdef __FLAT__
  3485.     return CopyFile(szsrc,szdst,FALSE);
  3486. #else
  3487.     #if 1//2.00E szsrcが存在しない場合、0バイトのサイズのszdstファイルを作ってしまっていた
  3488.     {
  3489.         BOOL ret = FALSE;
  3490.         HFILE hfsrc = HFILE_ERROR;
  3491.         HFILE hfdst = HFILE_ERROR;
  3492.         hfsrc = _lopen(szsrc,OF_READ);
  3493.         if (hfsrc != HFILE_ERROR) {
  3494.             hfdst = _lcreat(szdst,0);
  3495.             if (hfdst != HFILE_ERROR) {
  3496.                 DWORD time = hfileGetDate(hfsrc);
  3497.                 IFILE cbFile = _llseek(hfsrc,0,SEEK_END);
  3498.                 _llseek(hfsrc,0,SEEK_SET);
  3499.                 ret = hfileCopy(hfdst,hfsrc,cbFile);
  3500.                 hfileSetDate(hfdst,time);
  3501.             }
  3502.         }
  3503.         if (hfdst != HFILE_ERROR) _lclose(hfdst);
  3504.         if (hfsrc != HFILE_ERROR) _lclose(hfsrc);
  3505.         return ret;
  3506.     }
  3507.     #else
  3508.         hfdst = _lcreat(szdst,0);
  3509.         hfsrc = _lopen(szsrc,OF_READ);
  3510.         if (hfdst != HFILE_ERROR && hfsrc != HFILE_ERROR) {
  3511.             DWORD time = hfileGetDate(hfsrc);
  3512.             IFILE cbFile = _llseek(hfsrc,0,SEEK_END);
  3513.             _llseek(hfsrc,0,SEEK_SET);
  3514.             ret = hfileCopy(hfdst,hfsrc,cbFile);
  3515.             hfileSetDate(hfdst,time);
  3516.         }
  3517.         if (hfdst != HFILE_ERROR) _lclose(hfdst);
  3518.         if (hfsrc != HFILE_ERROR) _lclose(hfsrc);
  3519.         return ret;
  3520.     #endif
  3521. #endif
  3522. }
  3523.  
  3524. #include "_filer.h"
  3525.  
  3526. #ifdef __TXC__
  3527. #export
  3528. #ifdef __FLAT__
  3529.     #ifdef __TXC__
  3530.     extern "stdlib" {//2.00E "hfile"->"stdlib" WZ32でfileAtrが使えなかった
  3531.         unsigned _cdecl fileAtr(UCHAR* path,WORD* atr,BOOL fset);
  3532.     }
  3533.     #endif
  3534. #endif
  3535. #endexport
  3536.  
  3537. #ifdef __FLAT__
  3538. unsigned _cdecl fileAtr(UCHAR* path,WORD* atr,BOOL fset)
  3539. {
  3540.     if (fset) {
  3541.         DWORD atr32 = 0;
  3542.         
  3543.         if (*atr & FA_ARCH) atr32 |= FILE_ATTRIBUTE_ARCHIVE;
  3544.         if (*atr & FA_DIREC) atr32 |= FILE_ATTRIBUTE_DIRECTORY;
  3545.         if (*atr & FA_HIDDEN) atr32 |= FILE_ATTRIBUTE_HIDDEN;
  3546.         if (*atr & FA_RDONLY) atr32 |= FILE_ATTRIBUTE_READONLY;
  3547.         if (*atr & FA_SYSTEM) atr32 |= FILE_ATTRIBUTE_SYSTEM;
  3548.         return !SetFileAttributes(path,atr32);
  3549.     } else {
  3550.         DWORD atr32 = GetFileAttributes(path);
  3551.         *atr = 0;
  3552.         if (atr32 == 0xFFFFFFFF) return 1;
  3553.         if (atr32 & FILE_ATTRIBUTE_ARCHIVE) *atr |= FA_ARCH;
  3554.         if (atr32 & FILE_ATTRIBUTE_DIRECTORY) *atr |= FA_DIREC;
  3555.         if (atr32 & FILE_ATTRIBUTE_HIDDEN) *atr |= FA_HIDDEN;
  3556.         if (atr32 & FILE_ATTRIBUTE_READONLY) *atr |= FA_RDONLY;
  3557.         if (atr32 & FILE_ATTRIBUTE_SYSTEM) *atr |= FA_SYSTEM;
  3558.         return 0;
  3559.     }
  3560. }
  3561. #endif
  3562. #endif
  3563.  
  3564. #ifndef __NOTX__
  3565.  
  3566. //##imetx.c
  3567.  
  3568. //{###IME制御}
  3569. //IME(かな漢字変換プログラム)を制御します。
  3570.  
  3571. #ifdef __TXC__
  3572.     #ifdef __FLAT__
  3573.         extern "user32.dll" {
  3574.             #include <ime.h>
  3575.             BOOL WINAPI WINNLSEnableIME( HWND, BOOL );
  3576.         }
  3577.     #else
  3578.         extern "winnls.dll" {
  3579.             #include <ime.h>
  3580.             BOOL WINAPI WINNLSEnableIME( HWND, BOOL );
  3581.         }
  3582.     #endif
  3583. #endif
  3584.  
  3585. WORD TXAPI imeSend(UINT fnc,WPARAM wParam,LPARAM lParam1,LPARAM lParam2,LPARAM lParam3)
  3586. {
  3587. // SendIMEMessageExします。SendIMEMessageExの返り値を返します。
  3588. //1.00F 以前まではSendIMEMessageして、その返り値を返していましたが仕様変更しました。
  3589.     SHARE *sh = text1->share;
  3590. #ifdef __FLAT__
  3591.     IMESTRUCT *lpIme = (IMESTRUCT*)text1->lpIme;
  3592. #else
  3593.     IMESTRUCT *lpIme = (IMESTRUCT*)sh->lpIme;
  3594. #endif
  3595.     if (!lpIme) return 0;//1.99A この場合あり。
  3596.     memset(lpIme,0,sizeof(IMESTRUCT));
  3597.     lpIme->fnc = fnc;
  3598.     lpIme->wParam = wParam;
  3599.     lpIme->lParam1 = lParam1;
  3600.     lpIme->lParam2 = lParam2;
  3601.     lpIme->lParam3 = lParam3;
  3602. #ifdef __FLAT__
  3603.     return SendIMEMessageEx(textf->hwndtext,(LPARAM)GlobalPtrHandle(lpIme));
  3604. #else
  3605.     if (textf->hwndtext2 && textf->fFocus2) {//3.00B1 970612 WZ16で多重化時に下の窓でIMEの変換中文字列が表示されなかった
  3606.         return SendIMEMessageEx(textf->hwndtext2,GlobalPtrHandle(lpIme));
  3607.     } else {
  3608.         return SendIMEMessageEx(textf->hwndtext,GlobalPtrHandle(lpIme));
  3609.     }
  3610. #endif
  3611. }
  3612.  
  3613. //1.91A imeSetPosは廃止されました
  3614. //1.00F imeSetFontは廃止されました
  3615.  
  3616. BOOL TXAPIBASE imeGetOpen(void)
  3617. {
  3618. // IMEがONになっているかどうか返します。
  3619.     return imeSend(IME_GETOPEN,0,0,0,0);//1.00F
  3620. }
  3621.  
  3622. void TXAPIBASE imeSetOpen(BOOL fOpen)
  3623. {
  3624. // IMEをON/OFFします。
  3625.     imeSend(IME_SETOPEN,fOpen,0,0,0);
  3626.     // IMEが死んだようになるのの対策
  3627.     if (fOpen && !imeGetOpen()) {
  3628. #ifdef __FLAT__
  3629. #else
  3630.         WINNLSEnableIME(NULL,TRUE);
  3631. #endif
  3632.     }
  3633. }
  3634.  
  3635. #ifdef __TXC__
  3636. #export
  3637. #ifdef __TXC__
  3638. #endexport
  3639.  
  3640. imeOn
  3641. {
  3642. //IMEをONにします。
  3643. //IMEをキー操作でONにしても、ONにならないときに
  3644. //このコマンドを実行してみてください
  3645. //1.00Cで追加
  3646.     imeSetOpen(TRUE);
  3647. }
  3648.  
  3649. imeOff
  3650. {
  3651. //IMEをOFFにします。
  3652. //1.00Cで追加
  3653.     imeSetOpen(FALSE);
  3654. }
  3655.  
  3656. //##単語登録
  3657.  
  3658. HWND GetFocusEx(void)
  3659. {
  3660.     HWND hwnd = GetFocus();
  3661.     return (hwnd != NULL) ? hwnd : GetDesktopWindow();
  3662. }
  3663.  
  3664.  
  3665. WORD imeWordRegister(mchar* pszWord, mchar* pszYomi)
  3666. {
  3667.     HGLOBAL hIme = GlobalAlloc(GHND | GMEM_SHARE | GMEM_ZEROINIT, sizeof (IMESTRUCT));
  3668.     IMESTRUCT* pIme = (IMESTRUCT*)GlobalLock(hIme);
  3669.     pIme->fnc = IME_ENTERWORDREGISTERMODE;
  3670.     
  3671.     HGLOBAL hWord = GlobalAlloc(GHND | GMEM_SHARE, strlen(pszWord) + 1);
  3672.     mchar* pWord = (mchar*)GlobalLock(hWord);
  3673.     strcpy(pWord, pszWord);
  3674.     GlobalUnlock(hWord);
  3675.     pIme->lParam1 = (LPARAM)hWord;
  3676.     
  3677.     HGLOBAL hYomi = GlobalAlloc(GHND | GMEM_SHARE, strlen(pszYomi) + 1);
  3678.     mchar* pYomi = (mchar*)GlobalLock(hYomi);
  3679.     strcpy(pYomi, pszYomi);
  3680.     GlobalUnlock(hWord);
  3681.     pIme->lParam2 = (LPARAM)hYomi;
  3682.     
  3683.     GlobalUnlock(hIme);
  3684.     
  3685.     HWND hwnd = GetFocusEx();
  3686.     WORD r = (WORD)SendIMEMessageEx(hwnd, (LPARAM)hIme);
  3687.     GlobalFree(hIme);
  3688.     GlobalFree(hWord);
  3689.     GlobalFree(hYomi);
  3690.     return r;
  3691. }
  3692.  
  3693. BOOL TXCMDBASE imeRegWord(TX* text)
  3694. {
  3695. // 日本語入力辞書への単語登録
  3696. // 日本語入力システム(IME)の辞書ユーティリティを起動し、選択範囲の
  3697. // 文字列(漢字)を複写します。
  3698. // Thanks dieさん
  3699. //1.00H2 でimereg.cから移動
  3700.     txstr szword(128);
  3701.     txGetWord(text,szword);
  3702.     imeWordRegister(szword,"");
  3703.     return TRUE;
  3704. }
  3705.  
  3706. //{###ウィンドウ}
  3707.  
  3708. HWND TXAPIBASE isopen(mchar* szfilename)
  3709. {
  3710. // szfilenameがオープンされていれば、そのhwndbaseを返します
  3711. //2.92 
  3712.     return (HWND)txOp(text,TXOP_ISOPEN,(LPARAM)szfilename,NULL);
  3713. }
  3714.  
  3715. void TXAPI exit(void)
  3716. {
  3717. // 現在のウィンドウを閉じます
  3718. // ウィンドウが全部閉じられると、WZの実行を終了します。
  3719. //2.94 970123 新規API
  3720.     txQuit(textf);
  3721. }
  3722.  
  3723. //{###検索・置換}
  3724.  
  3725. BOOL TXAPI txJumpURL(TX* text)
  3726. {
  3727. // カーソル位置にURL、E-Mailアドレス、"ファイル名"があればジャンプ
  3728. // カーソル位置になければ、行頭からこれらがあるか調べ、あればジャンプ
  3729. // ジャンプしたかどうかを返す
  3730.     return (BOOL)txOp(text,TXOP_TXJUMPURL,NULL,NULL);
  3731. }
  3732.  
  3733. #export
  3734. #endif
  3735. #endexport
  3736. #endif
  3737.  
  3738. //##ヘルプ
  3739. //{###ヘルプ}
  3740.  
  3741. //1.99G 
  3742. BOOL TXAPI WinHelpWz(mchar* szfilename,UINT fuCommand,LPARAM dwData)
  3743. {
  3744.     mchar _szfilename[CCHPATHNAME];
  3745.     
  3746.     if (
  3747.         szfilename == NULL ||
  3748.         szfilename[0] == 0 ||
  3749.         pathEquFileName(szfilename,"wz")    //2.00B WZ16でツールバーの[?]ボタンでヘルプが表示されなかった
  3750.     ) {
  3751.         szfilename = _szfilename;
  3752.         szfilename[0] = 0;
  3753. #if 1//1.99G NT3.5はwz16.hlpを使用
  3754.     #if 1//2.99B 970322 NT4.0はwz16.hlpを使用
  3755.         if ((_fwin40 && _platform == WINDOWS95) || _fwinnt351) {
  3756.             pathSetFileName(szfilename,"wz:\\wz.hlp");
  3757.         } else {
  3758.             pathSetFileName(szfilename,"wz:\\wz16.hlp");
  3759.         }
  3760.     #else
  3761.         if (_fwin40 || _fwinnt351) {
  3762.             pathSetFileName(szfilename,"wz:\\wz.hlp");
  3763.         } else {
  3764.             pathSetFileName(szfilename,"wz:\\wz16.hlp");
  3765.         }
  3766.     #endif
  3767. #else
  3768.         #ifdef __FLAT__
  3769.             pathSetFileName(szfilename,"wz:\\wz.hlp");
  3770.         #else
  3771.             pathSetFileName(szfilename,"wz:\\wz16.hlp");
  3772.         #endif
  3773. #endif
  3774.     }
  3775.     if (fuCommand == HELP_CONTENTS && _fwin40) {
  3776.         //1.99G Windows95では目次を開く為にWinHelpを起動する。
  3777.         mchar szbuff[20 + CCHPATHNAME];
  3778.         strcpy(szbuff,"winhelp ");
  3779.         strcat(szbuff,szfilename);
  3780.         return (WinExec(szbuff,SW_SHOW) >= 32);
  3781.     } else {
  3782. //information(szfilename);
  3783.         return WinHelp(textf->hwndbase,szfilename,fuCommand,dwData);//2.95 970128 text1->textf
  3784.     }
  3785. }
  3786.  
  3787. #ifdef __TXC__
  3788.  
  3789. //{###文字列ブロック}
  3790. //##history
  3791. // 1996.12.2 start
  3792.  
  3793. static mchar _szfilename[] = "wzhist.dat";
  3794. static mchar _szhead[] = "..\x08\x08[";
  3795.  
  3796. HSTRBLK TXAPI historyOpen(mchar* szName,int cbHistbuff)
  3797. {
  3798. // szNameのヒストリを開く。
  3799. // szNameに、'[',']',改行は使えない。
  3800.     HSTRBLK sb = sbNewAlloc(cbHistbuff);
  3801.     if (sb) {
  3802.         mchar szfilename[CCHPATHNAME];
  3803.         pathFullConfig(szfilename,_szfilename);
  3804.         TX _text;
  3805.         TX* text = &_text;
  3806.         if (txInit(text,szfilename)) {
  3807.             if (txSearchEx(text,_szhead+szName+"]",SEARCH_CUR)) {
  3808.                 // テキストのトップがヒストリのトップになるように逆順に
  3809.                 //出力。
  3810.                 txstr szline;
  3811.                 txNextPara(text);
  3812.                 NPARA nparaEnd = text->npara;
  3813.                 NPARA nparaTop = 1;
  3814.                 while(1) {
  3815.                     txGetPara(text,szline);
  3816.                     if (!strncmp(szline,_szhead,strlen(_szhead))) {
  3817.                         nparaTop = text->npara - 1;
  3818.                         break;
  3819.                     }
  3820.                     if (!txNextPara(text)) {
  3821.                         nparaTop = text->npara;
  3822.                         break;
  3823.                     }
  3824.                 }
  3825.                 for (NPARA npara = nparaTop;npara >= nparaEnd;npara--) {
  3826.                     txJumpNpara(text,npara);
  3827.                     txGetPara(text,szline);
  3828.                     if (szline[0]) sbAdd(sb,szline);
  3829.                 }
  3830.             }
  3831.             txClose(text);
  3832.         }
  3833.     }
  3834.     return sb;
  3835. }
  3836.  
  3837. void TXAPI historyClose(mchar* szName,HSTRBLK sb)
  3838. {
  3839. // szNameのヒストリを開じる。sbも破棄する。
  3840. // szNameに、'[',']',改行は使えない。
  3841.     if (sb) {
  3842.         mchar szfilename[CCHPATHNAME];
  3843.         pathFullConfig(szfilename,_szfilename);
  3844.         TX _text;
  3845.         TX* text = &_text;
  3846.         if (txInit(text,szfilename)) {
  3847.             if (txSearchEx(text,_szhead+szName+"]",SEARCH_CUR)) {
  3848.                 txSelectEx(text,CLIP_CHAR);
  3849.                 txstr szline;
  3850.                 txNextPara(text);
  3851.                 while(1) {
  3852.                     int lch = txGetPara(text,szline);
  3853.                     if (!strncmp(szline,_szhead,strlen(_szhead))) break;
  3854.                     if (!txNextPara(text)) break;
  3855.                 }
  3856.                 txSelectDelete(text);
  3857.             }
  3858.             // ヒストリのトップが、テキストのトップになるように逆順に出
  3859.             //力。
  3860.             {
  3861.                 txInsertLine(text,"%s%s]",_szhead,szName);
  3862.                 int n = sbGetCount(sb);
  3863.                 for (int i = n;--i >= 0;) {
  3864.                     mchar* sz = sbRead(sb,i);
  3865.                     if (sz[0]) txInsertLine(text,sz);
  3866.                 }
  3867.             }
  3868.             txSave(text);
  3869.             txClose(text);
  3870.         }
  3871.         sbDelete(sb);
  3872.     }
  3873. }
  3874.  
  3875. #endif// __TXC__
  3876.  
  3877. #endif// __NOTX__
  3878.  
  3879.