home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1999 March / VPR9903A.BIN / APUPDATE / VC / Tx300d / TX300D.LZH / STD.C < prev    next >
C/C++ Source or Header  |  1997-06-13  |  65KB  |  2,708 lines

  1. // WZ EDITOR 標準機能 TX-C標準ライブラリ関数群
  2. // Copyright 1995-96 TY
  3.  
  4. #ifdef __TXC__
  5.     #pragma HEADER+
  6.     #include <windows.h>
  7.     #include <windowsx.h>
  8. #else
  9.     #define __CC_STD    // 自分自身のコンパイルフラグをセット
  10.     #include "..\tx.h"
  11.     #include <string.h>
  12.     #include <stdio.h>
  13.     #include <stdlib.h>
  14.     #include <ctype.h>
  15. #endif
  16.  
  17. //{###情報取得}
  18.  
  19. #ifdef __TXC__
  20. #export
  21.  
  22. #define WIN16        1
  23. #define WIN32S        2
  24. #define WINDOWS95    3
  25. #define WINDOWSNT    4
  26.  
  27. #ifdef __TXC__
  28. extern "std" {
  29. #endif
  30.     // TX-C:外部にexportする静的変数は、初期化済みデータ(static)でないといけない
  31.     // bssではだめ。
  32.     extern BYTE _platform;    // GetWindowsPlatform()の値と同じ
  33.     extern BYTE _fwin40;    // is Windows4.0(Windows95) ?
  34.     extern BYTE _fwinnt351;    // is WindowsNT3.51 ?
  35.     extern BYTE _fpsh;        // プロパティーシートを使う?
  36. #ifdef __TXC__
  37. }
  38. #endif
  39.  
  40. #define IsPropSheet()    (_fwin40 || _fwinnt351)
  41.  
  42. #endexport
  43. #endif
  44.  
  45. BYTE _platform = 0;
  46. BYTE _fwin40 = FALSE;
  47. BYTE _fwinnt351 = FALSE;    //1.99A 
  48. BYTE _fpsh = FALSE;            //2.00B 
  49.  
  50. int TXAPI GetWindowsPlatform(void)
  51. {
  52. // 現在動作中のWindowsのプラットフォームを返します。
  53. // WIN16,WIN32S,WINDOWS95,WINDOWSNTのどれかを返します。
  54. //1.00Fで追加
  55. #ifdef __FLAT__
  56.     if (!_platform) {
  57.         DWORD dwVersion = GetVersion();
  58.         if (dwVersion < 0x80000000) {
  59.             _platform = WINDOWSNT;
  60.             if (LOBYTE(LOWORD(dwVersion)) >= 4) {//2.00E WinNT4.0対応
  61.                 _fwin40 = TRUE;
  62.                 _fpsh = TRUE;
  63.             } else {
  64.                 _fwinnt351 = (HIBYTE(LOWORD(dwVersion)) == 0x33);
  65.                 if (_fwinnt351) {
  66.                     _fpsh = TRUE;
  67.                 }
  68.             }
  69.         } else if (LOBYTE(LOWORD(dwVersion)) < 4) {
  70.             _platform = WIN32S;
  71.         } else {
  72.             _platform = WINDOWS95;
  73.             _fwin40 = TRUE;
  74.             _fpsh = TRUE;
  75.         }
  76.     }
  77.     return _platform;
  78. #else
  79.     _platform = WIN16;
  80.     return _platform;
  81. #endif
  82. }
  83.  
  84. #ifndef __NOTX__
  85.  
  86. int TXAPI getversion(void)
  87. {
  88. // WZのバージョン番号を返します。
  89. // 1.00Cなら0x1003を返します。
  90. // 1.00Cで追加しました。
  91. // 1.00/1.00A/1.00BでこのAPIを呼び出すとダイナミックリンクエラーになります。
  92. // 1.00/1.00A/1.00Bかどうかを判定するには次のようにしてください。
  93. // if (iswz100AB()) {//1.00/1.00A/1.00B}
  94.     return SendMessage(text1->hwndbase,WM_COMMAND,IDM_TXGETVERSION,0);
  95. }
  96.  
  97. int TXAPI textSearch(HWND hwnd)
  98. {
  99. //1.00H4 リストから探す。見つからなければ-1を返す
  100. #ifdef __TXC__
  101.     SHARE *sh = text->share;
  102. #endif
  103.     int ret = -1;
  104.     int i;
  105.     
  106.     wzlock(LOCK_WZPROCESS);
  107.     for (i = 0;i < sh->nOpen;i++) {
  108.         if (sh->tWzprocess[i].hwnd == hwnd) {
  109.             ret = i;
  110.             break;
  111.         }
  112.     }
  113.     wzunlock(LOCK_WZPROCESS);
  114.     //2.00B search.otherUpなどが実行されなかった
  115.     // "return i;"になってた
  116.     return ret;
  117. }
  118.  
  119. BOOL TXAPI textSetProcessMode(HWND hwnd,DWORD modeProcess)
  120. {
  121. //1.00H5 hwndの窓のmodeProcessを設定
  122.     BOOL ret = FALSE;
  123.     int i;
  124. #if 1//1.99C 先にロックしないとまずいんでは?
  125.     wzlock(LOCK_WZPROCESS);
  126.     i = textSearch(hwnd);
  127. #else
  128.     i = textSearch(hwnd);
  129.     wzlock(LOCK_WZPROCESS);
  130. #endif
  131.     if (i != -1) {
  132. #ifdef __TXC__
  133.         SHARE *sh = text->share;
  134. #endif
  135.         sh->tWzprocess[i].modeProcess = modeProcess;
  136.         ret = TRUE;
  137.     }
  138.     wzunlock(LOCK_WZPROCESS);
  139.     return ret;
  140. }
  141.  
  142. DWORD TXAPI textGetProcessMode(HWND hwnd)
  143. {
  144. //1.00H5 hwndの窓のmodeProcessを返す
  145. // hwndが見つからなければ0を返す
  146.     DWORD ret = 0;
  147.     int i;
  148.     wzlock(LOCK_WZPROCESS);
  149.     i = textSearch(hwnd);
  150.     if (i != -1) {
  151. #ifdef __TXC__
  152.         SHARE *sh = text->share;
  153. #endif
  154.         ret = sh->tWzprocess[i].modeProcess;
  155.     }
  156.     wzunlock(LOCK_WZPROCESS);
  157.     return ret;
  158. }
  159.  
  160. //{###ファイル名・パス名}
  161.  
  162. void TXAPI pathGetWzexeFilename(mchar szfilename[CCHPATHNAME])
  163. {
  164. // szfilenameにWZ.EXEのフルパスをセットする。
  165. // 2.90で追加。
  166.     if (text1->fWzc) {
  167.         #ifdef __FLAT__
  168.         GetModuleFileName(text1->hInstance,szfilename,CCHPATHNAME);
  169.         pathSetFileName(szfilename,"wzeditor.exe");
  170.         #endif
  171.     } else {
  172.         if (text1->hInstanceParent) {
  173.             GetModuleFileName(text1->hInstanceParent,szfilename,CCHPATHNAME);
  174.         } else {
  175.             GetModuleFileName(text1->hInstance,szfilename,CCHPATHNAME);
  176.         }
  177.     }
  178. }
  179.  
  180. //{###コマンドライン}
  181.  
  182. //1.00H3 
  183. // ここでPROCESS_INFORMATIONを使って、TXAPIとするのはだめ。
  184. // <windows.h>が#includeされてないとstd.txhでエラーになっちゃう。
  185. // マクロで、__DEV__を参照しても駄目。
  186. // __DEV__を変更しても、コンパイルされないで出荷されちゃうゾ
  187. BOOL TXAPIBASE wzExec(LPBYTE _szarg)
  188. {
  189. #if 1//3.00B1 970613 wzExec:長い引数に対応
  190. #ifdef __FLAT__
  191.     BOOL ret = FALSE;
  192.     mchar szmodulename[CCHPATHNAME];
  193.     mchar* szarg = NULL;
  194.     pathGetWzexeFilename(szmodulename);
  195.     //
  196.     szarg = malloc(strlen(_szarg) + 10);
  197.     if (szarg) {
  198.         PROCESS_INFORMATION processinfo;
  199.         STARTUPINFO startinfo;
  200.         //
  201.         szarg[0] = ' ';    // 先頭は必ず空白を渡さないといけない
  202.         strcpy(szarg + 1,_szarg);
  203.         //
  204.         memset(&startinfo,0,sizeof(startinfo));
  205.         startinfo.cb = sizeof(startinfo);
  206.         //
  207.         ret = CreateProcess(
  208.             szmodulename,
  209.             szarg,
  210.             NULL,
  211.             NULL,
  212.             FALSE,
  213.             0,
  214.             NULL,
  215.             NULL,
  216.             &startinfo,
  217.             &processinfo
  218.         );
  219.         free(szarg);
  220.     }
  221.     return ret;
  222. #else
  223.     BOOL ret = FALSE;
  224.     mchar* szarg = malloc(CCHPATHNAME + strlen(_szarg) + 10);
  225.     if (szarg) {
  226.         mchar *p = szarg;
  227.         GetModuleFileName(text1->hInstance,p,CCHPATHNAME);
  228.         p += strlen(p);
  229.         *p++ = ' ';
  230.         strcpy(p,_szarg);
  231.         if (WinExec(szarg,SW_SHOWNORMAL) < 32) {//2.00E SW_SHOW->SW_SHOWNORMAL
  232.         #ifdef __TXC__
  233.             attention("コマンド(%s)が起動できません。\nメモリ不足の可能性があります",szcmd);
  234.         #else
  235.             attention(rcString(12),szarg);
  236.         #endif
  237.         } else {
  238.             ret = TRUE;
  239.         }
  240.         free(szarg);
  241.     }
  242.     return ret;
  243. #endif
  244. #else
  245. #ifdef __FLAT__
  246.     mchar szmodulename[CCHPATHNAME];
  247.     mchar szarg[CCHPATHNAME];
  248.     PROCESS_INFORMATION processinfo;
  249.     STARTUPINFO startinfo;
  250.     //
  251.     szarg[0] = ' ';    // 先頭は必ず空白を渡さないといけない
  252.     strcpymax(szarg+1,_szarg,CCHPATHNAME-1);
  253.     //
  254.     memset(&startinfo,0,sizeof(startinfo));
  255.     startinfo.cb = sizeof(startinfo);
  256.     //
  257.     pathGetWzexeFilename(szmodulename);
  258.     return CreateProcess(
  259.         szmodulename,
  260.         szarg,
  261.         NULL,
  262.         NULL,
  263.         FALSE,
  264.         0,
  265.         NULL,
  266.         NULL,
  267.         &startinfo,
  268.         &processinfo
  269.     );
  270. #else
  271.     mchar szcmd[CCHPATHNAME*2];
  272.     mchar *p = szcmd;
  273.     
  274.     GetModuleFileName(text1->hInstance,p,CCHPATHNAME);
  275.     p += strlen(p);
  276.     *p++ = ' ';
  277.     strcpy(p,_szarg);
  278.     if (WinExec(szcmd,SW_SHOWNORMAL) < 32) {//2.00E SW_SHOW->SW_SHOWNORMAL
  279.     #ifdef __TXC__
  280.         attention("コマンド(%s)が起動できません。\nメモリ不足の可能性があります",szcmd);
  281.     #else
  282.         attention(rcString(12),szcmd);
  283.     #endif
  284.         return FALSE;
  285.     }
  286.     return TRUE;
  287. #endif
  288. #endif
  289. }
  290.  
  291. #endif    // __NOTX__
  292.  
  293. #ifndef __NOTX__
  294.  
  295. //{###文字列ブロック}
  296. //複数の文字列をまとめて管理する機能を提供します。
  297. //文字列の追加、削除、検索などができます。
  298. //WZのヒストリー機能実現、キーワード管理に使われています。
  299. //[1]文字列ブロック変数を用意
  300. //HSTRBLK hsb;
  301. //[2]sbNewで初期化
  302. //[3]sbAdd,sbSearchなどで利用
  303. //[4]sbDeleteで終了処理
  304.  
  305. #ifdef __TXC__
  306. #export
  307. #ifndef __HSTRBLK
  308. #define __HSTRBLK
  309.     #if 1//1.99C _text.h16だとエラーが出た
  310.         typedef struct tagSTRBLK * HSTRBLK;
  311.     #else
  312.         #ifdef __CC_STD    // 自分自身のコンパイル
  313.         typedef struct tagSTRBLK * HSTRBLK;
  314.         #else
  315.         DECLARE_HANDLE_TX(HSTRBLK);
  316.         #endif
  317.     #endif
  318.     // share構造体に置くためだけに、データ構造を公開する。
  319.     // ユーザーは、メンバを参照してはいけない。
  320.     typedef struct tagSTRBLK {
  321.         LPBYTE buff;
  322.         LPBYTE ptail;
  323.         WORD sizebuff;        // buffのサイズ
  324.         WORD nstr;            // 文字列数
  325.         // WORD bit field
  326.         WORD fSenseCase:1;
  327.         WORD fCustData:1;
  328.         WORD fShared:1;
  329.         WORD fstatic:1;        // for internal
  330.         WORD fAlloc:1;        //2.90 buff is allced by strblk
  331.         WORD reserved:11;
  332.         // WORD bit field end
  333.         LPBYTE pfound;
  334.     } STRBLK;
  335. #endif
  336. #endexport
  337. #endif
  338.  
  339. #ifdef __FLAT__//SHAREのアドレスが変化しても対応できるように
  340.     #define SB_OFFSET    (sb->fShared*(DWORD)(text1->share))
  341.     #define SB_LOCK        wzlock(LOCK_HIST);
  342.     #define SB_UNLOCK    wzunlock(LOCK_HIST);
  343. #else
  344.     #define SB_OFFSET    (0)
  345.     #define SB_LOCK
  346.     #define SB_UNLOCK
  347. #endif
  348.  
  349.  
  350. typedef STRBLK CONTEXTTX;//1.00F
  351. #ifdef __TXC__
  352.     #if 1//1.93 
  353.         #define MAXCONTEXTTX    120
  354.     #else
  355.         #define MAXCONTEXTTX    30
  356.     #endif
  357. #else
  358.     #define MAXCONTEXTTX    10
  359. #endif
  360. #include "context.ci"
  361.  
  362. HSTRBLK TXAPI sbNewStatic(HSTRBLK sb,LPBYTE buff,WORD sizebuff)
  363. {
  364. // sbNewと同じだが、ハンドルを利用側で作成
  365. // 次のように使用
  366. //    STRBLK _sb;
  367. //    HSTRBLK sb = sbNewStatic(&_sb,buff,sizebuff);
  368. //    sbAdd(sb,"abc");...
  369. //    sbAdd(&_sb,"abc");...//これでもOK
  370.     if (sb) {
  371.         SB_LOCK;
  372.         memset(sb,0,sizeof(CONTEXTTX));
  373.         sb->fstatic = TRUE;
  374.         sb->buff = sb->ptail = buff;
  375.         sb->sizebuff = sizebuff;
  376.         sb->fSenseCase = TRUE;
  377.         SB_UNLOCK;
  378.     }
  379.     return sb;
  380. }
  381.  
  382. HSTRBLK TXAPI sbNewStaticShare(HSTRBLK sb,LPBYTE buff,WORD sizebuff)
  383. {
  384.     SB_LOCK;
  385.     if (sbNewStatic(sb,buff,sizebuff)) {
  386. #ifdef __FLAT__
  387.         sb->fShared = TRUE;
  388. #endif
  389.     }
  390.     SB_UNLOCK;
  391.     return sb;
  392. }
  393.  
  394. HSTRBLK TXAPI sbNew(LPBYTE buff,WORD sizebuff)
  395. {
  396. // 文字列バッファをbuffに、buffのサイズをsizebuffに指定してオープン
  397. // ハンドルを返す
  398.     HSTRBLK sb = contextNew();
  399.     
  400. // dialog使っている時、ここでinformation等使うと、駄目みたい?
  401.     if (sb) {
  402.         sb->buff = sb->ptail = buff;
  403.         sb->sizebuff = sizebuff;
  404.         sb->fSenseCase = TRUE;
  405.     } else {
  406. //        attention("strblk:ハンドル不足");
  407.     }
  408.     return sb;
  409. }
  410.  
  411. HSTRBLK TXAPI sbNewAlloc(WORD sizebuff)
  412. {
  413. // sizebuffサイズの文字列バッファサイズをアロケートし、ハンドルを返す。
  414. //2.90 で追加
  415.     LPBYTE buff = malloc(sizebuff);
  416.     if (buff) {
  417.         HSTRBLK sb = contextNew();
  418.         if (sb) {
  419.             sb->buff = sb->ptail = buff;
  420.             sb->sizebuff = sizebuff;
  421.             sb->fSenseCase = TRUE;
  422.             sb->fAlloc = TRUE;
  423.         } else {
  424.             free(buff);
  425. //            attention("strblk:ハンドル不足");
  426.         }
  427.         return sb;
  428.     } else {
  429.         return NULL;
  430.     }
  431. }
  432.  
  433. void TXAPI sbSetBuff(HSTRBLK sb,LPBYTE buff,WORD sizebuff)
  434. {
  435. // sbDelAll後、文字列バッファをbuffにセットし直す。
  436. // 以前の文字列バッファの解放は行わない
  437. //2.00Eで追加
  438.     if (sb) {
  439.         SB_LOCK;
  440.         sbDelAll(sb);
  441.         sb->buff = sb->ptail = buff;
  442.         sb->sizebuff = sizebuff;
  443.         SB_UNLOCK;
  444.     }
  445. }
  446.  
  447. LPVOID TXAPI sbGetBuff(HSTRBLK sb)
  448. {
  449. // 文字列バッファを返す
  450. //1.00Fで追加
  451.     return sb->buff;
  452. }
  453.  
  454. BOOL TXAPI sbReverse(HSTRBLK sb)
  455. {
  456. // sbの内容を逆順にします。
  457. //2.99C 970325 new
  458.     BOOL ret = FALSE;
  459.     HSTRBLK sbTmp = sbNewAlloc(sb->sizebuff);
  460.     if (sbTmp) {
  461.         int n = sbGetCount(sb);
  462.         int n0 = n;
  463.         int i;
  464.         for (i = 0;i < n;i++) {
  465.             sbAdd(sbTmp,sbRead(sb,i));
  466.         }
  467.         n = sbGetCount(sbTmp);
  468.         ret = (n == n0);
  469.         sbDelAll(sb);
  470.         for (i = n;i--;) {
  471.             sbAdd(sb,sbRead(sbTmp,i));
  472.         }
  473.         sbDelete(sbTmp);
  474.     }
  475.     return ret;
  476. }
  477.  
  478. void TXAPI sbSetSenseCase(HSTRBLK sb,BOOL fSet)
  479. {
  480. // 大文字・小文字を区別するかどうか設定
  481. // デフォルト:区別
  482. // いつでも変更できます
  483.     SB_LOCK;
  484.     sb->fSenseCase = fSet;
  485.     SB_UNLOCK;
  486. }
  487.  
  488. BOOL TXAPI sbGetSenseCase(HSTRBLK sb)
  489. {
  490. // 大文字・小文字を区別するかどうかの設定内容を返します
  491. //1.96で追加
  492.     BOOL ret;
  493.     SB_LOCK;
  494.     ret = sb->fSenseCase;
  495.     SB_UNLOCK;
  496.     return ret;
  497. }
  498.  
  499. void TXAPI sbSetCustData(HSTRBLK sb,BOOL fSet)
  500. {
  501. // CustDataを使うかどうかの設定
  502. // デフォルト:使わない
  503. // sbNew等の直後に呼び出してください。
  504. //1.01A で追加
  505.     SB_LOCK;
  506.     sb->fCustData = fSet;
  507.     SB_UNLOCK;
  508. }
  509.  
  510. BOOL TXAPI sbGetCustData(HSTRBLK sb)
  511. {
  512. // CustDataを持っているかどうか返す
  513. //1.91A 
  514.     BOOL ret;
  515.     SB_LOCK;
  516.     ret = sb->fCustData;
  517.     SB_UNLOCK;
  518.     return ret;
  519. }
  520.  
  521. typedef struct {
  522.     // ヘッダID
  523.     WORD sizestruct;
  524.     UCHAR id[7];
  525.     // ヘッダ本体
  526.     WORD cbdata;
  527.     WORD nstr;
  528.     // WORD bit field
  529.     WORD fCustData:1;
  530.     WORD reserved:15;
  531.     // WORD bit field end
  532. } SBHDR;
  533.  
  534. void TXAPI sbDelAll(HSTRBLK sb)
  535. {
  536. // すべて削除
  537.     SB_LOCK;
  538.     sb->ptail = sb->buff;
  539.     sb->nstr = 0;
  540.     SB_UNLOCK;
  541. }
  542.  
  543. static BOOL _sbLoad(HSTRBLK sb,HFILE hf)
  544. {
  545.     SBHDR head;
  546.     
  547.     if (hf == HFILE_ERROR) return FALSE;
  548.     if (_lread(hf,&head,sizeof(head)) != sizeof(head)) return FALSE;
  549.     if (head.sizestruct != sizeof(head)) return FALSE;
  550.     if (strcmp(head.id,"strblk")) return FALSE;
  551.     if (head.cbdata > sb->sizebuff) return FALSE;
  552.     if (head.fCustData != sb->fCustData) return FALSE;//1.01A 
  553.     if (_lread(hf,sb->buff + SB_OFFSET,head.cbdata) != head.cbdata) {
  554.         sbDelAll(sb);
  555.         return FALSE;
  556.     }
  557.     sb->nstr = head.nstr;
  558.     sb->ptail = sb->buff + head.cbdata;
  559.     return TRUE;
  560. }
  561.  
  562. BOOL TXAPI sbLoad(HSTRBLK sb,HFILE hf)
  563. {
  564. // ファイルからロード
  565.     BOOL ret;
  566.     SB_LOCK;
  567.     ret = _sbLoad(sb,hf);
  568.     SB_UNLOCK;
  569.     return ret;
  570. }
  571.  
  572. static BOOL _sbSave(HSTRBLK sb,HFILE hf)
  573. {
  574.     SBHDR head;
  575.     
  576.     if (hf == HFILE_ERROR) return FALSE;
  577.     head.sizestruct = sizeof(head);
  578.     strcpy(head.id,"strblk");
  579.     head.cbdata = sb->ptail - sb->buff;
  580.     head.nstr = sb->nstr;
  581.     head.fCustData = sb->fCustData;
  582.     if (_lwrite(hf,(void*)&head,sizeof(head)) != sizeof(head)) return FALSE;
  583.     if (_lwrite(hf,(void*)(sb->buff + SB_OFFSET),head.cbdata) != head.cbdata) return FALSE;
  584.     return TRUE;
  585. }
  586.  
  587. BOOL TXAPI sbSave(HSTRBLK sb,HFILE hf)
  588. {
  589. // ファイルへセーブ
  590.     BOOL ret;
  591.     SB_LOCK;
  592.     ret = _sbSave(sb,hf);
  593.     SB_UNLOCK;
  594.     return ret;
  595. }
  596.  
  597. mchar* TXAPI sbAdd(HSTRBLK sb,mchar *szstr)
  598. {
  599. // szstrを末尾に追加。追加結果の文字列ポインタを返す
  600.     mchar *ret = NULL;
  601.     SB_LOCK;
  602.     {
  603.         int sizestr = strsize(szstr);
  604.         if (sb->ptail - sb->buff + sizeof(WORD) + sizestr + sizeof(DWORD) > sb->sizebuff) {
  605.             // NG
  606.         } else {
  607.             *(WORD *)(sb->ptail + SB_OFFSET) = sizestr;sb->ptail += sizeof(WORD);
  608.             ret = sb->ptail + SB_OFFSET;
  609.             memcpy(ret,szstr,sizestr);
  610.             sb->ptail += sizestr;
  611.             if (sb->fCustData) {//1.01A 
  612.                 *(DWORD*)(sb->ptail + SB_OFFSET) = 0;
  613.                 sb->ptail += sizeof(DWORD);
  614.             }
  615.             sb->nstr++;
  616.         }
  617.     }
  618.     SB_UNLOCK;
  619.     return ret;
  620. }
  621.  
  622. int TXAPI sbiPreSearch(HSTRBLK sb,mchar *szstr)
  623. {
  624. // szstrを検索。見つけた位置(0から(sbGetCount-1))を返す
  625. // 文字列の頭だけが一致すればOKとする。
  626.     int ret = -1;
  627.     SB_LOCK;
  628.     {
  629.         LPBYTE p = sb->buff + SB_OFFSET;
  630.         int sizestr = strlensize(szstr);
  631.         int i;
  632.         
  633.         if (sb->fSenseCase) {
  634.             for (i = 0;i < sb->nstr;i++) {
  635.                 int size = *(WORD *)p;p += sizeof(WORD);
  636.                 
  637.                 size -= sizeof(mchar);
  638.                 if (sizestr >= size && !memcmp(p,szstr,size)) {
  639.                     sb->pfound = p - sizeof(WORD) - SB_OFFSET;
  640.                     ret = i;
  641.                     break;
  642.                 }
  643.                 p += size + sizeof(mchar);
  644.                 if (sb->fCustData) p += sizeof(DWORD);//1.01A 
  645.             }
  646.         } else {//2.00E4 !fSenseCaseに対応
  647.             for (i = 0;i < sb->nstr;i++) {
  648.                 int size = *(WORD *)p;p += sizeof(WORD);
  649.                 
  650.                 size -= sizeof(mchar);
  651.                 if (sizestr >= size && !strnicmp(p,szstr,size)) {
  652.                     sb->pfound = p - sizeof(WORD) - SB_OFFSET;
  653.                     ret = i;
  654.                     break;
  655.                 }
  656.                 p += size + sizeof(mchar);
  657.                 if (sb->fCustData) p += sizeof(DWORD);//1.01A 
  658.             }
  659.         }
  660.     }
  661.     SB_UNLOCK;
  662.     return ret;
  663. }
  664.  
  665. int TXAPI sbiSearch(HSTRBLK sb,mchar *szstr)
  666. {
  667. // szstrを検索。見つけた位置(0から(sbGetCount-1))を返す
  668. // 見つからなければ-1を返す
  669.     int ret = -1;
  670.     SB_LOCK;
  671.     {
  672.         LPBYTE p = sb->buff + SB_OFFSET;
  673.         int sizestr = strsize(szstr);
  674.         int i;
  675.         
  676.         if (sb->fSenseCase) {
  677.             for (i = 0;i < sb->nstr;i++) {
  678.                 int size = *(WORD *)p;p += sizeof(WORD);
  679.                 
  680.                 if (sizestr == size && !memcmp(p,szstr,sizestr)) {
  681.                     sb->pfound = p - sizeof(WORD) - SB_OFFSET;
  682.                     ret = i;
  683.                     break;
  684.                 }
  685.                 p += size;
  686.                 if (sb->fCustData) p += sizeof(DWORD);//1.01A 
  687.             }
  688.         } else {
  689.             for (i = 0;i < sb->nstr;i++) {
  690.                 int size = *(WORD *)p;p += sizeof(WORD);
  691.                 
  692.                 if (sizestr == size && !strnicmp(p,szstr,sizestr)) {
  693.                     sb->pfound = p - sizeof(WORD) - SB_OFFSET;
  694.                     ret = i;
  695.                     break;
  696.                 }
  697.                 p += size;
  698.                 if (sb->fCustData) p += sizeof(DWORD);//1.01A 
  699.             }
  700.         }
  701.     }
  702.     SB_UNLOCK;
  703.     return ret;
  704. }
  705.  
  706. BOOL TXAPI sbSearch(HSTRBLK sb,mchar *szstr)
  707. {
  708. // szstrを検索。見つかったかどうか返す
  709.     if (sbiSearch(sb,szstr) == -1) return FALSE;
  710.     return TRUE;
  711. }
  712.  
  713. static void pfoundDelete(HSTRBLK sb)
  714. {
  715.     SB_LOCK;
  716.     {
  717.         LPBYTE p = sb->pfound + SB_OFFSET;
  718.         int cbdel = sizeof(WORD) + *(WORD *)p;
  719.         if (sb->fCustData) cbdel += sizeof(DWORD);//1.01A 
  720.         {
  721.             int cbmove = sb->ptail + SB_OFFSET - p;
  722.             if (cbmove) memcpy(p,p + cbdel,cbmove);
  723.             sb->ptail -= cbdel;
  724.             sb->nstr--;
  725.         }
  726.     }
  727.     SB_UNLOCK;
  728. }
  729.  
  730. BOOL TXAPI sbDel(HSTRBLK sb,mchar *szstr)
  731. {
  732. // szstrを削除
  733.     BOOL ret = TRUE;
  734.     SB_LOCK;
  735.     {
  736.         int i = sbiSearch(sb,szstr);
  737.         if (i == -1) {
  738.             ret = FALSE;
  739.         } else {
  740.             pfoundDelete(sb);
  741.         }
  742.     }
  743.     SB_UNLOCK;
  744.     return ret;
  745. }
  746.  
  747. // 自分自身の文字列が渡されることがあるので注意
  748. mchar* TXAPI sbAddHist(HSTRBLK sb,mchar *szstr)
  749. {
  750. // szstrがすでにあれば、末尾に移動する
  751. // なければ末尾に追加する
  752.     mchar *ret;
  753.     SB_LOCK;
  754.     {
  755.         // 追加する
  756.         ret = sbAdd(sb,szstr);
  757.         if (!ret) {
  758.             // 追加できなかった
  759.             // reduceする
  760.             LPBYTE p = sb->buff;
  761.             BOOL freduce = FALSE;
  762.             int sizereduce = sb->sizebuff / 3;
  763.             int i;
  764.             
  765.             for (i = 0;i < sb->nstr;i++) {
  766.                 int size = p - sb->buff;
  767.                 if (size > sizereduce) {
  768.                     int size = sb->ptail - p;
  769.                     if (size > 0) {
  770.                         freduce = TRUE;
  771.                         memcpy(sb->buff + SB_OFFSET,p + SB_OFFSET,size);
  772.                         sb->ptail = sb->buff + size;
  773.                         sb->nstr -= i;
  774.                     }
  775.                     break;
  776.                 }
  777.                 p += sizeof(WORD) + *(WORD *)(p + SB_OFFSET);
  778.                 if (sb->fCustData) p += sizeof(DWORD);//1.01A 
  779.             }
  780.             if (!freduce) sbDelAll(sb);
  781.             //
  782.             ret = sbAdd(sb,szstr);
  783.             if (!ret) {
  784.                 // 追加できなかった
  785.                 sbDelAll(sb);
  786.                 ret = sbAdd(sb,szstr);// これでも追加できないこともある
  787.             }
  788.         }
  789.         if (sbiSearch(sb,szstr) == -1) ret = NULL;
  790.         if (ret) {
  791.             if (ret == sb->pfound + sizeof(WORD) + SB_OFFSET) {
  792.                 // OK
  793.             } else {
  794.                 // 重複した
  795.                 ret -= sizeof(WORD) + *(WORD *)(sb->pfound + SB_OFFSET);
  796.                 if (sb->fCustData) ret -= sizeof(DWORD);//1.01A 
  797.                 pfoundDelete(sb);
  798.             }
  799.         }
  800.     }
  801.     SB_UNLOCK;
  802.     return ret;
  803. }
  804.  
  805. int TXAPI sbGetCount(HSTRBLK sb)
  806. {
  807. // 文字列数を返す
  808.     int ret;
  809.     SB_LOCK;
  810.     ret = sb->nstr;
  811.     SB_UNLOCK;
  812.     return ret;
  813. }
  814.  
  815. mchar* TXAPI sbRead(HSTRBLK sb,int istr)
  816. {
  817. // i番目(0から(sbGetCount-1))の文字列を返す
  818.     mchar *ret = NULL;
  819.     SB_LOCK;
  820.     if (0 <= istr && istr < sb->nstr) {
  821.         LPBYTE p = sb->buff + SB_OFFSET;
  822.         int i;
  823.         
  824.         for (i = 0;i < istr;i++) {
  825.             p += sizeof(WORD) + *(WORD *)p;
  826.             if (sb->fCustData) p += sizeof(DWORD);//1.01A 
  827.         }
  828.         ret = p + sizeof(WORD);
  829.     }
  830.     SB_UNLOCK;
  831.     return ret;
  832. }
  833.  
  834. DWORD TXAPI sbReadCustdata(HSTRBLK sb,int istr)
  835. {
  836. // i番目(0から(sbGetCount-1))のCustDataを返す
  837. // 読みだせなければ0を返す
  838. //1.01A で追加
  839. //2.95 970131 sbReadCustData -> sbReadCustdata
  840.     DWORD ret = 0;
  841.     if (sb->fCustData) {
  842.         mchar *p;
  843.         
  844.         SB_LOCK;
  845.         p = sbRead(sb,istr);
  846.         if (p) ret = *(DWORD *)(p + *(WORD*)((LPBYTE)p - sizeof(WORD)));
  847.         SB_UNLOCK;
  848.     }
  849.     return ret;
  850. }
  851.  
  852. BOOL TXAPI sbWriteCustdata(HSTRBLK sb,int istr,DWORD CustData)
  853. {
  854. // i番目(0から(sbGetCount-1))のCustDataをセットする
  855. // セットできたかどうかを返す
  856. //1.01A で追加
  857.     BOOL ret = FALSE;
  858.     if (sb->fCustData) {
  859.         mchar *p;
  860.         
  861.         SB_LOCK;
  862.         p = sbRead(sb,istr);
  863.         if (p) {
  864.             *(DWORD *)(p + *(WORD*)((LPBYTE)p - sizeof(WORD))) = CustData;
  865.             ret = TRUE;
  866.         }
  867.         SB_UNLOCK;
  868.     }
  869.     return ret;
  870. }
  871.  
  872. BOOL TXAPI sbDelI(HSTRBLK sb,int i)
  873. {
  874. // i番目(0から(sbGetCount-1))の文字列を削除
  875.     BOOL ret = FALSE;
  876.     SB_LOCK;
  877.     {
  878.         mchar *p = sbRead(sb,i);
  879.         if (p) {
  880.             sb->pfound = p - sizeof(WORD) - SB_OFFSET;
  881.             pfoundDelete(sb);
  882.             ret = TRUE;
  883.         }
  884.     }
  885.     SB_UNLOCK;
  886.     return ret;
  887. }
  888.  
  889. mchar* TXAPI sbRead2(HSTRBLK sb,int istr,WORD *lchstr)
  890. {
  891. // i番目(0から(sbGetCount-1))の文字列を返す
  892. // sizestrに文字列のサイズ(最後のNULLも含む)を返す
  893.     mchar *p;
  894.     SB_LOCK;
  895.     p = sbRead(sb,istr);
  896.     if (p) *lchstr = *(WORD *)((LPBYTE)p - sizeof(WORD)) - sizeof(mchar);
  897.     SB_UNLOCK;
  898.     return p;
  899. }
  900.  
  901. int TXAPI sbiSearchPrev(HSTRBLK sb,mchar *szstr,int istr)
  902. {
  903. // istr-1から0までszstrを検索する
  904. // 見つからなければ-1を返す
  905. // szstrより長い文字列でも、先頭部分が一致すればOKとする
  906. // 大文字・小文字は区別しない
  907.     int sizestr = strlensize(szstr);
  908.     
  909.     SB_LOCK;
  910.     for (istr--;istr >= 0;istr--) {
  911.         if (!strnicmp(sbRead(sb,istr),szstr,sizestr)) {
  912.             SB_UNLOCK;
  913.             return istr;
  914.         }
  915.     }
  916.     SB_UNLOCK;
  917.     return -1;
  918. }
  919.  
  920. int TXAPI sbiSearchNext(HSTRBLK sb,mchar *szstr,int istr)
  921. {
  922. // istr+1からnstr-1までszstrを検索する
  923. // 見つからなければ-1を返す
  924. // szstrより長い文字列でも、先頭部分が一致すればOKとする
  925. // 大文字・小文字は区別しない
  926.     int sizestr = strlensize(szstr);
  927.     
  928.     SB_LOCK;
  929.     for (istr++;istr < sb->nstr;istr++) {
  930.         if (!strnicmp(sbRead(sb,istr),szstr,sizestr)) {
  931.             SB_UNLOCK;
  932.             return istr;
  933.         }
  934.     }
  935.     SB_UNLOCK;
  936.     return -1;
  937. }
  938.  
  939. BOOL TXAPI sbDelete(HSTRBLK sb)
  940. {
  941. // 破棄。不要になったら必ず呼んでください
  942.     if (!sb) return FALSE;
  943.     if (sb->fAlloc) free(sb->buff);//2.90 
  944.     if (!sb->fstatic) return contextDelete(sb);
  945.     return TRUE;
  946. }
  947.  
  948. HSTRBLK TXAPI sbFromHist(HANDLETX hist)
  949. {
  950. // histから、sbに変換。histがsbの場合はそのままhistを返す。
  951. // 2.90 で追加。
  952.     if (hist && (DWORD)hist < MAXHIST) {
  953.         return &text1->share->hist[(int)hist];
  954.     }
  955.     return hist;
  956. }
  957.  
  958. HANDLETX TXAPI sbToHist(HSTRBLK sb)
  959. {
  960. // sbからhistへ変換。sbがhistでなければ0を返す。
  961. // 2.90 で追加。
  962.     int i;
  963.     if (sb) {
  964.         for (i = 1;i < MAXHIST;i++) {
  965.             if ((HANDLETX)&text1->share->hist[i] == sb) return (HANDLETX)i;
  966.         }
  967.     }
  968.     return 0;
  969. }
  970.  
  971.  
  972. //##整数テーブル
  973. //2.90 
  974.  
  975. #ifdef __TXC__
  976. #export
  977. #ifndef __INTTABLE
  978. #define __INTTABLE
  979. typedef struct {
  980.     int sizeTable;
  981.     int n;
  982.     DWORD* table;
  983. } INTTABLE;
  984. #endif
  985. #endexport
  986. #endif
  987.  
  988. BOOL TXAPI itInit(INTTABLE* it,DWORD* table,int cbTable)
  989. {
  990. // 次の様に使用
  991. // INTTABLE it;
  992. // DWORD table[5];
  993. // itInit(&it,table,sizeof(table);
  994.     it->sizeTable = cbTable / sizeof(DWORD);
  995.     it->n = 0;
  996.     it->table = table;
  997.     return TRUE;
  998. }
  999.  
  1000. int TXAPI itiSearch(INTTABLE* it,DWORD val)
  1001. {
  1002.     int i;
  1003.     for (i = 0;i < it->n;i++) {
  1004.         if (it->table[i] == val) return i;
  1005.     }
  1006.     return -1;
  1007. }
  1008.  
  1009. BOOL TXAPI itSearch(INTTABLE* it,DWORD val)
  1010. {
  1011.     return (itiSearch(it,val) != -1);
  1012. }
  1013.  
  1014. BOOL TXAPI itAdd(INTTABLE* it,DWORD val)
  1015. {
  1016.     if (it->sizeTable == it->n) return FALSE;
  1017.     it->table[it->n] = val;
  1018.     it->n++;
  1019.     return TRUE;
  1020. }
  1021.  
  1022. BOOL TXAPI itDel(INTTABLE* it,DWORD val)
  1023. {
  1024.     int i = itiSearch(it,val);
  1025.     if (i != -1) {
  1026.         memcpy(it->table+i,it->table+i+1,(it->n-i-1)*sizeof(DWORD));
  1027.         it->n--;
  1028.         return TRUE;
  1029.     }
  1030.     return FALSE;
  1031. }
  1032.  
  1033. BOOL TXAPI itDelAll(INTTABLE* it)
  1034. {
  1035.     it->n = 0;
  1036.     return TRUE;
  1037. }
  1038.  
  1039. #endif    // __NOTX__
  1040.  
  1041. //{###文字操作}
  1042. //文字のタイプを返したり、各種変換機能を提供します。
  1043.  
  1044. #include "base.h"
  1045.  
  1046. #ifdef __TXC__
  1047. #export
  1048.  
  1049. #define _K1            0x01
  1050. #define    _K2            0x02
  1051. #define    _K12        (_K1|_K2)
  1052. #define    _KANA        0x04
  1053. #define __ALP        0x08
  1054. #define __NUM        0x10
  1055. #define __LOW        0x20
  1056. #define __SPC        0x40
  1057.  
  1058. #ifdef __TXC__
  1059. extern "std" {//1.00C iskanjiが使えないことがあった
  1060. #endif
  1061.     extern UCHAR tJctype[256];
  1062. #ifdef __TXC__
  1063. }
  1064. #endif
  1065.  
  1066. #define iskanji(c)    (tJctype[(UCHAR)(c)]&_K1)
  1067. #define iskanji2(c)    (tJctype[(UCHAR)(c)]&_K2)
  1068. #define iskana(c)    (tJctype[(UCHAR)(c)]&_KANA)
  1069. #endexport
  1070. #endif
  1071.  
  1072. UCHAR tJctype[256] = {
  1073.     0,0,0,0,0,0,0,0,    // 00
  1074.     0,__SPC,__SPC,__SPC,__SPC,__SPC,0,0,    // 08
  1075.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        // 10
  1076.     __SPC,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    // 20
  1077.     __NUM,__NUM,__NUM,__NUM,__NUM,__NUM,__NUM,__NUM,    // 30
  1078.     __NUM,__NUM,0,0,0,0,0,0,                            // 38
  1079.     _K2,_K2|__ALP,_K2|__ALP,_K2|__ALP,                    // 40
  1080.     _K2|__ALP,_K2|__ALP,_K2|__ALP,_K2|__ALP,            // 44
  1081.     _K2|__ALP,_K2|__ALP,_K2|__ALP,_K2|__ALP,            // 48
  1082.     _K2|__ALP,_K2|__ALP,_K2|__ALP,_K2|__ALP,            // 4C
  1083.     _K2|__ALP,_K2|__ALP,_K2|__ALP,_K2|__ALP,            // 50
  1084.     _K2|__ALP,_K2|__ALP,_K2|__ALP,_K2|__ALP,            // 54
  1085.     _K2|__ALP,_K2|__ALP,_K2|__ALP,_K2,                    // 58
  1086.     _K2,_K2,_K2,_K2,                                    // 5C
  1087.     _K2,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,                // 60
  1088.     _K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,    // 64
  1089.     _K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,    // 68
  1090.     _K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,    // 6C
  1091.     _K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,    // 70
  1092.     _K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,    // 74
  1093.     _K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2|__ALP|__LOW,_K2,                // 78
  1094.     _K2,_K2,_K2,0,        // 7C
  1095.     _K2,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,//80
  1096.     _K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,//90
  1097. //2.00E2 A0はiskanaではなくした
  1098.     _K2,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// A0
  1099.     _K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// A8
  1100.     _K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// B0
  1101.     _K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// B8
  1102.     _K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// C0
  1103.     _K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// C8
  1104.     _K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// D0
  1105.     _K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,_K2|_KANA,// D8
  1106.     _K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,//E0
  1107.     _K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,_K12,0,0,0,//F0
  1108. };
  1109.  
  1110.  
  1111. #ifdef __TXC__
  1112. #export
  1113. #ifdef __TXC__
  1114. #endexport
  1115.  
  1116. int TXAPIBASE isalnum(TXCHAR c)
  1117. {
  1118. // cが半角英数字かどうか返す
  1119. // 全角対応(isalnum('A')は0を返す)
  1120.     if (c < 0x100) {
  1121.         return (tJctype[c] & (__ALP|__NUM));
  1122.     }
  1123.     return 0;
  1124. }
  1125.  
  1126. int TXAPIBASE isalpha(TXCHAR c)
  1127. {
  1128. // cが半角英字かどうか返す
  1129. // 全角対応(isalpha('A')は0を返す)
  1130.     if (c < 0x100) {
  1131.         return (tJctype[c] & __ALP);
  1132.     }
  1133.     return 0;
  1134. }
  1135.  
  1136. int TXAPIBASE isdigit(TXCHAR c)
  1137. {
  1138. // cが半角数字かどうか返す
  1139. // 全角対応(isdigit('0')は0を返す)
  1140.     if (c < 0x100) {
  1141.         return (tJctype[c] & __NUM);
  1142.     }
  1143.     return 0;
  1144. }
  1145.  
  1146. int TXAPIBASE islower(TXCHAR c)
  1147. {
  1148. // cが半角英小文字かどうか返す
  1149. // 全角対応(islower('a')は0を返す)
  1150.     if (c < 0x100) {
  1151.         return ((tJctype[c] & (__ALP|__LOW)) == (__ALP|__LOW));
  1152.     }
  1153.     return 0;
  1154. }
  1155.  
  1156. int TXAPIBASE isupper(TXCHAR c)
  1157. {
  1158. // cが半角英大文字かどうか返す
  1159. // 全角対応(isupper('A')は0を返す)
  1160.     if (c < 0x100) {
  1161.         return ((tJctype[c] & (__ALP|__LOW)) == __ALP);
  1162.     }
  1163.     return 0;
  1164. }
  1165.  
  1166. int TXAPIBASE isspace(TXCHAR c)
  1167. {
  1168. // cが半角空白文字かどうか返す
  1169. // cがスペース、タブ、復帰、改行、垂直タブ、改ページ
  1170. // (0x20,0x09-0x0D)なら真を返す
  1171. // 全角対応(isspace(' ')は0を返す)
  1172.     if (c < 0x100) {
  1173.         return (tJctype[c] & __SPC);
  1174.     }
  1175.     if (c == '\n') return TRUE;    // CR+LF
  1176.     return 0;
  1177. }
  1178.  
  1179. int TXAPIBASE isreturn(TXCHAR c)
  1180. {
  1181. // cが改行文字かどうか返す
  1182. // cが'\n'か0x0Aか0x1A(EOF)なら真を返す
  1183. // 全角対応
  1184.     return (c == '\n' /* CR+LF */ || c == 0x0A || c == 0x1A);
  1185. }
  1186.  
  1187. int TXAPIBASE iseof(TXCHAR c)
  1188. {
  1189. // cがEOF文字(0x1A)なら真を返す
  1190. // 全角対応
  1191.     return (c == 0x1A);
  1192. }
  1193.  
  1194. int TXAPIBASE iszenkaku(TXCHAR c)
  1195. {
  1196. // cが全角文字なら真を返す
  1197.     if (c == '\n') return FALSE;    // CR+LF
  1198.     return (c >= 0x100);
  1199. }
  1200.  
  1201. TXCHAR TXAPIBASE toupper(TXCHAR c)
  1202. {
  1203. // cが半角英小文字なら、半角英大文字に変換して返す
  1204. // そうでなければcを返す
  1205. // 全角対応(toupper('a')は'a'を返す)
  1206.     if (c < 0x100 && (tJctype[c] & (__ALP|__LOW)) == (__ALP|__LOW)) {
  1207.         return c - 0x20;
  1208.     } else {
  1209.         return c;
  1210.     }
  1211. }
  1212.  
  1213. TXCHAR TXAPIBASE tolower(TXCHAR c)
  1214. {
  1215. // cが半角英大文字なら、半角英小文字に変換して返す
  1216. // そうでなければcを返す
  1217. // 全角対応(tolower('A')は'A'を返す)
  1218.     if (c < 0x100 && (tJctype[c] & (__ALP|__LOW)) == __ALP) {
  1219.         return c + 0x20;
  1220.     } else {
  1221.         return c;
  1222.     }
  1223. }
  1224.  
  1225. #export
  1226. #endif
  1227. #endexport
  1228. #endif
  1229.  
  1230. //{###文字列操作}
  1231.  
  1232. mchar* TXAPI strnext(mchar* szstr)
  1233. {
  1234. // szstrが差す文字の次の文字へのポインタを返します
  1235. // 漢字、2バイト目が0の漢字にも対応しています。
  1236. // szstrがヌル文字を差していればszstrをそのまま返します。
  1237. //1.90で新設
  1238.     mchar c;
  1239.     if (!szstr) return NULL;
  1240.     c = *szstr;
  1241.     if (iskanji(c) && szstr[1]) {
  1242.         return szstr + 2;
  1243.     }
  1244.     if (c == 0) return szstr;
  1245.     return szstr + 1;
  1246. }
  1247.  
  1248. mchar* TXAPI strprev(mchar* sztop,mchar* szstr)
  1249. {
  1250. // szstrが差す文字の前の文字へのポインタを返します
  1251. // sztopに文字列の先頭文字へのポインタを渡してください
  1252. // 漢字、2バイト目が0の漢字にも対応しています。
  1253. // szstrが文字列の先頭ならszstrをそのまま返します。
  1254. //3.00B1 970519 new
  1255.     if (!szstr) return NULL;
  1256.     if (szstr == sztop) return szstr;
  1257.     {
  1258.         mchar* p = sztop;
  1259.         mchar* p0 = p;
  1260.         while(1) {
  1261.             mchar c = *p;
  1262.             if (iskanji(c) && p[1]) {
  1263.                 p += 2;
  1264.             } else {
  1265.                 p++;
  1266.             }
  1267.             if (c == 0) break;
  1268.             if (p == szstr) break;
  1269.             p0 = p;
  1270.         }
  1271.         return p0;
  1272.     }
  1273. }
  1274.  
  1275. TXCHAR strread(mchar* szstr)
  1276. {
  1277. // *szstrが漢字ならMAKEWORD(szstr[1],szstr[0])、
  1278. // そうでなければ*szstrを返します。
  1279. //3.00B1 970519 new
  1280.     mchar c = *szstr;
  1281.     if (iskanji(c) && szstr[1]) {
  1282.         return MAKEWORD(szstr[1],c);
  1283.     }
  1284.     return c;
  1285. }
  1286.  
  1287. //{###ファイル名・パス名}
  1288. //ファイル名、パス名文字列の操作機能を提供します。
  1289. //フルパス指定からファイル名や拡張子を取り出したりセットしたりできます。
  1290.  
  1291. #ifndef __TXC__
  1292.     #include <string.h>
  1293.     #include <stdlib.h>
  1294.     #include <ctype.h>
  1295.     #include "base.h"
  1296. #endif
  1297.  
  1298. #ifdef __TXC__
  1299. #export
  1300. // パス名・ファイル名の最大長('\0'を含む)
  1301. #define CCHPATHNAME32    260            //1.98 WZ32のCCHPATHNAME
  1302. #ifdef __FLAT__
  1303.     #define CCHDRIVE        3        //1.00F ドライブ名の長さ
  1304.     #define CCHFILENAME        256        // "12345678.123\"等も平気
  1305.     #define CCHFILEEXT        256        // "."も含む拡張子の最大長
  1306.     #define CCHPATHNAME        260        // ファイル名も含む長さ絶対パスの最大長
  1307.     
  1308.     #define CCHSPATHNAME    260        //1.00F ファイル名も含む長さ絶対パスの最大長
  1309.     #define CCHAPPNAME        64
  1310. #else
  1311.     #define CCHDRIVE        3        //1.00F ドライブ名の長さ
  1312.     #define CCHFILENAME        14        // "12345678.123\"等も平気
  1313.     #define CCHFILEEXT        5        // "."も含む拡張子の最大長
  1314.     #define CCHPATHNAME        145        // ファイル名も含む長さ絶対パスの最大長
  1315.     
  1316.     #define CCHSPATHNAME    72        //1.00F そう長くはならない絶対パスの最大長(メモリ節約)
  1317.     #define CCHAPPNAME        64
  1318. #endif
  1319.  
  1320. #ifdef __TXC__
  1321. extern "tx" {
  1322. #endif
  1323. BOOL TXAPI txfullpath(mchar *dst,mchar *src);
  1324. #ifdef __TXC__
  1325. }
  1326. #endif
  1327.  
  1328. #endexport
  1329. #endif
  1330.  
  1331. ///#include "path.h"
  1332. #include "_filer.h"
  1333.  
  1334. mchar* TXAPIBASE pathGetExt(mchar *path)
  1335. {
  1336. // pathの拡張子へのポインタを返す
  1337. // path:"aaaa.bcd"や"aaaa."なら、'.'へのポインタを返す
  1338. // path:"aaaa"なら、'\0'(文字列ターミネータ)へのポインタを返す
  1339. //1.00F ディレクトリに拡張子が含まれていると誤動作していた
  1340.     mchar *p0 = NULL;
  1341.     mchar c;
  1342.     for (;c = *path;) {
  1343.         if (iskanji(c) && path[1]) {
  1344.             //1.99I 
  1345.             path += 2;
  1346.         } else {
  1347.             if (c == '.') p0 = path;
  1348.             if (c == '\\' || c == '/') p0 = NULL;//1.00F
  1349.             path++;
  1350.         }
  1351.     }
  1352.     if (p0) return p0;
  1353.     return path;
  1354. }
  1355.  
  1356. mchar* TXAPIBASE pathSetExt(mchar *path,mchar *ext)
  1357. {
  1358. // pathの拡張子をextに設定する
  1359. // ext:".bcd"や"."や""のように指定する
  1360. //3.00A3 970508 pathのサイズは最低CCHPATHNAMEであることを仮定しています。これを
  1361. // オーバーしないように設定します
  1362. #if 1///3.00A3 970508 
  1363.     mchar* p = pathGetExt(path);
  1364.     if (ext) {
  1365.         if ((p - path) + strlen(ext) >= CCHPATHNAME) return path;
  1366.         strcpy(p,ext);
  1367.     } else {
  1368.         *p = 0;
  1369.     }
  1370.     return path;
  1371. #else
  1372.     if (ext) {
  1373.         strcpy(pathGetExt(path),ext);
  1374.     } else {
  1375.         strcpy(pathGetExt(path),"");
  1376.     }
  1377.     return path;
  1378. #endif
  1379. }
  1380.  
  1381. BOOL TXAPIBASE pathIsExt(mchar *path,mchar *ext)
  1382. {
  1383. // pathの拡張子がextか返す
  1384. // pathGetExtの返り値とextをstricmpして結果を返す
  1385. // 一致でTRUE, 不一致でFALSEを返す
  1386.     return !stricmp(pathGetExt(path),ext);
  1387. }
  1388.  
  1389. BOOL TXAPI pathEquFileName(mchar *path,mchar *name)
  1390. {
  1391. // pathの拡張子を除くファイル名がnameか返す
  1392. // 一致でTRUE, 不一致でFALSEを返す
  1393. //1.00Cで追加
  1394.     mchar *p = pathGetFileName(path);
  1395. #if 1//2.96 970209 pathがNULLのときに必ずTRUEを返してしまっていた
  1396.     mchar *pend = pathGetExt(path);
  1397.     int lch = pend - p;
  1398.     return (!strnicmp(p,name,lch) && lch == strlen(name));
  1399. #else
  1400.     mchar *pend = pathGetExt(path);
  1401.     return !strnicmp(p,name,pend - p);
  1402. #endif
  1403. }
  1404.  
  1405. mchar* TXAPIBASE pathGetFileName(mchar *path)
  1406. {
  1407. // pathのファイル名を返す
  1408.     mchar *p = path;
  1409.     mchar *name;
  1410.     
  1411.     if (p[0] && p[1] == ':') p += 2;
  1412.     name = p;
  1413.     
  1414.     while(*p) {
  1415.         if (iskanji(*p)) {
  1416.             if (p[1]) {
  1417.                 p += 2;
  1418.             } else {
  1419.                 break;
  1420.             }
  1421.         } else {
  1422.             if (*p == '/' || *p == '\\') {
  1423.                 name = p + 1;
  1424.             }
  1425.             p++;
  1426.         }
  1427.     }
  1428.     
  1429.     return name;
  1430. }
  1431.  
  1432. BOOL TXAPI pathIsAutosave(mchar *szfilename)
  1433. {
  1434.     mchar*p = pathGetFileName(szfilename);
  1435.     return (p[0] == '$' && p[1] == '~');
  1436. }
  1437.  
  1438. UINT TXAPI pathGetDriveType(mchar* szfilename)
  1439. {
  1440. // szfilenameのドライブのドライブタイプを返します。
  1441. // szfilenameはフルパスで指定してください。
  1442.     if (isalpha(szfilename[0]) && szfilename[1] == ':') {//2.00B ドライブ名チェック強化
  1443. #ifdef __FLAT__
  1444.         mchar szdrive[3];
  1445.         strcpylen(szdrive,szfilename,2);
  1446.         return GetDriveType(szdrive);
  1447. #else
  1448.         int idrive = toupper(szfilename[0]) - 'A';
  1449.         return GetDriveType(idrive);
  1450. #endif
  1451.     }
  1452.     return 0;
  1453. }
  1454.  
  1455. int TXAPI ispathsepa(mchar c)
  1456. {
  1457. // cがパスセパレータ'/'か'\'ならTRUE、そうでなければFALSEを返します。
  1458.     return (c == '/' || c == '\\');
  1459. }
  1460.  
  1461. #ifndef __NOTX__
  1462.  
  1463. #ifdef __TXC__
  1464. #export
  1465. enum PATHMODE {PATH_RELATIVE,PATH_ABSOLUTE,PATH_ABSOLUTEDRIVE,PATH_URL};
  1466. #endexport
  1467. #endif
  1468.  
  1469. int TXAPI pathGetMode(mchar* szfilename)
  1470. {
  1471. // szfilenameのモードを返します。
  1472. // PATH_RELATIVE,PATH_ABSOLUTE,PATH_ABSOLUTEDRIVE,PATH_URLのいずれかを返します
  1473. //1.90で新設
  1474.     if (strstr(szfilename,"//")) return PATH_URL;
  1475.     if (szfilename[1] == ':') return PATH_ABSOLUTEDRIVE;
  1476.     if (szfilename[0] == '\\' || szfilename[0] == '/') return PATH_ABSOLUTE;
  1477.     return PATH_RELATIVE;
  1478. }
  1479.  
  1480. mchar* TXAPI pathSepa(mchar* szstr)
  1481. {
  1482. // szstrからパスセパレータ'/'と'\'を探し、最初に見つけたパスセパレータを返す
  1483. // なければNULLを返す
  1484. //1.90で新設
  1485.     mchar c;
  1486.     while(c = *szstr) {
  1487.         if (ispathsepa(c)) return szstr;
  1488.         if (iskanji(c) && szstr[1]) {
  1489.             szstr += 2;
  1490.         } else {
  1491.             szstr++;
  1492.         }
  1493.     }
  1494.     return NULL;
  1495. }
  1496.  
  1497. void TXAPI pathFlushSepa(mchar* szstr,int ch)
  1498. {
  1499. // szstrのパスセパレータをchにセットします
  1500. //1.90で新設
  1501.     mchar*p = szstr;
  1502.     while(p = pathSepa(p)) {
  1503.         *p = ch;
  1504.         p++;
  1505.     }
  1506. }
  1507.  
  1508. int TXAPI pathCmp(mchar* szpath1,mchar* szpath2,int *plch)
  1509. {
  1510. // strcmpと同じ様にszpath1とszpath2を比較します。
  1511. // パスセパレータ'\'と'/'は、同一文字として比較します。
  1512. // plchがNULLでなければマッチした文字数をplchに返します。
  1513. //1.90で新設
  1514. //2.98 970307 "c:\wz"と"c:\wz\std"でも一致しまっていた
  1515.     int d = 0;
  1516.     mchar*p1 = szpath1;
  1517.     mchar*p2 = szpath2;
  1518.     while(1) {
  1519.         mchar c1 = *p1;
  1520.         mchar c2 = *p2;
  1521.         if (c1 && c2) {
  1522.             if (iskanji(c1)) {
  1523.                 if (iskanji(c2)) {
  1524.                     d = p1[1] - p2[1];
  1525.                     if (d != 0) break;
  1526.                     p1 += 2;
  1527.                     p2 += 2;
  1528.                 } else {
  1529.                     d = c1 - c2;
  1530.                     break;
  1531.                 }
  1532.             } else if (iskanji(c2)) {
  1533.                 d = c1 - c2;
  1534.                 break;
  1535.             } else if (c1 == '\\' || c1 == '/') {
  1536.                 if (c2 == '\\' || c2 == '/') {
  1537.                     p1++;
  1538.                     p2++;
  1539.                 } else {
  1540.                     d = c1 - c2;
  1541.                     break;
  1542.                 }
  1543.             } else {
  1544.                 d = toupper(c1) - toupper(c2);
  1545.                 if (d != 0) break;
  1546.                 p1++;
  1547.                 p2++;
  1548.             }
  1549.         } else {
  1550.             d = c1 - c2;
  1551.             break;
  1552.         }
  1553.     }
  1554.     if (plch) *plch = p1 - szpath1;
  1555.     return d;
  1556. }
  1557.  
  1558. int TXAPI pathCmpN(mchar* szpath1,mchar* szpath2,int lch,int *plch)
  1559. {
  1560. // strncmpと同じ様にszpath1とszpath2を比較します。
  1561. // パスセパレータ'\'と'/'は、同一文字として比較します。
  1562. // plchがNULLでなければマッチした文字数をplchに返します。
  1563. //1.90で新設
  1564.     mchar buff1[CCHPATHNAME];
  1565.     mchar buff2[CCHPATHNAME];
  1566.     strcpy(buff1,szpath1);
  1567.     strcpy(buff2,szpath2);
  1568.     buff1[lch] = 0;
  1569.     buff2[lch] = 0;
  1570.     return pathCmp(buff1,buff2,plch);
  1571. }
  1572.  
  1573. int TXAPI pathSetMode(mchar* szfilename,mchar* szbase,mchar* szaddress,int mode)
  1574. {
  1575. // szfilenameのモードを設定します。
  1576. // modeにはPATH_RELATIVE,PATH_ABSOLUTE,PATH_ABSOLUTEDRIVE,PATH_URLのいずれかを指定します。
  1577. // szbaseにはベースディレクトリ、szaddressには、PATH_URLの場合サーバとドネインを指定します。
  1578. //1.90で新設
  1579. //3.00A3 970508 szfilenameのサイズは最低CCHPATHNAMEであることを仮定しています。これを
  1580. // オーバーしないように設定します
  1581.     mchar szabs[CCHPATHNAME];
  1582.     mchar buff[CCHPATHNAME];
  1583.     // setup szabs
  1584.     strcpy(szabs,szfilename);
  1585.     {
  1586.         mchar* p = strstr(szabs,"//");
  1587.         if (p) {
  1588.             p = pathSepa(p+2);
  1589.             if (p) {
  1590.                 strcpy(szabs,p);
  1591.             }
  1592.         }
  1593.     }
  1594.     strcpy(buff,szbase);
  1595.     pathSetFileName(buff,szabs);
  1596.     strcpy(szabs,buff);
  1597.     // szfilenameにはszabsからドライブ名を除いたものをセット
  1598.     if (szabs[1] == ':') {
  1599.         strcpy(szfilename,&szabs[2]);
  1600.     } else {
  1601.         strcpy(szfilename,szabs);
  1602.     }
  1603.     //
  1604.     switch(mode) {
  1605.         case PATH_ABSOLUTEDRIVE: {
  1606.             strcpy(szfilename,szabs);
  1607.             break;
  1608.         }
  1609.         case PATH_ABSOLUTE: {
  1610.             break;
  1611.         }
  1612.         case PATH_URL: {
  1613. #if 1//3.00A3 970508 
  1614.             strcpy(buff,"http://");
  1615.             if (strlen(buff) + (szaddress ? strlen(szaddress) : 0) + strlen(szfilename) >= CCHPATHNAME) {
  1616.                 // overflow
  1617.             } else {
  1618.                 if (szaddress) strcat(buff,szaddress);
  1619.                 strcat(buff,szfilename);
  1620.             }
  1621.             //
  1622.             strcpy(szfilename,buff);
  1623.             pathFlushSepa(szfilename,'/');
  1624.             return TRUE;
  1625. #else
  1626.             strcpy(buff,"http://");
  1627.             if (szaddress) {
  1628.                 strcat(buff,szaddress);
  1629.             }
  1630.             strcat(buff,szfilename);
  1631.             //
  1632.             strcpy(szfilename,buff);
  1633.             pathFlushSepa(szfilename,'/');
  1634.             return TRUE;
  1635. #endif
  1636.         }
  1637.         case PATH_RELATIVE: {
  1638.             mchar* p1 = (szbase[1] == ':') ? &szbase[2] : szbase;
  1639.             mchar* p2 = (szabs[1] == ':') ? &szabs[2] : szabs;
  1640.             mchar* dst = szfilename;
  1641.             BOOL f = TRUE;
  1642.             while(*p1 && *p2) {
  1643.                 p1++;
  1644.                 if (f) p2++;
  1645.                 {
  1646.                     mchar* p1a = pathSepa(p1);
  1647.                     mchar* p2a = p2;
  1648.                     if (f) {
  1649.                         p2a = pathSepa(p2);
  1650.                         if (!p2a) p2a = "";
  1651.                     }
  1652.                     if (!p1a) {
  1653.                         if ((dst - szfilename) + strlen(p2) >= CCHPATHNAME) break;//3.00A3 970508 
  1654.                         strcpy(dst,p2);
  1655.                         dst += strlen(dst);
  1656.                         break;
  1657.                     }
  1658.                     if (f) {
  1659.                         int lch1 = p1a - p1;
  1660.                         int lch2 = p2a - p2;
  1661.                         if (lch1 == lch2 && !strnicmp(p1,p2,lch1)) {
  1662.                             // 一致
  1663.                         } else {
  1664.                             f = FALSE;
  1665.                             if ((dst - szfilename) + 3 >= CCHPATHNAME) break;//3.00A3 970508 
  1666.                             strcpy(dst,"..\\");
  1667.                             dst += 3;
  1668.                         }
  1669.                     } else {
  1670.                         if ((dst - szfilename) + 3 >= CCHPATHNAME) break;//3.00A3 970508 
  1671.                         strcpy(dst,"..\\");
  1672.                         dst += 3;
  1673.                     }
  1674.                     p1 = p1a;
  1675.                     if (f) p2 = p2a;
  1676.                 }
  1677.             }
  1678.             *dst = 0;
  1679.             break;
  1680.         }
  1681.         default: {
  1682.             return FALSE;
  1683.         }
  1684.     }
  1685.     pathFlushSepa(szfilename,(textf->crSave == RETURNCODE_LF) ? '/' : '\\');//2.99C 970324 text1->textf
  1686.     return TRUE;
  1687. }
  1688.  
  1689. mchar* TXAPI pathToWz(mchar *szpath)
  1690. {
  1691. // szpathがWZディレクトリ内を指すものであれば、wz:\形式に変換します。
  1692. // そうでなければ何もしません
  1693. // szpathを返します
  1694. //3.00A3 970508 szpathのサイズは最低CCHPATHNAMEであることを仮定しています。これを
  1695. // オーバーしないように設定します
  1696.     if (szpath) {
  1697.         int len = strlen(text1->szexedir);
  1698.         if (!strnicmp(szpath,text1->szexedir,len)) {
  1699.             // text1->szexedirは"wz:\"より絶対長いはずなので、szbuffをオーバーすることはない
  1700.             mchar szbuff[CCHPATHNAME];
  1701.             strcpy(szbuff,"wz:\\");
  1702.             strcat(szbuff,szpath + len);
  1703.             strcpy(szpath,szbuff);
  1704.         }
  1705.     }
  1706.     return szpath;
  1707. }
  1708.  
  1709. #endif    // __NOTX__
  1710.  
  1711. void TXAPI pathFlush(mchar* szstr)
  1712. {
  1713. // szstrに"..\"が含まれていたら適切に処理して取り除ければ取り除きます
  1714. //1.90で新設
  1715.     int tsepa[100];
  1716.     int nsepa = 0;
  1717.     mchar*p = szstr;
  1718.     while(*p) {
  1719.         if (*p == '.' && p[1] == '.' && ispathsepa(p[2]) && nsepa >= 2) {
  1720.             mchar* p0 = szstr+tsepa[nsepa-2];
  1721.             nsepa -= 2;
  1722.             strcpy(p0,&p[2]);
  1723.             p = p0;
  1724.         } else {
  1725.             if (ispathsepa(*p)) {
  1726.                 if (nsepa == 100) break;    // overflow
  1727.                 tsepa[nsepa++] = p - szstr;
  1728.             }
  1729.             p = strnext(p);
  1730.         }
  1731.     }
  1732. }
  1733.  
  1734. mchar* TXAPIBASE pathSetFileName(mchar *path,mchar *filename)
  1735. {
  1736. // pathのファイル名をfilenameに設定します
  1737. // filenameにドライブ名付き絶対パス、絶対パス、
  1738. // "wz:\","win:\"付きパスを指定することもできます
  1739. //1.90 "..\"に対応
  1740. //2.00B "%{date}","%{year}","%{month}","%{day}"で
  1741. // 現在の日付,年,月,日を指定できます。
  1742. // "windrive:\"付きパスを指定することもできます
  1743. // "..\"を含めることもできます
  1744. //3.00A3 970508 pathのサイズは最低CCHPATHNAMEであることを仮定しています。これを
  1745. // オーバーしないように設定します
  1746.     if (!filename) {
  1747.         strcpy(pathGetFileName(path),"");
  1748.     } else {
  1749.         mchar top = filename[0];
  1750.         int lchFilename = strlen(filename);//3.00A3 970508 
  1751.         if (lchFilename + 2 >= CCHPATHNAME) return path;//3.00A3 970508 
  1752.         if (isalpha(top) && filename[1] == ':') {
  1753.             // ドライブ名が付いている
  1754.             strcpy(path,filename);
  1755.         } else if (ispathsepa(top)) {
  1756.             // 先頭が'\'だ。
  1757.             if (isalpha(*path) && path[1] == ':') {
  1758.                 strcpy(path + 2,filename);
  1759.             } else {
  1760.                 strcpy(path,filename);
  1761.             }
  1762. #ifndef __NOTX__
  1763.         } else if (!strnicmp(filename,"wz:\\",4)) {
  1764.             // "wz:\"
  1765.             strcpy(path,text1->szexedir);
  1766.             if (strlen(path) + lchFilename >= CCHPATHNAME) return path;//3.00A3 970508 
  1767.             strcat(path,filename + 4);
  1768.         } else if (!strnicmp(filename,"win:\\",5)) {
  1769.             // "win:\"
  1770.             GetWindowsDirectory(path,CCHPATHNAME);
  1771.             if (strlen(path) + lchFilename >= CCHPATHNAME) return path;//3.00A3 970508 
  1772.             strcat(path,filename + 5);
  1773.         } else if (!strnicmp(filename,"windrive:\\",10)) {
  1774.             // "windrive:\"
  1775.             GetWindowsDirectory(path,CCHPATHNAME);
  1776.             if (strlen(path) + lchFilename >= CCHPATHNAME) return path;//3.00A3 970508 
  1777.             strcpy(path + 3,filename + 10);
  1778. #endif
  1779.         } else {
  1780. #if 1//3.00A3 970508 
  1781.             mchar* p = pathGetFileName(path);
  1782.             if ((p - path) + lchFilename >= CCHPATHNAME) return path;//3.00A3 970508 
  1783.             strcpy(p,filename);
  1784. #else
  1785.             strcpy(pathGetFileName(path),filename);
  1786. #endif
  1787.         }
  1788.     }
  1789.     pathFlush(path);//1.90 
  1790. #ifndef __NOTX__
  1791.     //2.00B
  1792.     if (strchr(path,'%')) {
  1793.         mchar* src = path;
  1794.         TIME time;
  1795.         TM tm;
  1796.         timeGet(&time);
  1797.         timeGetLocal(&tm,&time);
  1798.         while(1) {
  1799.             src = strchr(src,'%');
  1800.             if (!src) break;
  1801.             {
  1802.                 // 必ず置換後の方が文字列の長さが変わらないか短くなること
  1803.                 int len = 0;
  1804.                 if (len = strmatch(src,"%{date}")) {
  1805.                     sprintf(src,"%02d%02d%02d",tm.tm_year,tm.tm_mon + 1,tm.tm_mday);
  1806.                 } else if (len = strmatch(src,"%{year}")) {
  1807.                     sprintf(src,"%02d",tm.tm_year);
  1808.                 } else if (len = strmatch(src,"%{month}")) {
  1809.                     sprintf(src,"%02d",tm.tm_mon + 1);
  1810.                 } else if (len = strmatch(src,"%{day}")) {
  1811.                     sprintf(src,"%02d",tm.tm_mday);
  1812.                 }
  1813.                 if (len) {
  1814.                     int lenPrint = strlen(src);
  1815.                     strcpy(src + lenPrint,src + len);
  1816.                     src += len;
  1817.                 } else {
  1818.                     src++;
  1819.                 }
  1820.             }
  1821.         }
  1822.     }
  1823. #endif
  1824.     return path;
  1825. }
  1826.  
  1827. BOOL TXAPI pathGetFull(mchar *path)
  1828. {
  1829. // pathが絶対パスかどうか返します。
  1830. // pathの先頭部分が、"ドライブ名:\","ドライブ名:/","\\"かどうかで判断しています。
  1831. //2.00B UNC対応
  1832.     if (isalpha(path[0]) && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) return TRUE;
  1833.     if (path[0] == '\\' && path[1] == '\\') return TRUE;
  1834.     return FALSE;
  1835. }
  1836.  
  1837. BOOL TXAPI pathFormDir(mchar *path)
  1838. {
  1839. // pathの最後がパスセパレータで終わっていたら、取り除いてTRUEを返す
  1840. // そうでなければFALSEを返す
  1841.     mchar *p = strGetLast(path);
  1842.     if (ispathsepa(*p)) {
  1843.         *p = 0;
  1844.         return TRUE;
  1845.     }
  1846.     return FALSE;
  1847. }
  1848.  
  1849. #ifndef __NOTX__
  1850.  
  1851. void TXAPI pathSetDir(mchar *path)
  1852. {
  1853. // pathの最後がパスセパレータで終わっていなければ、パスセパレータを追加する
  1854. //3.00A3 970508 pathのサイズは最低CCHPATHNAMEであることを仮定しています。これを
  1855. // オーバーしないように設定します
  1856.     mchar *p = strGetLast(path);
  1857.     if (!ispathsepa(*p)) {
  1858.         if (strlen(path) + 1 >= CCHPATHNAME) return;//3.00A3 970508 
  1859.         if (textf->crSave == RETURNCODE_LF) {//2.99C 970324 text1->textf
  1860.             strcat(path,"/");
  1861.         } else {
  1862.             strcat(path,"\\");//1.00C pathSetDirプログラムミス
  1863.         }
  1864.     }
  1865. }
  1866.  
  1867. #endif// __NOTX__
  1868.  
  1869. //1.00H2 
  1870. BOOL TXAPIBASE pathFormLong(mchar *path)
  1871. {
  1872. // pathが、["ファイル名"],["ファイル名],[ファイル名"]のときは、
  1873. // pathに[ファイル名]をセットしTRUEを返します。
  1874. // そうでなければFALSEを返します
  1875.     BOOL ret = FALSE;
  1876.     int len = strlen(path);
  1877.     
  1878.     if (path[0] == '"') {
  1879.         if (len >= 2 && path[len-1] == '"') len--;
  1880.         strcpylen(path,&path[1],len-1);
  1881.         return TRUE;
  1882.     } else if (len && path[len-1] == '"') {
  1883.         path[len-1] = 0;
  1884.         return TRUE;
  1885.     }
  1886.     return FALSE;
  1887. }
  1888.  
  1889. //1.00H2 
  1890. mchar* TXAPIBASE pathSetLong(mchar *path)
  1891. {
  1892. // pathを""で括ります。
  1893. // strlen(path)が最大2文字増加しますので、これに見合った長さのバッファのポインタを
  1894. // pathに指定してください。
  1895. // pathを返します
  1896. //3.00A3 970508 pathのサイズは最低CCHPATHNAMEであることを仮定しています。これを
  1897. // オーバーしないように設定します
  1898.     mchar szbuff[CCHPATHNAME];
  1899.     mchar *dst = szbuff;
  1900.     int len = strlen(path);
  1901.     if (len + 2 >= CCHPATHNAME) return path;//3.00A3 970508 
  1902.     *dst++ = '"';
  1903.     strcpy(dst,path);dst += len;
  1904.     *dst++ = '"';
  1905.     *dst = 0;
  1906.     strcpy(path,szbuff);
  1907.     return path;
  1908. }
  1909.  
  1910. void TXAPI pathForm(mchar *path)
  1911. {
  1912. // pathをDOSのパス形式に変換
  1913. // "a:\wz\wz.exe" -> "a:\wz"
  1914. // "a:\abc"       -> "a:\"
  1915.     mchar *p;
  1916.     pathSetFileName(path,0);
  1917.     p = strGetLast(path);
  1918.     if (*p == '\\' || *p == '/') {
  1919.         if (strlen(path) == 3) return;    // "a:\"はそのまま返す
  1920.         *p = 0;    // 末尾の"\"を除いて返す
  1921.     }
  1922. }
  1923.  
  1924. #ifdef __NOTX__
  1925. //    typedef struct find_t FILEFIND;
  1926.     #define fileFindFirst        _dos_findfirst
  1927.     #define fileFindNext        _dos_findnext
  1928.     #define txfullpath(dst,src)    _fullpath(dst,src,CCHPATHNAME)
  1929. #endif
  1930.  
  1931. BOOL TXAPI pathIsDirectory(mchar *path)
  1932. {
  1933. // pathがディレクトリかどうか返す
  1934. // pathがディレクトリでないか存在しなければFALSEを返す
  1935. //1.00Fで追加
  1936. #ifdef __FLAT__
  1937.     {
  1938.         BOOL ret = FALSE;
  1939.         WIN32_FIND_DATA ffd;
  1940.         HANDLE hfind = FindFirstFile(path,&ffd);
  1941.         if (hfind != INVALID_HANDLE_VALUE) {
  1942.             if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ret = TRUE;
  1943.             FindClose(hfind);
  1944.         }
  1945.         return ret;
  1946.     }
  1947. #else
  1948.     {
  1949.         FILEFIND find;
  1950.         
  1951.         if (!fileFindFirst(path,FA_DIREC,&find)) {
  1952.             if (find.attrib & FA_DIREC) return TRUE;
  1953.         }
  1954.     }
  1955. #endif
  1956.     return FALSE;
  1957. }
  1958.  
  1959. BOOL TXAPI pathIsWild(mchar *path)
  1960. {
  1961. // pathが'*','?',を含んでいたらTRUEを返す
  1962.     if (strchr(path,'*') || strchr(path,'?')) return TRUE;
  1963.     return FALSE;
  1964. }
  1965.  
  1966. BOOL TXAPI pathIsFileName(mchar *path)
  1967. {
  1968. // パス指定がファイルかどうか返す
  1969. // pathが""だったり、'*','?',';'を含んでたり、
  1970. // ディレクトリだったらFALSEを返す
  1971. // そうでなければTRUEを返す
  1972.     if (!path || !path[0]) return FALSE;
  1973.     if (pathIsWild(path)) return FALSE;
  1974.     if (strchr(path,';')) return FALSE;
  1975.     {
  1976.         mchar c = *strGetLast(path);
  1977.         if (c == '\\' || c == '/' || c == ':') return FALSE;
  1978.     }
  1979.     if (pathIsDirectory(path)) return FALSE;
  1980.     return TRUE;
  1981. }
  1982.  
  1983. BOOL TXAPI pathDirExist(mchar *path)
  1984. {
  1985. // pathのディレクトリが存在するか返す
  1986. // pathは、DOSのパス形式で指定
  1987. // pathが、"a:\"のようなドライブ指定なら、必ずTRUEを返す
  1988. // そうでなければ、実際にディレクトリがあるか調べる
  1989.     if (!path || !path[0]) return FALSE;
  1990.     if (isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && path[3] == 0) return TRUE;
  1991.     if (pathIsDirectory(path)) return TRUE;
  1992.     return FALSE;
  1993. }
  1994.  
  1995. mchar* TXAPI pathSetFull(mchar *path)
  1996. {
  1997. // pathを絶対パスに変換
  1998. //3.00A3 970508 pathのサイズは最低CCHPATHNAMEであることを仮定しています。これを
  1999. // オーバーしないように設定します
  2000.     mchar src[CCHPATHNAME];
  2001.     mchar dst[CCHPATHNAME];
  2002.     
  2003.     strcpy(src,path);
  2004.     {
  2005.         mchar *p = pathGetFileName(src);
  2006.         
  2007.         if (*p == 0) {
  2008.             // "xxx\"のように'\'で終わるなら"*.*"を追加。こうしないと駄目
  2009.             pathSetFileName(src,"*.*");
  2010.         }
  2011.     }
  2012.     if (txfullpath(dst,src)) {
  2013.         strcpy(path,dst);
  2014.     } else {
  2015.         *path = 0;
  2016.     }
  2017.     return path;
  2018. }
  2019.  
  2020. BOOL TXAPI pathSearchExt(mchar *szdst,mchar *szenvext)
  2021. {
  2022. // szdstの拡張子を、szenvextリストにセットして検索する
  2023. // 見つかったかどうか返す
  2024. // szdstの拡張子を変更する
  2025. //3.00A3 970508 szdstのサイズは最低CCHPATHNAMEであることを仮定しています。これを
  2026. // オーバーしないように設定します
  2027.     mchar *szext = pathGetExt(szdst);
  2028.     int cchRemain = CCHPATHNAME - (szext - szdst);//3.00A3 970508 
  2029.     mchar *src = szenvext;
  2030.     mchar *src0 = src;
  2031.     BOOL fexit = FALSE;
  2032.     if (szext[0] == '.' || !szenvext) {
  2033.         OFSTRUCT of;
  2034.         if (OpenFile(szdst,&of,OF_EXIST) != HFILE_ERROR) {
  2035.             return TRUE;
  2036.         }
  2037.         return FALSE;
  2038.     }
  2039.     while(!fexit) {
  2040.         int len;
  2041.         src = strchr(src,';');
  2042.         if (!src) src = strchr(src0,' ');
  2043.         if (src == NULL) {
  2044.             fexit = TRUE;
  2045.             src = szenvext + strlen(szenvext);
  2046.         }
  2047.         len = src-src0;
  2048. #if 1//3.00A3 970508 
  2049.         strcpylenmax(szext,src0,len,cchRemain);
  2050. #else
  2051.         mcharcpy(szext,src0,len);szext[len] = 0;
  2052. #endif
  2053.         {
  2054.             OFSTRUCT of;
  2055.             if (OpenFile(szdst,&of,OF_EXIST) != HFILE_ERROR) {
  2056.                 return TRUE;
  2057.             }
  2058.         }
  2059.         //
  2060.         src++;
  2061.         src0 = src;
  2062.     }
  2063.     return FALSE;
  2064. }
  2065.  
  2066. #ifndef __NOTX__
  2067.  
  2068. mchar* TXAPI pathEnvWalk(mchar* szenvpath,mchar* szdst)
  2069. {
  2070. //パス指定szenvpathを解析し、1つずつ取り出します。
  2071. //結果をszdstに返します。次に調べるべきパス指定を返します。
  2072. //なければNULLを返します。
  2073. //使い方:std.cのpathSearchを参考にしてください。
  2074.     mchar *p = szenvpath;
  2075.     if (!p) return NULL;
  2076.     while(1) {
  2077.         if (*p == ';' || *p == ' ') {
  2078.             p++;
  2079.         } else if (*p == 0) {
  2080.             return NULL;
  2081.         } else {
  2082.             break;
  2083.         }
  2084.     }
  2085.     {
  2086.         mchar *p0 = p;
  2087.         mchar c0 = 0;
  2088.         mchar c;
  2089.         int lchexedir = strlen(text1->szexedir) - 1;
  2090.         szdst[0] = 0;    // 初期化 for error時
  2091.         
  2092.         for(;;c0 = c,p++) {
  2093.             c = *p;
  2094.             if (iskanji(c)) {
  2095.                 p++;
  2096.             } else if (c == ';' || c == ' ' || c == 0) {
  2097.                 mchar *dst = szdst;
  2098.                 int len = p - p0;
  2099.                 
  2100.                 if (len >= 3 && !strnicmp(p0,"wz:",3)) {
  2101.                     if (!(lchexedir + (len - 3) + 1 >= CCHPATHNAME)) {
  2102.                         mcharcpy(dst,text1->szexedir,lchexedir);dst+=lchexedir;
  2103.                         mcharcpy(dst,p0+3,len-3);dst+=len-3;
  2104.                     }
  2105.                 } else {
  2106.                     if (!(len + 1 >= CCHPATHNAME)) {
  2107.                         mcharcpy(dst,p0,len);dst+=len;
  2108.                     }
  2109.                 }
  2110.                 if (c0 != '\\' && c0 != '/') *dst++ = '\\';
  2111.                 *dst = 0;
  2112.                 return p;
  2113.             }
  2114.         }
  2115.     }
  2116. }
  2117.  
  2118. BOOL TXAPI pathSearch(mchar *szdst,mchar *szpath,mchar *szenvpath,mchar *szenvext)
  2119. {
  2120. // szpathを検索し、szdstに結果を入れる
  2121. // ファイルが見つかったかどうかを返す
  2122. //3.00A3 970508 szdstのサイズは最低CCHPATHNAMEであることを仮定しています。これを
  2123. // オーバーしないように設定します
  2124. #ifndef __TXC__
  2125.     TX* text = text1;
  2126. #endif
  2127.     int lchPath = strlen(szpath);//3.00A3 970508 
  2128.     if (lchPath >= CCHPATHNAME) return FALSE;//3.00A3 970508 
  2129.     if (pathGetFull(szpath)) {
  2130.         // フルパス
  2131.         strcpy(szdst,szpath);
  2132.         return pathSearchExt(szdst,szenvext);
  2133.     } else if (!strnicmp(szpath,"wz:\\",4)) {
  2134.         // フルパス(wz:\)
  2135.         strcpy(szdst,text->szexedir);
  2136.         if (strlen(szdst) + lchPath >= CCHPATHNAME) return FALSE;//3.00A3 970508 
  2137.         strcat(szdst,szpath+4);
  2138.         return pathSearchExt(szdst,szenvext);
  2139.     } else {
  2140.         mchar *p = szenvpath;
  2141.         while(1) {
  2142.             p = pathEnvWalk(p,szdst);
  2143.             if (!p) break;
  2144.             if (strlen(szdst) + lchPath >= CCHPATHNAME) return FALSE;//3.00A3 970508 
  2145.             strcat(szdst,szpath);
  2146.             if (pathSearchExt(szdst,szenvext)) return TRUE;
  2147.         }
  2148.     }
  2149.     szdst[0] = 0;
  2150.     return FALSE;
  2151. }
  2152.  
  2153. BOOL TXAPI pathIsIncluded(mchar *szfilename,mchar *szenvpath)
  2154. {
  2155. // szfilenameのファイルのディレクトリが、
  2156. // szenvpathのパス指定に含まれているか返します
  2157. // szfilenameにはフルパスを指定してください。
  2158. // ファイル名はダミーでもいいですから指定して下さい。
  2159. //{#EX}pathIsIncluded(\"a:\wz\std\apidb.c",\"a:\wz\std");はTRUEを返します
  2160. //1.00Cで追加
  2161.     mchar szsrc[CCHPATHNAME];
  2162.     strcpy(szsrc,szfilename);
  2163.     pathSetFileName(szsrc,NULL);
  2164.     {
  2165.         mchar szdst[CCHPATHNAME];
  2166.         mchar *p = szenvpath;
  2167.         while(1) {
  2168.             p = pathEnvWalk(p,szdst);
  2169.             if (!p) return FALSE;
  2170.             if (!stricmp(szsrc,szdst)) return TRUE;
  2171.         }
  2172.     }
  2173. }
  2174.  
  2175. #endif// __NOTX__
  2176.  
  2177. BOOL TXAPIBASE fileIsExist(mchar *_szfilename)
  2178. {
  2179. // szsrcのファイルが存在するかどうか返します。
  2180. // ファイル名は""でくくってあっても構いません。
  2181.     mchar szfilename[CCHPATHNAME];
  2182.     strcpy(szfilename,_szfilename);
  2183.     pathFormLong(szfilename);//1.00H2 
  2184. #if 1
  2185. {
  2186.     //1.01A fileIsExist:ファイルが存在してもオープンできないときはFALSEを返していたのを修正
  2187.     BOOL ret = FALSE;
  2188.     #ifdef __FLAT__
  2189.         WIN32_FIND_DATA ffd;
  2190.         HANDLE hfind = FindFirstFile(szfilename,&ffd);
  2191.         if (hfind != INVALID_HANDLE_VALUE) {
  2192.             ret = TRUE;
  2193.             FindClose(hfind);
  2194.         }
  2195.     #else
  2196.         FILEFIND filefind;
  2197.         if (!fileFindFirst(szfilename,FA_NORMAL,&filefind)) {
  2198.             ret = TRUE;
  2199.         }
  2200.     #endif
  2201.     return ret;
  2202. }
  2203. #else
  2204.     {
  2205.         HFILE hf = hfileOpen(szfilename);
  2206.         if (hf != HFILE_ERROR) {
  2207.             hfileClose(hf);
  2208.             return TRUE;
  2209.         }
  2210.     }
  2211.     return FALSE;
  2212. #endif
  2213. }
  2214.  
  2215. #ifndef __NOTX__
  2216.  
  2217. void TXAPI pathAuto(mchar* szfilename,mchar* szenvpath,mchar* szenvext)
  2218. {
  2219. // WZ Editorのパス検索と同じ機能を提供
  2220.     if (szfilename && szfilename[0]) {
  2221.         if (!textf->fNoTextPathSearch) {//2.99C 970324 text1->textf
  2222. #if 1    //2.99C 970323 szfilenameがフルパスでない時、たまたまカレントディレクトリに
  2223.         // szfilenameがあったとき、そのまま返していたが、
  2224.         // この場合もきちんとパス検索して、できるだけフルパスで返すようにした。
  2225.         // ヒストリからファイルを選んでもファイルが開かなかったり、
  2226.         // 2.99Bでtxe起動でマクロパス検索がパスされてtxeが起動しなかったりした。
  2227.             BOOL fFullPath = pathGetFull(szfilename);
  2228.             if (fFullPath && fileIsExist(szfilename)) {
  2229.                 // OK
  2230.             } else {
  2231.                 BYTE path[CCHPATHNAME];
  2232.                 strcpy(path,szfilename);
  2233.                 if (fFullPath && pathSearchExt(path,szenvext)) {
  2234.                     strcpy(szfilename,path);
  2235.                 } else {
  2236.                     if (pathSearch(path,pathGetFileName(szfilename),szenvpath,szenvext)) {
  2237.                         strcpy(szfilename,path);
  2238.                     }
  2239.                 }
  2240.             }
  2241. #else
  2242.             if (!fileIsExist(szfilename)) {
  2243.                 BYTE path[CCHPATHNAME];
  2244.                 
  2245.                 strcpy(path,szfilename);
  2246.                 if (pathSearchExt(path,szenvext)) {
  2247.                     strcpy(szfilename,path);
  2248.                 } else {
  2249.                     if (pathSearch(path,pathGetFileName(szfilename),szenvpath,szenvext)) {
  2250.                         strcpy(szfilename,path);
  2251.                     }
  2252.                 }
  2253.             }
  2254. #endif
  2255.         }
  2256.         // 拡張子が"."のみなら、消去
  2257.         {
  2258.             mchar *szext = pathGetExt(szfilename);
  2259.             if (szext[1] == 0) *szext = 0;
  2260.         }
  2261.     }
  2262. }
  2263.  
  2264. void TXAPI _wzpathAuto(mchar *szfilename,BOOL fSearchPath)
  2265. {
  2266. //2.92 
  2267.     if (textf->fNoTextPathSearch || !fSearchPath) {//2.99C 970324 text1->textf
  2268.         // 拡張子が"."のみなら、消去
  2269.         mchar *szext = pathGetExt(szfilename);
  2270.         if (szext[1] == 0) *szext = 0;
  2271.     } else {
  2272.         pathAuto(szfilename,wzGetEnv(WZENV_PATH),wzGetEnv(WZENV_EXT));
  2273.     }
  2274. }
  2275.  
  2276. void TXAPI wzpathAuto(mchar *szfilename)
  2277. {
  2278. // szfilenameに結果を返すので注意すること
  2279. // szfilenameにはCCHPATHNAME以上のサイズのメモリを渡すこと
  2280. // 絶対パスを返すわけではない
  2281. //2.92 
  2282.     _wzpathAuto(szfilename,TRUE);
  2283. }
  2284.  
  2285. //{###メニュー操作}
  2286. //メニューを作成し、コマンドを追加します。
  2287. //メニューは#winmenu命令を使って簡単につくれます。usermenu.txcを参考にしてください。
  2288.  
  2289. #ifdef __TXC__
  2290.  
  2291. HMENU TXAPI menuNew(void)
  2292. {
  2293. // 新しくメニューを作成し、メニューハンドルを返します。
  2294.     return CreatePopupMenu();
  2295. }
  2296.  
  2297. void TXAPI menuTitle(HMENU hmenu,mchar *sztitle)
  2298. {
  2299. // メニューにタイトルを付けます。menuNewの直後に呼び出して下さい。
  2300.     AppendMenu(hmenu,MF_STRING,0,"\t"+sztitle);
  2301.     AppendMenu(hmenu,MF_SEPARATOR,0,NULL);
  2302. }
  2303.  
  2304. void TXAPI menuTxD(HMENU hmenu,mchar key,mchar *sztitle,mchar *szfunc)
  2305. {
  2306. // メニューにDOSスタイルのコマンドを追加します。
  2307. // sztitleにメニューに表示する文字列、szfuncにWZのコマンドを指定して下さい。
  2308.     txstr szkey = "& \t";
  2309.     szkey[1] = key;
  2310.     menuTx(hmenu,szkey + sztitle,szfunc);
  2311. }
  2312.  
  2313. void TXAPI menuStr(HMENU hmenu,mchar *szStr,int id)
  2314. {
  2315. // メニューに文字列を追加します。
  2316. // szStrに文字列、idにメニューIDを指定して下さい。
  2317.     AppendMenu(hmenu,MF_STRING,id,szStr);
  2318. }
  2319.  
  2320. void TXAPI menuSepa(HMENU hmenu)
  2321. {
  2322. // メニューにセパレータを追加します。
  2323.     AppendMenu(hmenu,MF_SEPARATOR,0,NULL);
  2324. }
  2325.  
  2326. void TXAPI menuPopup(HMENU hmenu,mchar *szStr,HMENU hmenuPopup)
  2327. {
  2328. // メニューにポップアップメニューを追加します。
  2329. // szStrに文字列、hmenuPopupに追加するメニューのハンドルを指定して下さい。
  2330.     AppendMenu(hmenu,MF_POPUP,(UINT)hmenuPopup,szStr);
  2331. }
  2332.  
  2333. void TXAPI menuDelete(HMENU hmenu)
  2334. {
  2335. // メニューを削除します。メニューを使い終わったら呼んで下さい。
  2336.     DestroyMenu(hmenu);
  2337. }
  2338.  
  2339. void TXAPI menuHist(HMENU hmenu)
  2340. {
  2341. // メニューにファイルヒストリリストを追加します。
  2342.     menuStr(hmenu,"",IDM_TXFILEHIST);
  2343. }
  2344.  
  2345. void TXAPI menuHistTab(HMENU hmenu)
  2346. {
  2347. // メニューにDOSスタイルのファイルヒストリリストを追加します。
  2348.     menuStr(hmenu,"",IDM_TXFILEHISTTAB);
  2349. }
  2350.  
  2351. #endif    // __TXC__
  2352.  
  2353. void TXAPI menuOpenMouse(HMENU hmenu)
  2354. {
  2355. // マウスカーソル位置にメニューを表示します
  2356.     POINT point;
  2357.     GetCursorPos(&point);
  2358.     TrackPopupMenu(hmenu,TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_LEFTALIGN,point.x,point.y,0,textf->hwndbase,NULL);
  2359. }
  2360.  
  2361. void TXAPI menuOpen(HMENU hmenu)
  2362. {
  2363. // カーソル位置にメニューを表示します
  2364. // マウスでメニューが開かれた場合は、マウスカーソル位置にメニューを表示します
  2365.     if (textf->fMenuOpenMouse) {
  2366.         menuOpenMouse(hmenu);
  2367.     } else {
  2368.         POINT point;
  2369.         if (textf->fListbox) {
  2370.             // リストボックスモードではキャレットを生成していないので、
  2371.             // GetCaretPosでマトモな位置を取得できない。
  2372.             point.x = textf->cxChar * 4;
  2373.             point.y = textf->ly * textf->cyLine;
  2374.         } else {
  2375.             GetCaretPos(&point);
  2376.         }
  2377.         if (textf->hwndtext2 && textf->fFocus2) {
  2378.             //3.00B1 970612 ウィンドウ分割時、下の窓でShift+F10しても上の窓の位置にメニューが表示された
  2379.             ClientToScreen(textf->hwndtext2,&point);
  2380.         } else {
  2381.             ClientToScreen(textf->hwndtext,&point);
  2382.         }
  2383.         if (_fwin40) {
  2384.             // メニューの先頭項目が選択されるようにする
  2385.             // VZとの互換性を高める
  2386.             PostMessage(textf->hwndtext,WM_KEYDOWN,VK_DOWN,0);
  2387.         }
  2388.         TrackPopupMenu(hmenu,TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_LEFTALIGN,point.x,point.y,0,textf->hwndbase,NULL);
  2389.     }
  2390. }
  2391.  
  2392. #ifdef __TXC__
  2393.  
  2394. void TXAPI menuDelAll(HMENU hmenu)
  2395. {
  2396. // メニューの内容を全て破棄します。
  2397. /// all delete
  2398.     while(DeleteMenu(hmenu,0,MF_BYPOSITION));
  2399. }
  2400.  
  2401. #endif    // __TXC__
  2402.  
  2403. #endif// __NOTX__
  2404.  
  2405. #ifdef __TXC__
  2406. #export
  2407. #ifdef __TXC__
  2408. #endexport
  2409.  
  2410. //{###メモリ操作}
  2411. //メモリブロックの割り当てや解放、コピー機能などを提供します。
  2412.  
  2413. LPVOID TXAPI memAlloc(DWORD cbsize)
  2414. {
  2415. // cbsizeバイトのグローバルメモリブロックを確保し、
  2416. // メモリブロックのポインタを返す
  2417. // 確保したメモリブロックの0クリアはしません
  2418.     return GlobalAllocPtr(TXGMEM_MOVEABLE,cbsize);
  2419. }
  2420.  
  2421. LPVOID TXAPI memAllocZeroinit(DWORD cbsize)
  2422. {
  2423. // cbsizeバイトのグローバルメモリブロックを確保し、
  2424. // メモリブロックのポインタを返す
  2425. // 確保したメモリブロックの0クリアもします
  2426. //1.95で追加
  2427.     return GlobalAllocPtr(TXGMEM_MOVEABLE|GMEM_ZEROINIT,cbsize);
  2428. }
  2429.  
  2430. void TXAPI memFree(LPVOID pmem)
  2431. {
  2432. // memAllocで確保したメモリブロックを解放する。
  2433.     GlobalFreePtr(pmem);
  2434. }
  2435.  
  2436. LPVOID TXAPI memResize(LPVOID p,DWORD size)
  2437. {
  2438. // memAllocで確保したメモリブロックのサイズを変更する
  2439. //1.91A で追加
  2440. #ifdef __FLAT__
  2441.     return GlobalReAlloc(p,size,GMEM_MOVEABLE);
  2442. #else
  2443.     return GlobalReAllocPtr(p,size,0);
  2444. #endif
  2445. }
  2446.  
  2447. //{###ダイアログ}
  2448.  
  2449. static void _information(mchar *_format,void* arg)
  2450. {
  2451. // 情報メッセージボックスを出します
  2452. // printfと同じ書式指定でメッセージを表示します
  2453.     if (_format) {//1.90 
  2454.         mchar buff[500];
  2455.         vsprintf(buff,_format,arg);
  2456.         //2.93 text1 -> textf
  2457.         #ifdef __FLAT__//強制ACTIVE
  2458.         wndtxSetActive(textf->hwndbase);
  2459.         #endif
  2460.         MessageBox(wndtxGetActive(textf->hwndbase),buff,"WZ",MB_ICONINFORMATION|MB_OK);
  2461.     }
  2462. }
  2463.  
  2464. // %c,%ld,%d,%u,%s,%pだけ使える
  2465. void TXAPIBASE _cdecl information(mchar *_format,...)
  2466. {
  2467. // 情報メッセージボックスを出します
  2468. // printfと同じ書式指定でメッセージを表示します
  2469. // 表示できるメッセージの長さは最大500バイトです。
  2470.     _information(_format,(void*)(&_format + 1));
  2471. }
  2472.  
  2473. // %c,%ld,%d,%u,%s,%pだけ使える
  2474. void TXAPIBASE _cdecl attention(mchar *_format,...)
  2475. {
  2476. // 警告メッセージボックスを出します
  2477. // printfと同じ書式指定でメッセージを表示します
  2478. // 表示できるメッセージの長さは最大500バイトです。
  2479.     if (_format) {//1.90 
  2480.         mchar buff[500];
  2481.         vsprintf(buff,_format,(void*)(&_format + 1));
  2482.         //2.93 text1 -> textf
  2483.         #ifdef __FLAT__//強制ACTIVE
  2484.         wndtxSetActive(textf->hwndbase);
  2485.         #endif
  2486.         MessageBox(wndtxGetActive(textf->hwndbase),buff,"WZ",MB_ICONEXCLAMATION|MB_OK);
  2487.     }
  2488. }
  2489.  
  2490. //{###ダイアログ}
  2491.  
  2492. // %c,%ld,%d,%u,%s,%pだけ使える
  2493. int TXAPIBASE _cdecl question(mchar *_format,...)
  2494. {
  2495. // 問い合わせメッセージボックスを出します
  2496. // printfと同じ書式指定でメッセージを表示します
  2497. // [はい]が選択されるとIDYES、
  2498. // [いいえ]が選択されるとIDNO、
  2499. // [キャンセル]が選択されるとIDCANCEL、を返します
  2500. // 表示できるメッセージの長さは最大500バイトです。
  2501.     if (_format) {//1.90 
  2502.         mchar buff[500];
  2503.         vsprintf(buff,_format,(void*)(&_format + 1));
  2504.         //2.93 text1 -> textf
  2505.         #ifdef __FLAT__//強制ACTIVE
  2506.         wndtxSetActive(textf->hwndbase);
  2507.         #endif
  2508.         return MessageBox(wndtxGetActive(textf->hwndbase),buff,"WZ",MB_ICONQUESTION|MB_YESNOCANCEL);
  2509.     } else {
  2510.         return IDCANCEL;
  2511.     }
  2512. }
  2513.  
  2514. //{###標準出力}
  2515. //stdoutウィンドウに文字列を出力します。
  2516. //マクロのデバッグなどに使えます。
  2517. //2.00B printf,printでは、必ず標準出力窓のテキストの末尾に文字列を出力するようにしました。
  2518.  
  2519. // %c,%ld,%d,%u,%s,%pだけ使える
  2520. int TXAPI _cdecl print(mchar *szstr)
  2521. {
  2522. // 標準出力に文字列を出力する
  2523.     return txOp(text,TXOP_PRINT,(LPARAM)szstr,0);//2.96 970209 
  2524. }
  2525.  
  2526. // %c,%ld,%d,%u,%s,%pだけ使える
  2527. int TXAPIBASE _cdecl printf(mchar *_format,...)
  2528. {
  2529. // 書式付き出力を行う
  2530. // 出力は標準出力先"stdout"テキストに行う
  2531. // 正常実行できた場合は、出力したバイト数(ヌルターミネータは除く)を返す
  2532. // 書式の指定はCと同じ。詳細はCの本を参照してください。
  2533. // %cで漢字も表示できます。
  2534. //     %[-][0][n][,][l]{d|u|x|X|c|s|p}
  2535. // 例:printf("a = %3d,szstr = %s\n",a,szstr);
  2536. // ※100バイトを越えるような長いformatは指定できません
  2537.     return txOp(text,TXOP_PRINTF,(LPARAM)_format,(LPARAM)(&_format + 1));//2.96 970209 
  2538. }
  2539.  
  2540. //{###文字列操作}
  2541.  
  2542. // %c,%ld,%d,%u,%s,%pだけ使える
  2543. int TXAPIBASE _cdecl sprintf(mchar *buff,mchar *_format,...)
  2544. {
  2545. // printfと同じ様に、書式化された出力を文字列buffに
  2546. // 正常実行できた場合は、出力したバイト数(ヌルターミネータは除く)を返す
  2547. // 文字列バッファbuffの長さチェックはされないので、注意してください
  2548.     vsprintf(buff,_format,(void*)(&_format + 1));
  2549.     return strlen(buff);
  2550. }
  2551.  
  2552. //{###表示}
  2553.  
  2554. // %c,%ld,%d,%u,%s,%pだけ使える
  2555. void TXAPI _cdecl txDispInfo(PTEXT text,mchar *_format,...)
  2556. {
  2557. // ステータスバーに情報を表示
  2558. // formatはprintfと同じ様に指定
  2559. // textのhwndtextが画面に表示されていれば(表テキストであれば)、
  2560. // ステータスバーに表示します。txSetUndisp中でも、表示します。
  2561. // 表示されていなければ(裏テキストならば)、表示しません。
  2562. //1.00F "$b","$c"は廃止しました
  2563.     if (!text->hwndtext) return;
  2564.     text = txGetFrame(text);//3.00B1 970613 WZ FilerでもtxDispInfoできるようにした
  2565.     mchar buff[500];
  2566.     if (_format) {
  2567.         vsprintf(buff,_format,(void*)(&_format + 1));
  2568.     } else {
  2569.         buff[0] = 0;
  2570.     }
  2571.     SendMessage(text->hwndbase,WM_TXSB_SETUPTEXT,HSL_INFO,(LPARAM)buff);
  2572. }
  2573.  
  2574. static void _statprintf(mchar* _format,void* arg)
  2575. {
  2576.     mchar buff[500];
  2577.     TX* text = txGetFrame(textf);
  2578.     int fUndisp = text->fUndisp;
  2579.     text->fUndisp = 0;
  2580.     if (_format) {
  2581.         vsprintf(buff,_format,arg);
  2582.     } else {
  2583.         buff[0] = 0;
  2584.     }
  2585.     SendMessage(text->hwndbase,WM_TXSB_SETUPTEXT,HSL_SIMPLE,(LPARAM)buff);
  2586.     text->fUndisp = fUndisp;
  2587. }
  2588.  
  2589. void TXAPIC TXAPIBASE statprintf(mchar *_format,...)
  2590. {
  2591. // ステータスバーに情報を表示
  2592. // formatはprintfと同じ様に指定
  2593. // txSetUndisp中かどうかに関わらず、常に表示します。
  2594. //1.99Bで追加
  2595.     _statprintf(_format,(void*)(&_format + 1));
  2596. }
  2597.  
  2598. void TXAPIC informationex(mchar* _format,...)
  2599. {
  2600. // ステータスバーに情報を表示
  2601. // ステータスバーが非表示ならinformationする
  2602. // formatはprintfと同じ様に指定
  2603. // txSetUndisp中かどうかに関わらず、常に表示します。
  2604. //2.92で追加
  2605.     if (textf->fDispStatusbar) {//2.99C 970324 text1->textf
  2606.         _statprintf(_format,(void*)(&_format + 1));
  2607.     } else {
  2608.         information(_format,(void*)(&_format + 1));
  2609.     }
  2610. }
  2611.  
  2612. // %c,%ld,%d,%u,%s,%pだけ使える
  2613. void TXAPI _cdecl txDispSl(PTEXT text,int hsl,mchar *_format,...)
  2614. {
  2615. // hsl(HSL1からHSL3)に情報を表示
  2616. // formatはprintfと同じ様に指定
  2617. // 文字列の先頭部に"$c"を指定するとセンタリングして表示します。
  2618.     mchar buff[500];
  2619.     if (_format) {
  2620.         vsprintf(buff,_format,(void*)(&_format + 1));
  2621.     } else {
  2622.         buff[0] = 0;
  2623.     }
  2624.     SendMessage(text->hwndbase,WM_TXSB_SETUPTEXT,hsl,(LPARAM)buff);
  2625. }
  2626.  
  2627. #export
  2628. #endif
  2629. #endexport
  2630. #endif    // __TXC__
  2631.  
  2632. //{###文字操作}
  2633.  
  2634. BOOL TXAPIBASE txchIsKanji(TXCHAR c)
  2635. {
  2636. // cが全角文字かどうか返す
  2637.     if (c < 0x100) return FALSE;
  2638.     if (c == 0x0D0A) return FALSE;
  2639.     return TRUE;
  2640. }
  2641.  
  2642. BOOL TXAPIBASE txchIsReturn(TXCHAR c)
  2643. {
  2644. // cが改行コード(0x0D0A,0x0A,0x1A)かどうか返す
  2645.     if (c == 0x0A || c == 0x1A) return TRUE;
  2646.     if (c == 0x0D0A) return TRUE;
  2647.     return FALSE;
  2648. }
  2649.  
  2650. #ifdef __TXC__
  2651.  
  2652. //{###ウィンドウ操作}
  2653. //WZ特有のウィンドウ操作を行います。
  2654.  
  2655. BOOL TXAPI wndRegisterClass(mchar* szWndProc,txstr strClass)
  2656. {
  2657. // 簡易 RegisterClass
  2658. // 一般的なスタイルを持つウィンドウクラスを登録します。
  2659. // szWndProcには"マクロファイル名.ウィンドウプロシジャ名",
  2660. // strClassには、txstr型の変数を渡して下さい。wndRegisterClassがワーク用に
  2661. // 使います。利用側は変数の内容を変更してはいけません。
  2662. // ウィンドウが不要になったら、strClassを引数に指定してwndUnregisterClass
  2663. // してください。
  2664. // thanks dieさん
  2665. //2.96A 970211 仕様変更 strClassのフォーマット変更、返り値 void->BOOL:成功したかどうか返す
  2666.     WNDCLASS wc;
  2667.     structClear(wc);
  2668.     wc.lpfnWndProc = macroMakeWndProc(szWndProc);
  2669.     if (wc.lpfnWndProc) {
  2670.         sprintf(strClass,"TX:%ld:%x:%s",wc.lpfnWndProc,(UINT)text->hwndbase,szWndProc);
  2671.         wc.style =            CS_HREDRAW | CS_VREDRAW;
  2672.         wc.hInstance =        text->hInstance;
  2673.         wc.hIcon =             LoadIcon(NULL, IDI_APPLICATION);
  2674.         wc.hCursor =         LoadCursor(NULL, IDC_ARROW);
  2675.         wc.hbrBackground =    (HBRUSH)(COLOR_WINDOW + 1);
  2676.         wc.lpszClassName =    strClass;
  2677.         if (RegisterClass(&wc)) {
  2678.             return TRUE;
  2679.         } else {
  2680.             macroFreeWndProc(wc.lpfnWndProc);
  2681.         }
  2682.     }
  2683.     return FALSE;
  2684. }
  2685.  
  2686. void TXAPI wndUnregisterClass(txstr strClass)
  2687. {
  2688. // 簡易 UnregisterClass
  2689. // wndRegisterClassで登録したウィンドウクラスの登録を解除します。
  2690. // strClassには、wndRegisterClassに渡したstrClassを渡して下さい。
  2691. // thanks dieさん
  2692. //2.96A 970211 macroMakeWndProcで確保したリソースを解放するようにした
  2693.     FARPROC lpfn = atoi(&strClass[3]);
  2694.     macroFreeWndProc(lpfn);
  2695.     UnregisterClass(strClass,text->hInstance);
  2696. }
  2697.  
  2698. #endif
  2699.  
  2700. #ifdef __TXC__
  2701.  
  2702. __new
  2703. {
  2704.     GetWindowsPlatform();
  2705. }
  2706.  
  2707. #endif
  2708.