home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1999 March / VPR9903A.BIN / APUPDATE / VC / Tx300d / TX300D.LZH / APIDB2.C < prev    next >
C/C++ Source or Header  |  1997-05-22  |  60KB  |  2,441 lines

  1. // WZ EDITOR 標準機能 APIデータベース2
  2. // Copyright 1996 TY
  3. // 従来のapidb,cmdlistにとって替わります
  4.  
  5. //{###headline}
  6.  
  7. #define SM_EXRET        0x0001
  8. #define SM_BT            0x0002
  9.  
  10. static BOOL headlineMatch(TX* text,int nest,mchar* szhead,SEARCHMODE searchmode)
  11. {
  12.     int lchFind = strlen(szhead);
  13.     PARAATR paraatr;
  14.     paraatrRead(text,text->npara,¶atr);
  15.     if (paraatr.modeTitle == nest) {
  16.         txstr szstr;
  17.         txGetPara(text,szstr);
  18.         int lch = strlen(szstr);
  19.         if (lch == lchFind && !strncmp(szstr,szhead,lch)) return TRUE;
  20.     }
  21.     return FALSE;
  22. }
  23.  
  24. static NPARA _headlineSearch(TX* text,int nest,mchar* szhead,SEARCHMODE searchmode)
  25. {
  26. // textのカーソル行からnestの見出しszheadを検索する
  27. // nestより大きい見出しがあったら検索をやめて0を返す(SM_EXRETならそのnparaを返す)
  28. // SM_BTなら、szheadより比較値が大きな見出しがあったらnparaを返す
  29. // カーソル位置は不定
  30.     int lchFind;
  31.     if (szhead) lchFind = strlen(szhead);
  32.     if (text->editmode) {
  33.         txstr szstr;
  34.         NPARA npara;
  35.         for (npara = text->npara;;npara++) {
  36.             PARAATR paraatr;
  37.             if (!paraatrRead(text,npara,¶atr)) break;
  38.             if (paraatr.modeTitle) {
  39.                 if (paraatr.modeTitle < nest) {
  40.                     if (searchmode & SM_EXRET) return npara;
  41.                     return 0;
  42.                 }
  43.                 if (paraatr.modeTitle == nest) {
  44.                     txJumpNpara(text,npara);
  45.                     if (szhead) {
  46.                         txGetPara(text,szstr);
  47.                         int lch = strlen(szstr);
  48.                         if (lch == lchFind && !strncmp(szstr,szhead,lch)) return npara;
  49.                     } else {
  50.                         return npara;
  51.                     }
  52.                 }
  53.             }
  54.         }
  55.     } else {
  56.         txstr szline;
  57.         PARAATR paraatr;
  58.         txJumpParaTop(text);
  59.         while(1) {
  60.             INT lch;
  61.             int lchTop = txParaatrRead(text,¶atr,&lch);
  62.             if (paraatr.modeTitle) {
  63.                 if (paraatr.modeTitle < nest) {
  64.                     if (searchmode & SM_EXRET) return text->npara;
  65.                     return 0;
  66.                 }
  67.                 if (paraatr.modeTitle == nest) {
  68.                     if (szhead) {
  69.                         txGetPara(text,szline);
  70.                         mchar* psz = &szline[lchTop];
  71.                         if (lch == -1) lch = strlen(psz);
  72.                         if (searchmode & SM_BT) {
  73.                             // szheadは0ターミネイトされているのでn=lchを使用
  74.                             if (strncmp(psz,szhead,lch) > 0) return text->npara;
  75.                         } else {
  76.                             if (lch == lchFind && !strncmp(psz,szhead,lch)) return text->npara;
  77.                         }
  78.                     } else {
  79.                         return text->npara;
  80.                     }
  81.                 }
  82.             }
  83.             if (!txNextPara(text)) break;
  84.         }
  85.     }
  86.     return 0;
  87. }
  88.  
  89. static NPARA _headlineSearchPrev(TX* text,int nest,mchar* szhead,SEARCHMODE searchmode)
  90. {
  91. // textのカーソル行から前方方向へnestの見出しszheadを検索する
  92. // nestより大きい見出しがあったら検索をやめて0を返す
  93. // カーソル位置は不定
  94.     int lchFind;
  95.     if (szhead) lchFind = strlen(szhead);
  96.     if (text->editmode) {
  97.         txstr szstr;
  98.         NPARA npara;
  99.         for (npara = text->npara;npara;npara--) {
  100.             PARAATR paraatr;
  101.             if (!paraatrRead(text,npara,¶atr)) break;
  102.             if (paraatr.modeTitle) {
  103.                 if (paraatr.modeTitle < nest) return 0;
  104.                 if (paraatr.modeTitle == nest) {
  105.                     txJumpNpara(text,npara);
  106.                     if (szhead) {
  107.                         txGetPara(text,szstr);
  108.                         int lch = strlen(szstr);
  109.                         if (lch == lchFind && !strncmp(szstr,szhead,lch)) return npara;
  110.                     } else {
  111.                         return npara;
  112.                     }
  113.                 }
  114.             }
  115.         }
  116.     } else {
  117.         txstr szline;
  118.         PARAATR paraatr;
  119.         txJumpParaTop(text);
  120.         while(1) {
  121.             INT lch;
  122.             int lchTop = txParaatrRead(text,¶atr,&lch);
  123.             if (paraatr.modeTitle) {
  124.                 if (paraatr.modeTitle < nest) return 0;
  125.                 if (paraatr.modeTitle == nest) {
  126.                     if (szhead) {
  127.                         txGetPara(text,szline);
  128.                         mchar* psz = &szline[lchTop];
  129.                         if (lch == -1) lch = strlen(psz);
  130.                         if (lch == lchFind && !strncmp(psz,szhead,lch)) return text->npara;
  131.                     } else {
  132.                         return text->npara;
  133.                     }
  134.                 }
  135.             }
  136.             if (!txPrevPara(text)) break;
  137.         }
  138.     }
  139.     return 0;
  140. }
  141.  
  142. NPARA TXAPI headlineSearchTop(TX* text,int nest)
  143. {
  144. // カーソル位置からnestの見出しの頭を検索してnparaを返す。カーソル位置をnparaにセット
  145. // 見つからなければ0を返す。カーソル位置は保存する
  146.     NPARA npara0 = text->npara;
  147.     NPARA npara;
  148.     if (nest == 1) {
  149.         txJumpFileTop(text);
  150.         npara = _headlineSearch(text,1,NULL,0);
  151.     } else {
  152.         npara = _headlineSearchPrev(text,nest-1,NULL,0);
  153.         if (npara) {
  154.             txJumpNpara(text,npara);
  155.             if (txNextPara(text)) {
  156.                 npara = _headlineSearch(text,nest,NULL,0);
  157.             } else {
  158.                 npara = 0;
  159.             }
  160.         } else {
  161.             npara = _headlineSearch(text,nest,NULL,0);
  162.         }
  163.     }
  164.     if (npara) {
  165.         txJumpNpara(text,npara);
  166.         return npara;
  167.     }
  168.     txJumpNpara(text,npara0);
  169.     return 0;
  170. }
  171.  
  172. NPARA TXAPI headlineSearch(TX* text,int nest,mchar* szhead,SEARCHMODE searchmode)
  173. {
  174. // textのnest見出しの先頭の見出しから前方方向へnestの見出しszheadを検索する
  175. // 見出しがみつかったら、カーソルをセットし、見出しのnparaを返す
  176. // nestより大きい見出しがあったら検索をやめる
  177. // みつからなかったらカーソルを検索前のnparaの論理行頭にセットして0を返す
  178.     NPARA npara0 = text->npara;
  179.     headlineSearchTop(text,nest);
  180.     NPARA npara = _headlineSearch(text,nest,szhead,searchmode);
  181.     if (npara) {
  182.         return npara;
  183.     } else {
  184.         txJumpNpara(text,npara0);
  185.         return 0;
  186.     }
  187. }
  188.  
  189. BOOL TXAPI headlineDel(TX* text)
  190. {
  191. // カーソル行の見出しとその内容を削除
  192. // 削除した場合はカーソルを、以前の位置の前行に設定
  193.     NPARA npara = text->npara;
  194.     PARAATR paraatr;
  195.     INT lch;
  196.     txParaatrRead(text,¶atr,&lch);
  197.     if (paraatr.modeTitle) {
  198.         if (!txNextPara(text)) return FALSE;
  199.         NPARA npara1 = _headlineSearch(text,paraatr.modeTitle,NULL,SM_EXRET);
  200.         txJumpNpara(text,npara);
  201.         txSelectEx(text,CLIP_CHAR);
  202.         if (npara1) {
  203.             txJumpNpara(text,npara1);
  204.         } else {
  205.             txJumpFileEnd(text);
  206.         }
  207.         txSelectDelete(text);
  208.         txPrevPara(text);
  209.         return TRUE;
  210.     }
  211.     return FALSE;
  212. }
  213.  
  214. BOOL TXAPI headlineDelContents(TX* text)
  215. {
  216. // カーソル行の見出しの内容を削除
  217. // 子見出しは削除しない
  218. // カーソル位置は見出しの先頭に設定
  219.     NPARA npara = text->npara;
  220.     PARAATR paraatr;
  221.     txParaatrRead(text,¶atr,NULL);
  222.     if (paraatr.modeTitle) {
  223.         if (txNextPara(text)) {
  224.             while(1) {
  225.                 txParaatrRead(text,¶atr,NULL);
  226.                 if (paraatr.modeTitle) break;
  227.                 if (!txNextPara(text)) break;
  228.             }
  229.             txSelectEx(text,CLIP_CHAR);
  230.             txJumpNpara(text,npara + 1);
  231.             txSelectDelete(text);
  232.         }
  233.         txJumpNpara(text,npara);
  234.         return TRUE;
  235.     }
  236.     return FALSE;
  237. }
  238.  
  239. BOOL TXAPI headlineInsert(TX* text,int nest,mchar* szhead)
  240. {
  241. // カーソル行に見出しを挿入
  242. // カーソルは見出し行の論理行頭へ
  243.     txJumpParaTop(text);
  244.     txInsertReturn(text);
  245.     txPrevPara(text);
  246.     txInsert(text,szhead);
  247.     PARAATR paraatr;
  248.     txParaatrRead(text,¶atr,NULL);
  249.     paraatr.modeTitle = nest;
  250.     txParaatrWrite(text,¶atr);
  251.     txJumpParaTop(text);
  252.     return TRUE;
  253. }
  254.  
  255. static void txAddPara(TX* text)
  256. {
  257. // 現在の見出しの次行に行を挿入し、カーソルをその行頭に設定する
  258. // カーソルが常に現在の見出しの中にいるようにするため
  259.     txJumpParaEnd(text);
  260.     txInsertReturn(text);
  261. }
  262.  
  263. //{###APIデータベース}
  264. //現在使える全てのWZ EditorのコマンドとAPIを管理します。
  265.  
  266. #include <windows.h>
  267. #include <windowsx.h>
  268. #include "_filer.h"
  269.  
  270. extern "custmize" DWORD TXAPI txmenuPickup(DWORD dst,int mode,mchar* szarg);
  271. #define PICKUP_MENUAPIDB2    6
  272.  
  273. void TXAPI apidb2FlushCache(void);
  274.  
  275. #define MYDEBUG            0
  276. #define IDB_DEBUG        IDB_API
  277.  
  278. static void textCmdselTerm(void);
  279.  
  280. // TXCMD        txcmd.api
  281. // TXCMDBASE    txcmdbas.api
  282. // TXAPI        txapi.api
  283. // TXAPIBASE    txapibas.api
  284.  
  285. #export
  286. #define IDB_CMD            0
  287. #define IDB_CMDBASE        1
  288. #define IDB_API            2
  289. #define IDB_APIBASE        3
  290. #define IDB_NSYSTEM        4    // システムコマンド/API
  291. #define IDB_CMDUSER        4    // ユーザが登録したコマンド
  292. #define IDB_APIUSER        5    // ユーザが登録したAPI
  293. #define IDB_N            6
  294. #define IDB_CMDDEFAULT    100    // IDB_CMD or IDB_CMDBASE ユーザ選択値を保持
  295. #define IDB_APIDEFAULT    101    // IDB_API or IDB_APIBASE ユーザ選択値を保持
  296. #endexport
  297.  
  298. #define IDB_ISBASE(idb)    ((idb) == IDB_CMDBASE || (idb) == IDB_APIBASE)
  299. #define IDB_ISCMD(idb)    ((idb) == IDB_CMDBASE || (idb) == IDB_CMD || (idb) == IDB_CMDDEFAULT)
  300.  
  301. static mchar* _szCategoryMenu = "メニュー";
  302.  
  303. typedef struct {
  304.     TX* text;
  305.     TX bodytext;
  306.     BOOL fWrite;
  307. } APIDBCONTEXT;
  308. APIDBCONTEXT _context[IDB_N];
  309.  
  310. static mchar* apidb2GetFilename(int idb)
  311. {
  312.     static mchar* tszfilename[IDB_N] = {
  313.         "txcmd.api","txcmd.api","txapi.api","txapi.api","txcmdusr.api","txapiusr.api",
  314.     };
  315.     return tszfilename[idb];
  316. }
  317.  
  318. static void apidb2SetConfig(TX* text)
  319. {
  320.     strcpy(text->tsztitle[0],".###");
  321.     strcpy(text->tsztitle[1],".##");
  322.     strcpy(text->tsztitle[2],".#");
  323.     strcpy(text->tszformat[SZFORMAT_TITLE4],"");
  324.     strcpy(text->tszformat[SZFORMAT_TITLE5],"");
  325.     strcpy(text->tszformat[SZFORMAT_TITLE6],"");
  326.     strcpy(text->tszformat[SZFORMAT_TAB],"");//3.00B1 970519 _dialogListとdialogListのAPIヘルプが同じになっていた
  327. }
  328.  
  329. static apidb2SearchCategory(TX* db,mchar* szapi);
  330.  
  331. static void merge(TX* db,TX* text,NPARA nparaTop)
  332. {
  333.     NPARA nparaEnd = text->npara;
  334.     txJumpNpara(text,nparaTop);
  335.     PARAATR paraatr;
  336.     INT lch;
  337.     int lchTop = txParaatrRead(text,¶atr,&lch);
  338.     txstr szline;
  339.     txGetPara(text,szline);
  340.     mchar* psz = &szline[lchTop];
  341.     if (lch == -1) lch = strlen(psz);
  342.     txstr sztitle;
  343.     txstrcpylen(sztitle,psz,lch);
  344. //information(sztitle);
  345.     if (apidb2SearchCategory(db,sztitle)) {
  346.         txNextPara(db);
  347.         nparaTop++;
  348.     } else {
  349.         txJumpFileEnd(db);
  350.     }
  351.     txJumpNpara(text,nparaTop);
  352.     txSelectEx(text,CLIP_CHAR);
  353.     txJumpNpara(text,nparaEnd);
  354. #if 1//3.00A2 970506 [機能一覧]を開くと、クリップボードの内容が変化した
  355.     txPrivatePush(text);
  356.     txPrivatePopJump(db);
  357. #else
  358.     txSelectCopy(text);
  359.     txPaste(db);
  360. #endif
  361. }
  362.  
  363. static TX* _apidb2Open(int idb,BOOL fWrite)
  364. {
  365.     APIDBCONTEXT* context = &_context[idb];
  366.     if (context->text) {
  367.         return context->text;
  368.     }
  369.     //
  370.     context->fWrite = fWrite;
  371.     //
  372.     TX* text = context->text = &context->bodytext;
  373.     txInitText(text);
  374.     txSetFileName(text,text->szexedir + apidb2GetFilename(idb));
  375.     apidb2SetConfig(text);
  376.     txOpenText(text);
  377. //    if (!fWrite) txSetHigh(text);//無理
  378.     //
  379.     if (text && !fWrite) {
  380.         // ユーザAPIDBのマージ
  381.         int idbUser = idb;
  382.         TX *db = text;
  383.         if (idb == IDB_CMD || idb == IDB_CMDBASE) {
  384.             idbUser = IDB_CMDUSER;
  385.         } else if (idb == IDB_API || idb == IDB_APIBASE) {
  386.             idbUser = IDB_APIUSER;
  387.         } else {
  388.             idbUser = -1;
  389.         }
  390.         if (idbUser != -1) {
  391.             TX textBody;
  392.             TX* text = &textBody;
  393.             txInitText(text);
  394.             txSetFileName(text,text->szexedir + apidb2GetFilename(idbUser));
  395.             apidb2SetConfig(text);
  396.             if (txOpenText(text)) {
  397. //                txSetHigh(text);//無理
  398.                 NPARA npara0 = 0;
  399.                 txJumpFileTop(text);
  400.                 while(1) {
  401.                     PARAATR paraatr;
  402.                     INT lch;
  403.                     int lchTop = txParaatrRead(text,¶atr,&lch);
  404.                     if (paraatr.modeTitle == 1) {
  405.                         NPARA npara = text->npara;
  406.                         if (npara0) {
  407.                             merge(db,text,npara0);
  408.                         }
  409.                         npara0 = npara;
  410.                     }
  411.                     if (!txNextPara(text)) {
  412.                         if (npara0) {
  413.                             merge(db,text,npara0);
  414.                         }
  415.                         break;
  416.                     }
  417.                 }
  418.                 txClose(text);
  419.             }
  420. //            dialogaText(db,"aa");
  421.         }
  422.         if (IDB_ISCMD(idb)) {
  423.             // menu
  424.             txJumpFileEnd(text);
  425.             txAddPara(text);
  426.             headlineInsert(text,1,_szCategoryMenu);
  427.             txAddPara(text);
  428.             txmenuPickup((DWORD)text,PICKUP_MENUAPIDB2,NULL);
  429. //dialogaText(text,"aa");
  430.         }
  431.     }
  432.     if (fWrite) {
  433.         // キャッシュをフラッシュ
  434.         textCmdselTerm();
  435.     }
  436.     return text;
  437. }
  438.  
  439. static TX* apidb2Open(int idb)
  440. {
  441.     return _apidb2Open(idb,FALSE);
  442.  
  443. }
  444.  
  445. static TX* apidb2OpenWrite(int idb)
  446. {
  447.     return _apidb2Open(idb,TRUE);
  448. }
  449.  
  450. static void apidb2Close(int idb)
  451. {
  452.     APIDBCONTEXT* context = &_context[idb];
  453.     if (context->text) {
  454.         TX* text = context->text;
  455.         if (context->fWrite && text->fEdit) {
  456.             txSave(text);
  457.         }
  458.         txClose(text);
  459.         context->text = NULL;
  460.     }
  461. }
  462.  
  463. static void apidb2CloseAll(void)
  464. {
  465.     int idb;
  466.     for (idb = 0;idb < IDB_N;idb++) {
  467.         apidb2Close(idb);
  468.     }
  469. }
  470.  
  471. static TX* apidb2GetText(int idb)
  472. {
  473.     APIDBCONTEXT* context = &_context[idb];
  474.     TX* db = context->text;
  475.     if (db) return db;
  476.     return apidb2Open(idb);
  477. }
  478.  
  479. static NPARA apidb2SearchApi(TX* db,mchar* szapi)
  480. {
  481.     return headlineSearch(db,2,szapi,0);
  482. }
  483.  
  484. static BOOL apidb2DelApi(TX* db,mchar* szapi)
  485. {
  486. // szapiの登録データを削除する
  487. // szapiのデータが見つからなかったら、カーソル行は変更せず、論理行頭へジャンプ
  488. // 見つかったら、その位置に移動
  489. // szapiには、名前だけを指定
  490.     if (apidb2SearchApi(db,szapi)) {
  491.         return headlineDel(db);
  492.     }
  493.     return FALSE;
  494. }
  495.  
  496. BOOL TXAPI apidb2AddApi(TX* db,mchar* szapi)
  497. {
  498. // szapiを挿入
  499. // szapiがすでにあれば削除して挿入
  500. // カーソルは挿入行に設定
  501.     if (apidb2SearchApi(db,szapi)) {
  502.         headlineDel(db);
  503.     }
  504.     if (!headlineSearchTop(db,2)) {
  505.         txNextPara(db);
  506.     } else {
  507.         // ソートして挿入
  508. #if 01
  509.         NPARA npara = _headlineSearch(db,2,szapi,SM_BT|SM_EXRET);
  510.         if (npara) {
  511.             txJumpNpara(db,npara);
  512.         } else {
  513.             txJumpFileEnd(db);
  514.         }
  515. #endif
  516.     }
  517.     return headlineInsert(db,2,szapi);
  518. }
  519.  
  520. static apidb2SearchCategory(TX* db,mchar* szapi)
  521. {
  522.     return headlineSearch(db,1,szapi,0);
  523. }
  524.  
  525. static apidb2DelCategory(TX* db,mchar* szapi)
  526. {
  527.     if (apidb2SearchCategory(db,szapi)) {
  528.         return headlineDel(db);
  529.     }
  530.     return FALSE;
  531. }
  532.  
  533. static BOOL apidb2AddCategory(TX* db,mchar* szcategory)
  534. {
  535.     if (!apidb2SearchCategory(db,szcategory)) {
  536.         if (!headlineSearchTop(db,1)) {
  537.             txJumpFileEnd(db);
  538.         } else {
  539.             // ソートして挿入
  540. #if 01
  541.             NPARA npara = _headlineSearch(db,1,szcategory,SM_BT|SM_EXRET);
  542.             if (npara) {
  543.                 txJumpNpara(db,npara);
  544.             } else {
  545.                 txJumpFileEnd(db);
  546.             }
  547. #endif
  548.         }
  549.         return headlineInsert(db,1,szcategory);
  550.     }
  551.     return TRUE;
  552. }
  553.  
  554. // キー定義サポート
  555. #define KEY_MS        0
  556. #define KEY_VZ        1
  557. #define KEY_MI        2
  558. #define KEY_VZ98    3
  559. #define KEY_EMACS    4    //2.99 970313 
  560. #define KEY_N        5
  561. static TX _bodytxkey[KEY_N];
  562. static TX *_txkey[KEY_N];
  563. static void keyInsert(int ikey,mchar* szapi,mchar *p)
  564. {
  565.     if (_txkey[ikey]) {
  566.         mchar *szkey = strchr(p,'}');    //"{#MS}"etcをスキップ
  567.         if (szkey) {
  568.             szkey++;
  569.             szkey = strGetWordTop(szkey);
  570.             if (*szkey) {
  571.                 txInsertf(_txkey[ikey],"%s=%s\n",szapi,szkey);
  572.             }
  573.         }
  574.     }
  575. }
  576.  
  577. static BOOL ___apidb2TakeinText(int idb,TX* text)
  578. {
  579.     TX* db = apidb2GetText(idb);
  580.     mchar szapi[CCHWORD] = {0};
  581.     BOOL fBase = FALSE;
  582.     BOOL fBaseApi = FALSE;//3.00B1 970520 
  583.     txstr szbuff(CCHLINE);
  584.     BOOL fEvalApi = FALSE;
  585.     BOOL fFunctionDesc = FALSE;
  586.     BOOL fCategoryDesc = FALSE;
  587.     BOOL fCmd = (idb == IDB_CMD || idb == IDB_CMDBASE);
  588.     
  589.     txJumpFileTop(text);
  590.     while(1) {
  591.         txGetPara(text,szbuff);
  592.         mchar *p = szbuff;
  593.         p = strGetWordTop(p);
  594.         if (*p) {
  595.             if (*p == '/' && p[1] == '/') {
  596.                 p += 2;
  597.                 p = strGetWordTop(p);
  598.                 if (*p == '{') {
  599.                     if (strmatch(p,"{#API}")) {
  600.                         fEvalApi = TRUE;
  601.                     } else if (strmatch(p,"{###")) {
  602.                         p += 4;
  603.                         mchar *pend = strchr(p,'}');
  604.                         if (!pend) pend = p + strlen(p);
  605.                         mchar szcategory[CCHLINE];
  606.                         strcpylenmax(szcategory,p,pend - p,CCHLINE);
  607.                         if (!apidb2SearchCategory(db,szcategory)) {
  608.                             apidb2AddCategory(db,szcategory);
  609.                         }
  610.                         fCategoryDesc = TRUE;
  611.                     } else if (strmatch(p,"{#ENDAPI}")) {
  612.                         fEvalApi = FALSE;
  613.                     } else if (fEvalApi) {
  614.                         if (fCmd) {//2.96 970210 wz.keyにキーが2重に登録された
  615.                             if (strmatch(p,"{#MS}")) {
  616.                                 keyInsert(KEY_MS,szapi,p);
  617.                             } else if (strmatch(p,"{#VZ}")) {
  618.                                 keyInsert(KEY_VZ,szapi,p);
  619.                                 keyInsert(KEY_VZ98,szapi,p);
  620.                             } else if (strmatch(p,"{#VZIBM}")) {
  621.                                 keyInsert(KEY_VZ,szapi,p);
  622.                             } else if (strmatch(p,"{#VZ98}")) {
  623.                                 keyInsert(KEY_VZ98,szapi,p);
  624.                             } else if (strmatch(p,"{#MI}")) {
  625.                                 keyInsert(KEY_MI,szapi,p);
  626.                             } else if (strmatch(p,"{#EMACS}")) {//2.99 970313 
  627.                                 keyInsert(KEY_EMACS,szapi,p);
  628.                             }
  629.                         }
  630.                         if (strmatch(p,"{#@}")) {
  631.                             // locateを取得
  632.                             txstr sz = p + 4;
  633.                             sz += ".";
  634.                             sz += szapi;
  635.                             strcpymax(szapi,sz,cchof(szapi));
  636.                         } else if (strmatch(p,"{$")) {
  637.                             // {$...} setup指令は書き出さない
  638.                         } else {
  639.                             if (fCategoryDesc || fFunctionDesc) {
  640.                                 BOOL f = TRUE;
  641.                                 if (strmatch(p,"{#RET}")) {
  642.                                     if (fCmd) f = FALSE;
  643.                                 }
  644.                                 if (*p && f) {
  645.                                     txAddPara(db);
  646.                                     txInsert(db,p);
  647.                                 }
  648.                             }
  649.                         }
  650.                     }
  651.                 } else {
  652.                     if (fCategoryDesc == 1) {
  653.                         fCategoryDesc = 2;
  654.                         // 古い概要の説明を削除
  655.                         headlineDelContents(db);
  656.                         if (*p) {
  657.                             txAddPara(db);
  658.                             txInsert(db,p);
  659.                         }
  660.                     } else if (fCategoryDesc == 2) {
  661.                         if (*p) {
  662.                             txAddPara(db);
  663.                             txInsert(db,p);
  664.                         }
  665.                     } else if (fFunctionDesc == 1) {
  666.                         fFunctionDesc = 2;
  667.                         if (idb == IDB_APIUSER || idb == IDB_CMDUSER) {
  668.                             //2.95 970131 追加機能はBASEとする
  669.                             fBase = TRUE;
  670.                             fBaseApi = TRUE;
  671.                         }
  672.                         switch (idb) {
  673.                             case IDB_CMD:
  674.                             case IDB_CMDBASE:
  675.                             case IDB_CMDUSER: {
  676.                                 txstr sz = p;
  677.                                 sz += "(Cmd:";
  678.                                 sz += szapi;
  679.                                 sz += ")";
  680.                                 apidb2AddApi(db,sz);
  681.                                 //
  682.                                 #if 1
  683.                                 if (fBase) {
  684.                                     txAddPara(db);
  685.                                     txInsert(db,"{#BASE}");
  686.                                 }
  687.                                 #else
  688.                                 txAddPara(db);
  689.                                 txInsert(db,"{#CMD}");
  690.                                 txInsert(db,szapi);
  691.                                 #endif
  692.                                 txAddPara(db);
  693.                                 txInsert(db,"{#FUNC}");
  694.                                 if (*p) txInsert(db,p);
  695.                                 break;
  696.                             }
  697.                             case IDB_API:
  698.                             case IDB_APIBASE:
  699.                             case IDB_APIUSER: {
  700.                                 txAddPara(db);
  701.                                 if (fBaseApi) {//3.00B1 970519 
  702.                                     txInsert(db,"{#BASE}");
  703.                                     txAddPara(db);
  704.                                 }
  705.                                 #if 1//3.00A2 970506 APIDBに#include情報が欠落していた
  706.                                 {
  707.                                     mchar* p = strchr(szapi,'.');
  708.                                     if (p) {
  709.                                         txInsert(db,"{#@}");
  710.                                         txInsertBuff(db,szapi,p - szapi);
  711.                                         txAddPara(db);
  712.                                     }
  713.                                 }
  714.                                 #endif
  715.                                 txInsert(db,"{#FUNC}");
  716.                                 if (*p) txInsert(db,p);
  717.                                 break;
  718.                             }
  719.                         }
  720.                     } else if (fFunctionDesc == 2) {
  721.                         if (*p) {
  722.                             txAddPara(db);
  723.                             txInsert(db,p);
  724.                         }
  725.                     }
  726.                 }
  727.             } else {
  728.                 fFunctionDesc = 0;
  729.                 fCategoryDesc = 0;
  730.                 if (fEvalApi) {
  731.                     // 関数定義かどうか
  732.                     BOOL fFunction = FALSE;
  733.                     BOOL fTxcmdBase = FALSE;
  734.                     BOOL fTxcmd = FALSE;
  735.                     mchar *pPrototype = p;
  736.                     fBase = FALSE;
  737.                     fBaseApi = FALSE;
  738.                     while(1) {
  739.                         p = strGetWordTop(p);
  740.                         int len = strGetWordLen(p);
  741.                         if (len == 0) break;
  742.                         if (strisid(p,"TXCMDBASE") || strisid(p,"_txcmdbase")) {
  743.                             fTxcmd = TRUE;
  744.                             fTxcmdBase = TRUE;
  745.                             fBase = TRUE;
  746.                         } else if (strisid(p,"TXCMD") || strisid(p,"_txcmd")) {
  747.                             fTxcmd = TRUE;
  748.                         } else if (strisid(p,"TXAPIBASE") || strisid(p,"_txapibase")) {//3.00B1 970519 
  749.                             fBaseApi = TRUE;
  750.                         } else {
  751.                             mchar* pc = strchr(p,'(');
  752.                             if (pc && pc - p < len) {    // '('の直前の単語なら...
  753.                                 // 関数名
  754.                                 strcpylenmax(szapi,p,pc - p,CCHWORD);
  755.                                 switch (idb) {
  756.                                     case IDB_CMD:
  757.                                     case IDB_CMDBASE:
  758.                                     case IDB_CMDUSER: {
  759.                                         if (fTxcmd) {
  760.                                             fFunction = TRUE;
  761.                                         }
  762.                                         break;
  763.                                     }
  764.                                     case IDB_API:
  765.                                     case IDB_APIBASE:
  766.                                     case IDB_APIUSER: {
  767.                                         if (strchr(szapi,'.')) {
  768.                                             // "."が含まれていたら、コマンド
  769.                                         } else {
  770.                                             fFunction = TRUE;
  771.                                             apidb2AddApi(db,szapi);
  772.                                             #if 0
  773.                                             //ここでNextParaすると
  774.                                             // 別カテゴリをカーソルが指すことがある
  775.                                             txNextPara(db);
  776.                                             #endif
  777.                                             //
  778.                                             txAddPara(db);
  779.                                             txInsert(db,pPrototype);
  780.                                         }
  781.                                         break;
  782.                                     }
  783.                                 }
  784.                                 break;
  785.                             }
  786.                         }
  787.                         p += len;
  788.                     }
  789.                     if (fFunction) {
  790.                         fFunctionDesc = TRUE;
  791.                     }
  792.                 }
  793.             }
  794.         } else {
  795.             fFunctionDesc = 0;
  796.             fCategoryDesc = 0;
  797.         }
  798.         if (!txNextPara(text)) break;
  799.     }
  800.     return TRUE;
  801. }
  802.  
  803. static BOOL __apidb2TakeinText(TX* text,int idb)
  804. {
  805.     // 書き込みオープンするために、Closeする
  806.     apidb2Close(idb);
  807.     TX* db = apidb2OpenWrite(idb);
  808.     BOOL ret = ___apidb2TakeinText(idb,text);
  809.     // 保存を行うために、Closeする
  810.     apidb2Close(idb);
  811.     return ret;
  812. }
  813.  
  814. static BOOL _apidb2TakeinText(TX* text,BOOL fSystem)
  815. {
  816. // textのテキストファイルのコマンド/API情報をAPIDBに追加します。
  817. // 既に情報がAPIDBにあれば上書きします。
  818. //1.94 で追加
  819. #if MYDEBUG
  820.     return __apidb2TakeinText(text,IDB_DEBUG);
  821. #else
  822.     if (fSystem) {    // システムコマンド
  823.         __apidb2TakeinText(text,IDB_CMD);
  824.         __apidb2TakeinText(text,IDB_API);
  825.     } else {
  826.         __apidb2TakeinText(text,IDB_CMDUSER);
  827.         __apidb2TakeinText(text,IDB_APIUSER);
  828.     }
  829.     return TRUE;
  830. #endif
  831. }
  832.  
  833. BOOL TXAPI apidb2TakeinText(tx* text)
  834. {
  835.     return _apidb2TakeinText(text,FALSE);
  836. }
  837.  
  838. static BOOL _apidb2TakeinFile(mchar *szfilename,BOOL fSystem)
  839. {
  840. // szfilenameのテキストファイルのコマンド/API情報をAPIDBに追加します。
  841. // 既に情報がAPIDBにあれば上書きします。
  842.     TX body;
  843.     TX *text = &body;
  844.     
  845.     txInitText(text);
  846.     txSetFileName(text,szfilename);
  847. //printf("%s\n",szfilename);
  848.     text->width = MAXWIDTH;
  849.     txOpenText(text);
  850.     _apidb2TakeinText(text,fSystem);
  851.     txClose(text);
  852.     return TRUE;
  853. }
  854.  
  855. BOOL TXAPI apidb2TakeinFile(mchar *szfilename)
  856. {
  857. // szfilenameのテキストファイルのコマンド/API情報をユーザAPIDBに追加します。
  858. // 既に情報がAPIDBにあれば上書きします。
  859.     return _apidb2TakeinFile(szfilename,FALSE);
  860. }
  861.  
  862. BOOL TXAPI apidb2TakeinFileSystem(mchar *szfilename)
  863. {
  864. // szfilenameのテキストファイルのコマンド/API情報をシステムAPIDBに追加します。
  865. // 既に情報がAPIDBにあれば上書きします。
  866.     return _apidb2TakeinFile(szfilename,TRUE);
  867. }
  868.  
  869. static void _pickfiles(mchar *szpath)
  870. {
  871.     #ifdef __FLAT__
  872.     WIN32_FIND_DATA ffd;
  873.     HANDLE hfind;
  874.     #else
  875.     FILEFIND filefind;
  876.     #endif
  877.     mchar szfilename[CCHPATHNAME] = {0};
  878.     mchar szwk[CCHPATHNAME];
  879.     //
  880.     strcpy(szfilename,szpath);
  881.     #ifdef __FLAT__
  882.     hfind = FindFirstFile(szpath,&ffd);
  883.     if (hfind != INVALID_HANDLE_VALUE)
  884.     #else
  885.     if (!fileFindFirst(szpath,FA_NORMAL,&filefind))
  886.     #endif
  887.     {
  888.         #if TEST
  889.         int n = 10;
  890.         #endif
  891.         do {
  892.             #ifdef __FLAT__
  893.             pathSetFileName(szfilename,ffd.cFileName);
  894.             #else
  895.             pathSetFileName(szfilename,filefind.name);
  896.             #endif
  897.             if (pathEquFileName(szfilename,"dat")) continue;//1.00C dat.tllはAPIDBに含めない
  898.             if (pathEquFileName(szfilename,"term")) continue;//1.00C term.txeはAPIDBに含めない
  899.             if (pathEquFileName(szfilename,"comm")) continue;//2.00B 
  900.             if (pathEquFileName(szfilename,"wzup")) continue;//3.00A6 970511 
  901. #if 0//3.00A2 970504 
  902.             if (pathEquFileName(szfilename,"speak")) continue;//2.00B 
  903. #endif
  904.             if (!strnicmp(pathGetFileName(szfilename),"test",4)) continue;//1.00F3 "test*"はAPIDBに含めない
  905.             if (pathIsExt(szfilename,".txh")) {
  906.                 // 無条件に実行
  907.             } else {
  908.                 // 既に.txhが存在したら実行しない
  909.                 strcpy(szwk,szfilename);
  910.                 pathSetExt(szwk,".txh");
  911.                 if (fileIsExist(szwk)) continue;
  912.                 if (pathIsExt(szfilename,".h")) {
  913.                     // OK
  914.                     if (!stricmp(pathGetFileName(szfilename),"_text.h")) {
  915.                         // _text.hは既に実行済み
  916.                         continue;
  917.                     }
  918.                 } else {
  919.                     // .txm .txe .tll
  920.                     // 既に.hが存在したら見ない
  921.                     pathSetExt(szwk,".h");
  922.                     if (fileIsExist(szwk)) continue;
  923.                     {
  924.                         DWORD size;
  925.                         LPVOID pmem = macroGetExport(szfilename,&size);
  926.                         if (pmem) {
  927.                             GetTempFileName(0,"WZ",0,szwk);
  928.                             HFILE hf = _lcreat(szwk,0);
  929.                             if (hf == HFILE_ERROR) {
  930.                                 attention("ファイル %s が作成できません",szwk);
  931.                             } else {
  932.                                 _hwrite(hf,pmem,size);
  933.                                 _lclose(hf);
  934.                             }
  935.                             memFree(pmem);
  936.                             apidb2TakeinFileSystem(szwk);
  937.                             fileDelete(szwk);
  938.                         }
  939.                         continue;
  940.                     }
  941.                 }
  942.             }
  943.             apidb2TakeinFileSystem(szfilename);
  944.             #if TEST
  945.             if (n-- == 0) {
  946.                 break;
  947.             }
  948.             #endif
  949.         }
  950.         #ifdef __FLAT__
  951.         while(FindNextFile(hfind,&ffd));
  952.         FindClose(hfind);
  953.         #else
  954.         while (!fileFindNext(&filefind));
  955.         #endif
  956.     }
  957. }
  958.  
  959. static void pickfiles(mchar *_szpath)
  960. {
  961.     mchar szpath[CCHPATHNAME] = {0};
  962.     pathSetFileName(szpath,_szpath);
  963.     _pickfiles(szpath);
  964. }
  965.  
  966. static void apidb2DelAll(void)
  967. {
  968.     int idb;
  969.     for (idb = 0;idb < IDB_N;idb++) {
  970.         apidb2Close(idb);
  971.         TX* db = apidb2OpenWrite(idb);
  972.         txDeleteText(db);
  973.         txInsertLine(db,"<TX>");
  974.         txInsertLine(db,"TX-APIDB 3.00");
  975.         apidb2Close(idb);
  976.     }
  977. }
  978.  
  979. BOOL TXAPI apidb2Flush(void)
  980. {
  981. // txpathの *.H をパス検索して、{#API}-{#ENDAPI}を抜き出して
  982. // データベースを構築する
  983.     apidb2DelAll();
  984.     mchar *p = wzGetEnv(WZENV_TXPATH);//1.00F
  985.     // まず、_text.hを変換
  986.     apidb2TakeinFileSystem(text->szexedir + \"\std\_text.h");
  987.     //
  988.     while(1) {
  989.         mchar *next = strchrs(p,"; ");
  990.         if (!next) break;
  991.         if (next > p) {
  992.             mchar szpath[CCHPATHNAME];
  993.             strcpylen(szpath,p,next - p);
  994.             if (!stricmp(szpath,"wz:\\ty")) {
  995.                 //2.96 970210 "wz:\ty"内は無視
  996.             } else {
  997. //printf("%s\n",szpath);
  998.                 pathFormDir(szpath);
  999.                 strcat(szpath,\"\*.*");
  1000.                 //
  1001.                 pathSetExt(szpath,".txh");pickfiles(szpath);
  1002.                 pathSetExt(szpath,".h");pickfiles(szpath);
  1003.                 pathSetExt(szpath,".txm");pickfiles(szpath);
  1004.                 pathSetExt(szpath,".txe");pickfiles(szpath);
  1005.                 pathSetExt(szpath,".tll");pickfiles(szpath);
  1006.             }
  1007.         }
  1008.         p = next + 1;
  1009.     }
  1010.     return TRUE;
  1011. }
  1012.  
  1013. test
  1014. {
  1015. #if MYDEBUG
  1016.     int idb = IDB_DEBUG;
  1017.     apidb2Close(idb);
  1018.     TX* db = apidb2OpenWrite(idb);
  1019.     txDeleteText(db);
  1020.     db->fEdit = TRUE;
  1021.     apidb2Close(idb);
  1022.     //
  1023.     apidb2TakeinFileSystem(text->szexedir + "std\\edit.tll");
  1024. //    apidb2TakeinFileSystem(text->szexedir + "test.c");
  1025. //    apidb2TakeinFileSystem(text->szexedir + "std\\_text.h");
  1026. //    apidb2Flush();
  1027.     //
  1028.     txOpenFast(text,text->szexedir + apidb2GetFilename(idb));
  1029.     return;
  1030. #else
  1031.     apidb2Flush();
  1032. #endif
  1033.     for (int idb = 0;idb < IDB_N;idb++) {
  1034.         apidb2Close(idb);
  1035.     }
  1036.     txOpenFast(text,text->szexedir + "txcmd.api");
  1037. }
  1038.  
  1039. //##remake apidb & key file
  1040.  
  1041. //2.99G 970405 MS.KEY function disp修正
  1042. static mchar **getfkey(int ikey,int ifkkind)
  1043. {
  1044.     static mchar *_fkms[] = {
  1045.         "ヘルプ","ヘルプ2","下検索","支援","ジャンプ","窓選択","","選択","","メニューバー","","保存",NULL,
  1046.     };
  1047.     static mchar *_fkms_shift[] = {
  1048.         "機能","","上検索","補完","戻る","窓切替","","選択戻","","メニュー","","",NULL,
  1049.     };
  1050.     static mchar *_fkms_ctrl[] = {
  1051.         "ヘルプ1","ヘルプ2","","","マーク","次の窓","","","","","","開く",NULL,
  1052.     };
  1053.     static mchar *_fkms_shiftctrl[] = {    //2.99G 970405 NEW
  1054.         "","","","補完戻","","前の窓","","","","","","印刷",NULL,
  1055.     };
  1056.     static mchar *_fkvz[] = {
  1057.         "ファイル","窓換","文換","窓割","記憶","検索","置換","カット","インサート","ブロック","ページ","ヘルプ",NULL,
  1058.     };
  1059.     static mchar *_fkvz_shift[] = {
  1060.         "設定","","比較","","複写","マルチ","複写2","コピー","ペースト"," タグ","","",NULL,
  1061.     };
  1062.     static mchar *_fk_null[] = {
  1063.         "",NULL,//1個は""が必要
  1064.     };
  1065.     static mchar *_fkmi[] = {
  1066.         "ファイル","切換","移動","窓割","検索↓","行選択","カット","コピー","ペースト","タグ",NULL,
  1067.     };
  1068.     static mchar *_fkmi_shift[] = {
  1069.         "設定","","検索","","検索↑","選択","","","字ペースト","行2重",NULL,
  1070.     };
  1071.     static mchar *_fkmi_ctrl[] = {
  1072.         "","","","","","箱選択","","","","",NULL,
  1073.     };
  1074.     static mchar **tfk[KEY_N][FKEY_NKIND] = {
  1075.         _fkms,_fkms_shift,_fkms_ctrl,_fkms_shiftctrl,
  1076.         _fkvz,_fkvz_shift,_fk_null  ,_fk_null,
  1077.         _fkmi,_fkmi_shift,_fkmi_ctrl,_fk_null,
  1078.         _fkvz,_fkvz_shift,_fk_null  ,_fk_null,
  1079.         _fkvz,_fkvz_shift,_fk_null  ,_fk_null,//2.99 970313 
  1080.     };
  1081.     return tfk[ikey][ifkkind];
  1082. }
  1083.  
  1084. static void deleteCategory(TX* text,mchar* szCategory)
  1085. {
  1086.     txSetUndispEx(text);
  1087.     {
  1088.         txJumpFileTop(text);
  1089.         if (txSearchEx(text,szCategory,SEARCH_PARATOP|SEARCH_NOSENSECASE)) {
  1090.             txSelect(text);
  1091.             if (!txSearchEx(text,"[",SEARCH_PARATOP)) {
  1092.                 txJumpFileEnd(text);
  1093.             }
  1094.             txSelectDelete(text);
  1095.         }
  1096.     }
  1097.     txSetDispEx(text);
  1098. }
  1099.  
  1100. //1.99K 
  1101. // wz.keyから[TY]のキー定義を削除したものを_wz.keyに作成。
  1102. static void _wzkey(void)
  1103. {
  1104.     TX body;
  1105.     TX* text = &body;
  1106.     txInit(text,text1->szexedir + "wz.key");
  1107.     deleteCategory(text,"[TY]");
  1108.     txSaveTo(text,text->szexedir + "_wz.key");
  1109.     txReopenInternal(text);
  1110.     txClose(text);
  1111. }
  1112.  
  1113. //2.00E4 wz.keyから[TYツール]の定義を削除したものを_wz.mnuに作成。
  1114. static void _wzmnu(void)
  1115. {
  1116.     TX body;
  1117.     TX* text = &body;
  1118.     txInit(text,text1->szexedir + "wz.mnu");
  1119.     deleteCategory(text,"[TYツール]");
  1120.     txSaveTo(text,text->szexedir + "_wz.mnu");
  1121.     txReopenInternal(text);
  1122.     txClose(text);
  1123. }
  1124.  
  1125. apidb2Remake
  1126. {
  1127.     static mchar *tszkey[KEY_N] = {
  1128.         "Windows準拠","VZ(DOS/V版)準拠","MIFESライク","VZ(98版)準拠","Emacsライク",
  1129.     };
  1130.     int i;
  1131.     for (i = 0;i < KEY_N;i++) {
  1132.         _txkey[i] = &_bodytxkey[i];
  1133.         txInitText(_txkey[i]);
  1134.         txOpenText(_txkey[i]);
  1135.         txInsertf(_txkey[i],"[%s]\n",tszkey[i]);
  1136.     }
  1137.     apidb2Flush();
  1138.     {
  1139.         for (i = 0;i < KEY_N;i++) {
  1140.             txmenuOp(TXKEYOP_DEL,tszkey[i],NULL);
  1141.         }
  1142.         TX* txkey = (TX*)txmenuOp(TXKEYOP_OPEN,NULL,NULL);
  1143.         for (i = 0;i < KEY_N;i++) {
  1144.             {
  1145.                 static mchar* tszcaption[FKEY_NKIND] = {
  1146.                     "","+SHIFT","+CTRL","+SHIFT+CTRL",
  1147.                 };
  1148.                 int ikind;
  1149.                 for (ikind = 0;ikind < FKEY_NKIND;ikind++) {
  1150.                     mchar **fkey = getfkey(i,ikind);
  1151.                     txInsertf(_txkey[i],"FKEY%s=",tszcaption[ikind]);
  1152.                     mchar *szkey;
  1153.                     int ifkey;
  1154.                     for (ifkey = 0;szkey = fkey[ifkey];ifkey++) {
  1155.                         txInsertf(_txkey[i],"\"%s\" ",szkey);
  1156.                     }
  1157.                     txInsert(_txkey[i],"\n");
  1158.                 }
  1159.             }
  1160.             //
  1161.             txInsertText(txkey,_txkey[i]);
  1162.             //
  1163.             txClose(_txkey[i]);
  1164.             _txkey[i] = NULL;
  1165.         }
  1166.         txmenuOp(TXKEYOP_CLOSE,NULL,NULL);
  1167.         _wzkey();//1.99K 
  1168.         _wzmnu();//2.00E4 
  1169.     }
  1170. }
  1171.  
  1172. //{###コマンド選択
  1173.  
  1174. #include "dialog.h"
  1175. #include "search.txh"
  1176. #ifdef __FLAT__
  1177. #pragma multidef+
  1178. extern "comctl32.dll" {
  1179.     #include "c:\msvc40\include\commctrl.h"
  1180. }
  1181. #pragma multidef-
  1182. #endif
  1183.  
  1184. #define IDD_CONTEXTMENU            19980    //2.99G 970405 1000だとIDD_EXECと重なって変だったので、他と重ならない値に変更した
  1185.  
  1186. #export
  1187. #define IDD_CMDSEL_CONTEXTMENU    19989    //2.99A 970321 
  1188. #define IDD_CMDSEL_CATEGORY        19990
  1189. #define IDD_CMDSEL_LIST            19991
  1190. #define IDD_CMDSEL_EXPLAIN        19992
  1191. #define IDD_CMDSEL_SEARCH        19993    //2.00E4 
  1192. #define IDD_CMDSEL_SEARCHNEXT    19994    //2.00E4 
  1193. #define IDD_CMDSEL_TREELIST        19995    //2.90 
  1194. #define IDD_CMDSEL_KEYLIST        19996    //2.90 
  1195. #define IDD_CMDSEL_DISPALL        19997    //2.90 
  1196. #define IDD_CMDSEL_DISPBASE        19998    //2.90 
  1197. #define IDD_CMDSEL_DISPCATEGORY    19999    //2.90 
  1198.  
  1199. #define CS_SETSZCMD            (WM_TXUSER + 0)
  1200. #define CSN_SETSZCMD        (WM_TXUSER + 1)
  1201.  
  1202. #define CMDSEL_HOOK    \
  1203.     static PMACROFUNC pfunc;\
  1204.     if (pfunc.address == 0) {\
  1205.         macroGetFuncAddress("apidb2.dlgprocCmdsel",&pfunc);\
  1206.     }\
  1207.     if (pfunc.address) {\
  1208.         macroCallAddress(&pfunc,NULL,4,(long)hwnd,(long)message,(long)wParam,(long)lParam);\
  1209.     }
  1210. #endexport
  1211.  
  1212. static IFILE _adrSearch;//次に検索開始するアドレス
  1213. static DWORD _searchmode;
  1214. static txstr _txstrSearch;
  1215. static txstr _szapi;//前回見つけたCMD
  1216. __new
  1217. {
  1218.     _searchmode = text->searchmode;
  1219. }
  1220.  
  1221. static void apidb2GetExplain(int idb,TX* text)
  1222. {
  1223.     TX* db = apidb2GetText(idb);
  1224.     txstr szline;
  1225.     PARAATR paraatr;
  1226.     txParaatrRead(db,¶atr,NULL);
  1227.     if (paraatr.modeTitle == 2) {
  1228. #if 1//3.00A2 970506 
  1229.         BOOL fDesc = (idb == IDB_API || idb == IDB_APIBASE);
  1230.         BOOL fInclude = FALSE;
  1231.         BOOL fSkip = FALSE;
  1232.         txNextPara(db);
  1233.         while(1) {
  1234.             txParaatrRead(db,¶atr,NULL);
  1235.             if (paraatr.modeTitle) break;
  1236.             txGetPara(db,szline);
  1237.             //
  1238.             int len = 0;
  1239.             if (len = strmatch(szline,"{#FUNC}")) {
  1240.                 fDesc = TRUE;
  1241.             } else if (len = strmatch(szline,"{#RET}")) {
  1242.                 if (fDesc) txInsert(text,"<返り値> ");
  1243.             } else if (len = strmatch(szline,"{#EX}")) {
  1244.                 if (fDesc) txInsert(text,"<例> ");
  1245.             } else if (
  1246.                 strmatch(szline,"{#MS}") ||
  1247.                 strmatch(szline,"{#VZ}") ||
  1248.                 strmatch(szline,"{#VZ98}") ||
  1249.                 strmatch(szline,"{#VZIBM}") ||
  1250.                 strmatch(szline,"{#MI}") ||
  1251.                 strmatch(szline,"{#EMACS}")
  1252.             ) {
  1253.                 //3.00B1 970522 
  1254.                 fSkip = TRUE;
  1255.             } else if (len = strmatch(szline,"{#BASE}")) {
  1256.                 fSkip = TRUE;//3.00B1 970520 
  1257.             } else if (len = strmatch(szline,"{#@}")) {
  1258.                 if (fDesc) {
  1259.                     mchar* p = &szline[len];
  1260.                     if (
  1261.                         !stricmp(p,"std") ||
  1262.                         !stricmp(p,"dialoga") ||
  1263.                         !stricmp(p,"window") ||
  1264.                         !stricmp(p,"stdlib") ||
  1265.                         !stricmp(p,"cmd") ||
  1266.                         !stricmp(p,"file") ||
  1267.                         !stricmp(p,"help") ||
  1268.                         !stricmp(p,"system") ||
  1269.                         !stricmp(p,"macro")
  1270.                     ) {
  1271.                         // "_text.h"で#includeしてるので#includeする必要がない
  1272.                         fSkip = TRUE;
  1273.                     } else {
  1274.                         txInsert(text,"#include \"");
  1275.                         fInclude = TRUE;
  1276.                     }
  1277.                 }
  1278.             }
  1279.             if (fSkip) {
  1280.                 fSkip = FALSE;
  1281.             } else {
  1282.                 if (fDesc) {
  1283.                     txInsert(text,&szline[len]);
  1284.                     if (fInclude) {
  1285.                         txInsert(text,".h\"");
  1286.                         fInclude = FALSE;
  1287.                     }
  1288.                     txInsertReturn(text);
  1289.                 }
  1290.             }
  1291.             if (!txNextPara(db)) break;
  1292.         }
  1293. #else
  1294.         int fDesc = 0;
  1295.         txNextPara(db);
  1296.         while(1) {
  1297.             txParaatrRead(db,¶atr,NULL);
  1298.             if (paraatr.modeTitle) break;
  1299.             txGetPara(db,szline);
  1300.             if (fDesc || (idb == IDB_API || idb == IDB_APIBASE)) {
  1301.                 txInsert(text,szline);
  1302.                 txInsertReturn(text);
  1303.             } else {
  1304.                 int len;
  1305.                 if (len = strmatch(szline,"{#FUNC}")) {
  1306.                     fDesc = TRUE;
  1307.                     txInsert(text,&szline[len]);
  1308.                     txInsertReturn(text);
  1309.                 }
  1310.             }
  1311.             if (!txNextPara(db)) break;
  1312.         }
  1313. #endif
  1314.     } else {
  1315.         txNextPara(db);
  1316.         while(1) {
  1317.             txParaatrRead(db,¶atr,NULL);
  1318.             if (paraatr.modeTitle) break;
  1319.             txGetPara(db,szline);
  1320.             txInsert(text,szline);
  1321.             txInsertReturn(text);
  1322.             if (!txNextPara(db)) break;
  1323.         }
  1324.     }
  1325. }
  1326.  
  1327. // カーソル位置のコマンド名/API名を返す
  1328. static BOOL apidb2GetCmd(int idb,txstr szcmd)
  1329. {
  1330.     TX* db = apidb2GetText(idb);
  1331.     PARAATR paraatr;
  1332.     INT lch;
  1333.     int lchTop = txParaatrRead(db,¶atr,&lch);
  1334.     if (paraatr.modeTitle) {
  1335.         txstr szline;
  1336.         txGetPara(db,szline);
  1337.         mchar* p = &szline[lchTop];
  1338.         if (lch == -1) lch = strlen(p);
  1339.         if (idb == IDB_CMD || idb == IDB_CMDBASE) {
  1340.             mchar* ptop = strstr(p,"(Cmd:");
  1341.             if (ptop) {
  1342.                 ptop += 5;
  1343.             } else {
  1344.                 ptop = p;
  1345.             }
  1346.             int len = strlen(ptop);
  1347.             if (len && ptop[len-1] == ')') len--;
  1348.             txstrcpylen(szcmd,ptop,len);
  1349.             return TRUE;
  1350.         } else {
  1351.             szcmd = p;
  1352.             return TRUE;
  1353.         }
  1354.     }
  1355.     return FALSE;
  1356. }
  1357.  
  1358. // カーソル行のコマンドが基本コマンドかどうか返す
  1359. // カーソルがコマンドの見出しにあること
  1360. #if 1//3.00B1 970520 
  1361. static BOOL IsCmdBase(TX* db,int idb)
  1362. {
  1363.     BOOL ret = FALSE;
  1364.     if (IDB_ISCMD(idb)) {
  1365.         if (txNextPara(db)) {
  1366.             if (txCmpCur(db,"{#BASE}")) ret = TRUE;
  1367.             txPrevPara(db);
  1368.         }
  1369.     } else {
  1370.         if (txNextPara(db)) {
  1371.             if (txNextPara(db)) {
  1372.                 if (txCmpCur(db,"{#BASE}")) ret = TRUE;
  1373.                 txPrevPara(db);
  1374.             }
  1375.             txPrevPara(db);
  1376.         }
  1377.     }
  1378.     return ret;
  1379. }
  1380. #else
  1381. static BOOL IsCmdBase(TX* db)
  1382. {
  1383.     if (txNextPara(db)) {
  1384.         BOOL ret = TRUE;
  1385.         txstr szline;
  1386.         txGetPara(db,szline);
  1387.         if (!strstr(szline,"{#BASE}")) ret = FALSE;
  1388.         txPrevPara(db);
  1389.         return ret;
  1390.     }
  1391.     return FALSE;
  1392. }
  1393. #endif
  1394.  
  1395. // szcmdのコマンド名/API名を検索し、nparaを返す
  1396. static NPARA apidb2SearchCmd(int idb,mchar* szcmd,SEARCHMODE searchmode)
  1397. {
  1398.     PARAATR paraatr;
  1399.     TX* db = apidb2GetText(idb);
  1400.     BOOL fBase = IDB_ISBASE(idb);
  1401.     if (IDB_ISCMD(idb)) {
  1402.         txJumpFileTop(db);
  1403.         txstr sz = "(Cmd:" + szcmd + ")";
  1404.         while(1) {
  1405.             if (txSearchEx(db,sz,searchmode)) {
  1406.                 txParaatrRead(db,¶atr,NULL);
  1407.                 if (paraatr.modeTitle == 2) {
  1408.                     if (!(fBase && !IsCmdBase(db,idb))) {
  1409.                         return db->npara;
  1410.                     }
  1411.                 }
  1412.                 if (!txNextPara(db)) break;
  1413.             } else {
  1414.                 break;
  1415.             }
  1416.         }
  1417.         return 0;
  1418.     } else {
  1419.         txJumpFileTop(db);
  1420.         while(1) {
  1421.             if (txSearchEx(db,szcmd,searchmode|SEARCH_WORD)) {
  1422.                 txParaatrRead(db,¶atr,NULL);
  1423.                 if (paraatr.modeTitle == 2) {
  1424.                     if (!(fBase && !IsCmdBase(db,idb))) {
  1425.                         return db->npara;
  1426.                     }
  1427.                 }
  1428.                 if (!txNextPara(db)) break;
  1429.             } else {
  1430.                 break;
  1431.             }
  1432.         }
  1433.         return 0;
  1434.     }
  1435. }
  1436.  
  1437. // カーソル位置が含まれるカテゴリを検索し、カテゴリのnparaを返す
  1438. static NPARA apidb2GetCategoryNpara(int idb)
  1439. {
  1440.     PARAATR paraatr;
  1441.     TX* db = apidb2GetText(idb);
  1442.     while(1) {
  1443.         txParaatrRead(db,¶atr,NULL);
  1444.         if (paraatr.modeTitle == 1) {
  1445.             return db->npara;
  1446.         }
  1447.         if (!txPrevPara(db)) break;
  1448.     }
  1449.     return 0;
  1450. }
  1451.  
  1452. // カーソル位置が含まれるコマンドを検索し、コマンドのnparaを返す
  1453. static NPARA apidb2GetCmdNpara(int idb)
  1454. {
  1455.     PARAATR paraatr;
  1456.     TX* db = apidb2GetText(idb);
  1457.     while(1) {
  1458.         txParaatrRead(db,¶atr,NULL);
  1459.         if (paraatr.modeTitle == 2) {
  1460.             return db->npara;
  1461.         }
  1462.         if (!txPrevPara(db)) break;
  1463.     }
  1464.     return 0;
  1465. }
  1466.  
  1467. BOOL TXAPI apidb2MakeTreetext(TX* text,int idb)
  1468. {
  1469.     TX* db = apidb2GetText(idb);
  1470.     txJumpFileTop(db);
  1471.     txSetHigh(db);
  1472.     txSetHigh(text);
  1473.     txstr szline;
  1474.     int nCategory = 0;
  1475.     int nCmd = 0;
  1476.     BOOL fBase = IDB_ISBASE(idb);
  1477.     while(1) {
  1478.         PARAATR paraatr;
  1479.         int lchTop = txParaatrRead(db,¶atr,NULL);
  1480.         if (paraatr.modeTitle) {
  1481.             if (paraatr.modeTitle == 1) {
  1482.                 nCategory++;
  1483.                 if (nCmd == 0) {
  1484.                     // コマンドが1個もないカテゴリは消す
  1485.                     txPrevPara(text);
  1486.                     txDeletePara(text);
  1487.                 }
  1488.                 nCmd = 0;
  1489.             }
  1490.             BOOL fOut = TRUE;
  1491.             if (paraatr.modeTitle == 2) {
  1492.                 if (fBase) fOut = IsCmdBase(db,idb);
  1493.                 if (fOut) nCmd++;
  1494.             }
  1495.             if (fOut) {
  1496.                 txInsertChar(text,paraatr.modeTitle - 1 + '0');
  1497.                 //
  1498.                 txGetPara(db,szline);
  1499.                 mchar*pTop = &szline[lchTop];
  1500.                 {
  1501.                     mchar*p = strstr(pTop,"(Cmd:");
  1502.                     if (p) *p = 0;
  1503.                 }
  1504.                 txInsert(text,pTop);
  1505.                 txInsertChar(text,0);
  1506.                 txInsertf(text,"%d",db->npara);
  1507.                 txInsertReturn(text);
  1508.             }
  1509.         }
  1510.         if (!txNextPara(db)) break;
  1511.     }
  1512.     if (nCategory && nCmd == 0) {
  1513.         // コマンドが1個もないカテゴリは消す
  1514.         txPrevPara(text);
  1515.         txDeletePara(text);
  1516.     }
  1517.     txResetHigh(text);
  1518.     txResetHigh(db);
  1519. //dialogaText(text,"MakeTreetext");
  1520.     return TRUE;
  1521. }
  1522.  
  1523. BOOL TXAPI apidb2MakeCategorytext(TX* text,int idb)
  1524. {
  1525.     TX* db = apidb2GetText(idb);
  1526.     txJumpFileTop(db);
  1527.     txstr szline;
  1528.     int nCategory = 0;
  1529.     int nCmd = 0;
  1530.     BOOL fBase = IDB_ISBASE(idb);
  1531.     while(1) {
  1532.         PARAATR paraatr;
  1533.         int lchTop = txParaatrRead(db,¶atr,NULL);
  1534.         if (paraatr.modeTitle) {
  1535.             if (paraatr.modeTitle == 1) {
  1536.                 nCategory++;
  1537.                 if (nCmd == 0) {
  1538.                     // コマンドが1個もないカテゴリは消す
  1539.                     txPrevPara(text);
  1540.                     txDeletePara(text);
  1541.                 }
  1542.                 nCmd = 0;
  1543.                 //
  1544.                 txGetPara(db,szline);
  1545.                 mchar*pTop = &szline[lchTop];
  1546.                 txInsert(text,pTop);
  1547.                 txInsertChar(text,0);
  1548.                 txInsertf(text,"%d",db->npara);
  1549.                 txInsertReturn(text);
  1550.             } else if (paraatr.modeTitle == 2) {
  1551.                 if (fBase && !IsCmdBase(db,idb)) {
  1552.                 } else {
  1553.                     nCmd++;
  1554.                 }
  1555.             }
  1556.         }
  1557.         if (!txNextPara(db)) break;
  1558.     }
  1559.     if (nCategory && nCmd == 0) {
  1560.         // コマンドが1個もないカテゴリは消す
  1561.         txPrevPara(text);
  1562.         txDeletePara(text);
  1563.     }
  1564.     return TRUE;
  1565. }
  1566.  
  1567. // カーソルはカテゴリ行にあること
  1568. BOOL TXAPI apidb2MakeCommandtext(TX* text,int idb)
  1569. {
  1570.     TX* db = apidb2GetText(idb);
  1571.     if (!txNextPara(db)) return FALSE;
  1572.     txstr szline;
  1573.     BOOL fBase = IDB_ISBASE(idb);
  1574.     while(1) {
  1575.         PARAATR paraatr;
  1576.         int lchTop = txParaatrRead(db,¶atr,NULL);
  1577.         if (paraatr.modeTitle == 2) {
  1578.             if (fBase && !IsCmdBase(db,idb)) {
  1579.             } else {
  1580.                 txGetPara(db,szline);
  1581.                 mchar*pTop = &szline[lchTop];
  1582.                 {
  1583.                     mchar*p = strstr(pTop,"(Cmd:");
  1584.                     if (p) *p = 0;
  1585.                 }
  1586.                 txInsert(text,pTop);
  1587.                 txInsertChar(text,0);
  1588.                 txInsertf(text,"%d",db->npara);
  1589.                 txInsertReturn(text);
  1590.             }
  1591.         } else if (paraatr.modeTitle) break;
  1592.         if (!txNextPara(db)) break;
  1593.     }
  1594.     return TRUE;
  1595. }
  1596.  
  1597. #ifdef __FLAT__
  1598. static LPARAM treeviewGetParam(HWND hctrl,HTREEITEM h)
  1599. {
  1600.     if (h) {
  1601.         TV_ITEM tvi;
  1602.         structClear(tvi);
  1603.         tvi.hItem = h;
  1604.         TreeView_GetItem(hctrl,&tvi);
  1605.         return tvi.lParam;
  1606.     }
  1607.     return 0;
  1608. }
  1609. #endif
  1610.  
  1611. static TX _textCmdselBody[3];
  1612. static TX* _textCmdsel[3];
  1613. static int _idbCmdsel;
  1614. static int _idbCmdsel0;
  1615.  
  1616. permanent BOOL _fCmdBase = TRUE;
  1617. permanent BOOL _fApiBase = TRUE;
  1618.  
  1619. void TXAPI cmdselSetIdb(int idb)
  1620. {
  1621. // APIDBの種別を指定します
  1622.     if (idb == IDB_CMDDEFAULT) {
  1623.         idb = _fCmdBase ? IDB_CMDBASE : IDB_CMD;
  1624.     } else if (idb == IDB_APIDEFAULT) {
  1625.         idb = _fApiBase ? IDB_APIBASE : IDB_API;
  1626.     }
  1627.     _idbCmdsel = idb;
  1628. }
  1629.  
  1630. static void textCmdselTerm(void)
  1631. {
  1632.     int i;
  1633.     for (i = 0;i <= 2;i++) {
  1634.         if (_textCmdsel[i]) {
  1635.             txClose(_textCmdsel[i]);
  1636.             _textCmdsel[i] = NULL;
  1637.         }
  1638.     }
  1639. }
  1640.  
  1641. static TX* textCmdselOpen(int i)
  1642. {
  1643.     TX* text = _textCmdsel[i];
  1644.     if (text) {
  1645.         txDeleteText(text);
  1646.     } else {
  1647.         text = _textCmdsel[i] = &_textCmdselBody[i];
  1648.         txInitText(text);
  1649.         txOpenText(text);
  1650.     }
  1651.     return text;
  1652. }
  1653.  
  1654. static TX* textCmdsel(int i)
  1655. {
  1656.     return _textCmdsel[i];
  1657. }
  1658.  
  1659. static NPARA txGetParam(TX* text,NPARA npara)
  1660. {
  1661.     txJumpNpara(text,npara);
  1662.     txstr szline;
  1663.     int lch = txGetPara(text,szline);
  1664.     mchar*p = szline;
  1665.     int len = strlen(p);
  1666. //information("%d %d",len,lch);
  1667.     if (len < lch) {
  1668.         p += len + 1;
  1669.         return atoi(p);
  1670.     }
  1671.     return 0;
  1672. }
  1673.  
  1674. static NPARA txSearchParam(TX* text,NPARA lParam)
  1675. {
  1676.     NPARA ret = 0;
  1677.     if (text && lParam) {
  1678.         txJumpFileTop(text);
  1679.         while(1) {
  1680.             NPARA npara = txGetParam(text,text->npara);
  1681.             if (npara == lParam) {
  1682.                 ret = text->npara;
  1683.                 break;
  1684.             }
  1685.             if (!txNextPara(text)) break;
  1686.         }
  1687.     }
  1688.     return ret;
  1689. }
  1690.  
  1691. static void txSearchParamSet(TX* text,NPARA lParam,HWND hctrl,BOOL fListbox)
  1692. {
  1693.     int isel = txSearchParam(text,lParam) - 1;
  1694.     fListbox ? ListBox_SetCurSel(hctrl,isel) : ComboBox_SetCurSel(hctrl,isel);
  1695. }
  1696.  
  1697. static BOOL _fListboxCategory;
  1698. static BOOL _fListboxList;
  1699.  
  1700. static void explainPrintf(HWND hwnd,mchar* szstr,...)
  1701. {
  1702.     HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_EXPLAIN);
  1703.     if (hctrl) {
  1704.         mchar buff[CCHLINE];
  1705.         vsprintf(buff,szstr,(void*)(&szstr + 1));
  1706.         SendMessage(hctrl,LB_RESETCONTENT,0,0);
  1707.         SendMessage(hctrl,LB_ADDSTRING,0,buff);
  1708.     }
  1709. }
  1710.  
  1711. static NPARA cmdselSelected(HWND hwnd,TX* textCmd,NPARA nparaCmd)
  1712. {
  1713.     NPARA npara = txGetParam(textCmd,nparaCmd);
  1714.     TX body;
  1715.     TX* text = &body;
  1716.     txInitText(text);
  1717.     if (txOpenText(text)) {
  1718.         txstr szcmd;
  1719.         TX* db = apidb2GetText(_idbCmdsel);
  1720.         txJumpNpara(db,npara);
  1721.         PARAATR paraatr;
  1722.         txParaatrRead(db,¶atr,NULL);
  1723.         apidb2GetCmd(_idbCmdsel,szcmd);
  1724.         txInsertLine(text,szcmd);
  1725.         apidb2GetExplain(_idbCmdsel,text);
  1726.         listboxFromText(GetDlgItem(hwnd,IDD_CMDSEL_EXPLAIN),text);
  1727.         //
  1728.         {
  1729.             HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_KEYLIST);
  1730.             if (hctrl) {
  1731.                 WZCMD wzcmd = wzcmdFromSzcmd(szcmd);
  1732.                 WZKEY wzkey = 0;
  1733.                 txDeleteText(text);
  1734.                 while(1) {
  1735.                     if (wzkey = txKeySearch(textf,wzkey,wzcmd)) {
  1736.                         mchar szkey[CCHKEY];
  1737.                         txWzkeyToSzkey(textf,wzkey,szkey);
  1738.                         mchar szstr[CCHWORD];
  1739.                         szkeyToStr(szkey,szstr);
  1740.                         txInsertLine(text,szstr);
  1741.                     } else {
  1742.                         break;
  1743.                     }
  1744.                 }
  1745.                 listboxFromText(hctrl,text);
  1746.             }
  1747.         }
  1748.         txClose(text);
  1749.         //
  1750.         if (paraatr.modeTitle == 2) {// カテゴリの場合は送らない
  1751.             SendMessage(hwnd,CSN_SETSZCMD,0,(mchar*)szcmd);
  1752.         }
  1753.     }
  1754.     return npara;
  1755. }
  1756.  
  1757. BOOL cmdselSetSzcmd(HWND hwnd,mchar* szcmd,SEARCHMODE searchmode)
  1758. {
  1759.     HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_TREELIST);
  1760.     BOOL ret = FALSE;
  1761.     BOOL fNull = !(szcmd && *szcmd);
  1762.     if (hctrl) {
  1763. #ifdef __FLAT__
  1764.         NPARA npara = 0;
  1765.         if (!fNull) npara = apidb2SearchCmd(_idbCmdsel,szcmd,searchmode);
  1766.         if (npara) {
  1767.             npara = txSearchParam(textCmdsel(0),npara);
  1768.             if (npara) {
  1769.                 HTREEITEM h = treeviewSearchParam(hctrl,npara);
  1770.                 if (h) {
  1771.                     TreeView_SelectItem(hctrl,h);
  1772.                     ret = TRUE;
  1773.                 }
  1774.             }
  1775.         }
  1776.         if (!ret) {
  1777.             TreeView_SelectItem(hctrl,NULL);
  1778.         }
  1779. #endif
  1780.     } else {
  1781.         NPARA npara = 0;
  1782. //statprintf(szcmd);
  1783.         if (!fNull) npara = apidb2SearchCmd(_idbCmdsel,szcmd,searchmode);
  1784.         HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_CATEGORY);
  1785.         if (hctrl) {
  1786.             NPARA nparaCategory = 0;
  1787.             if (npara) {
  1788.                 nparaCategory = apidb2GetCategoryNpara(_idbCmdsel);
  1789.                 if (nparaCategory) {
  1790.                     ret = TRUE;
  1791.                 }
  1792.             }
  1793.             //
  1794.             txSearchParamSet(textCmdsel(1),nparaCategory,hctrl,_fListboxCategory);
  1795.             FORWARD_WM_COMMAND(hwnd,IDD_CMDSEL_CATEGORY,hctrl,LBN_SELCHANGE,SendMessage);
  1796.             //
  1797.             HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_LIST);
  1798.             txSearchParamSet(textCmdsel(2),npara,hctrl,_fListboxList);
  1799.             FORWARD_WM_COMMAND(hwnd,IDD_CMDSEL_LIST,hctrl,LBN_SELCHANGE,SendMessage);
  1800.         } else {
  1801.             // 「キー一覧」など、ツリー、カテゴリ、コマンドリストがない場合
  1802.             TX body;
  1803.             TX* text = &body;
  1804.             txInitText(text);
  1805.             if (txOpenText(text)) {
  1806.                 if (npara) {
  1807.                     ret = TRUE;
  1808.                     txInsertLine(text,szcmd);
  1809.                     apidb2GetExplain(_idbCmdsel,text);
  1810.                     listboxFromText(GetDlgItem(hwnd,IDD_CMDSEL_EXPLAIN),text);
  1811.                 }
  1812.                 txClose(text);
  1813.             }
  1814.         }
  1815.     }
  1816.     if (!ret) {
  1817.         if (fNull) {
  1818.             explainPrintf(hwnd,"コマンドが割り当てられていません");
  1819.             return FALSE;
  1820.         } else {
  1821.             explainPrintf(hwnd,"%sはコマンド一覧にありません",szcmd);
  1822.             return FALSE;
  1823.         }
  1824.     }
  1825.     return ret;
  1826. }
  1827.  
  1828. BOOL cmdselSearchNext(HWND hwnd);
  1829.  
  1830. BOOL cmdselSearch(HWND hwnd,mchar* szcmd,SEARCHMODE searchmode)
  1831. {
  1832.     BOOL ret = FALSE;
  1833.     _szapi = "";
  1834.     _adrSearch = 0;
  1835.     if (szcmd) {
  1836.         _txstrSearch = szcmd;
  1837.         _searchmode = searchmode;
  1838.     }
  1839.     //
  1840.     HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_SEARCHNEXT);
  1841.     if (hctrl) {
  1842.         EnableWindow(hctrl,TRUE);
  1843.         cmdselSearchNext(hwnd);
  1844.     }
  1845.     return ret;
  1846. }
  1847.  
  1848. BOOL cmdselUiSearch(HWND hwnd)
  1849. {
  1850.     if (txuiSearchSetForEx(text,"コマンドの検索",_txstrSearch,&_searchmode)) {
  1851.         return cmdselSearch(hwnd,NULL,0);
  1852.     }
  1853.     return FALSE;
  1854. }
  1855.  
  1856. BOOL cmdselUiSearchInit(HWND hwnd,mchar* szFind,DWORD searchmode)
  1857. {
  1858.     _txstrSearch = szFind;
  1859.     _searchmode = searchmode;
  1860.     return cmdselUiSearch(hwnd);
  1861. }
  1862.  
  1863. BOOL cmdselSearchNext(HWND hwnd)
  1864. {
  1865.     if (_adrSearch == -1) return FALSE;
  1866.     BOOL ret = TRUE;
  1867.     BOOL fBase = IDB_ISBASE(_idbCmdsel);
  1868.     TX* db = apidb2GetText(_idbCmdsel);
  1869.     txJumpAddress(db,_adrSearch);
  1870.     while(1) {
  1871.         if (txSearchEx(db,_txstrSearch,_searchmode)) {
  1872.             IFILE adr = txGetAddress(db);
  1873.             NPARA npara = apidb2GetCmdNpara(_idbCmdsel);
  1874.             if (npara) {
  1875.                 txstr szapi;
  1876.                 txstr szcategory;
  1877.                 txJumpNpara(db,npara);
  1878.                 if (fBase && !IsCmdBase(db,_idbCmdsel)) {
  1879.                     // 基本コマンドでなければスキップ
  1880.                     txJumpAddress(db,adr);
  1881.                 } else {
  1882.                     apidb2GetCmd(_idbCmdsel,szapi);
  1883.                     txJumpNpara(db,apidb2GetCategoryNpara(_idbCmdsel));
  1884.                     apidb2GetCmd(_idbCmdsel,szcategory);
  1885.                     if (_szapi == szapi) {
  1886.                         // 前回見つけたのと同じ場合はスキップ
  1887.                         txJumpAddress(db,adr);
  1888.                     } else {
  1889. //information("%s %s",_szapi,szapi);
  1890.                         _szapi = szapi;
  1891.                         // 本当にマッチしたか調べる
  1892.                         // TXCMDモードなのに、APIにマッチしたかもしれない
  1893.                         // こうゆう場合はハネる
  1894.                         _adrSearch = adr;
  1895.                         statprintf("見つかりました");
  1896.                         SendMessage(hwnd,CS_SETSZCMD,0,(mchar*)szapi);
  1897.                         ret = TRUE;
  1898.                         break;
  1899.                     }
  1900.                 }
  1901.             }
  1902.         } else {
  1903.             statprintf("見つかりませんでした");
  1904.             SetFocus(GetDlgItem(hwnd,IDD_CMDSEL_SEARCH));//focus windowをdisenableしないように
  1905.             EnableWindow(GetDlgItem(hwnd,IDD_CMDSEL_SEARCHNEXT),FALSE);
  1906.             _adrSearch = -1;
  1907.             break;
  1908.         }
  1909.     }
  1910.     return ret;
  1911. }
  1912.  
  1913. static void cmdselFlush(HWND hwnd)
  1914. {
  1915.     HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_TREELIST);
  1916.     BOOL fCacheFlush = (_idbCmdsel != _idbCmdsel0);
  1917.     _idbCmdsel0 = _idbCmdsel;
  1918.     if (hctrl) {
  1919.         // WZ3.0
  1920.         TX* text = textCmdsel(0);
  1921.         if (text && !fCacheFlush) {
  1922.             // cached
  1923.             txSetHigh(text);
  1924.             treeviewFromText(hctrl,text);
  1925.             txResetHigh(text);
  1926.         } else {
  1927.             text = textCmdselOpen(0);
  1928.             if (text) {
  1929.                 txSetHigh(text);
  1930.                 apidb2MakeTreetext(text,_idbCmdsel);
  1931.                 treeviewFromText(hctrl,text);
  1932.                 txResetHigh(text);
  1933.             }
  1934.         }
  1935.     } else {
  1936.         // WZ2.0互換
  1937.         HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_CATEGORY);
  1938.         mchar buff[CCHWORD];
  1939.         GetClassName(hctrl,buff,CCHWORD);
  1940.         _fListboxCategory = !stricmp(buff,"listbox");
  1941.         //
  1942.         TX* text = textCmdsel(1);
  1943.         if (text && !fCacheFlush) {
  1944.             // cached
  1945.         } else {
  1946.             text = textCmdselOpen(1);
  1947.             if (text) {
  1948.                 apidb2MakeCategorytext(text,_idbCmdsel);
  1949.             }
  1950.         }
  1951.         if (text) {
  1952.             if (_fListboxCategory) {
  1953.                 listboxFromText(hctrl,text);
  1954.             } else {
  1955.                 comboboxFromText(hctrl,text);
  1956.             }
  1957.         }
  1958.         //
  1959.         HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_LIST);
  1960.         GetClassName(hctrl,buff,CCHWORD);
  1961.         _fListboxList = !stricmp(buff,"listbox");
  1962.     }
  1963. }
  1964.  
  1965. static void contextmenu(HWND hwnd,POINT* _point)
  1966. {
  1967.     HMENU hmenu = menuNew();
  1968.     //
  1969.     menuStr(hmenu,"検索(&F)",IDD_CMDSEL_SEARCH);
  1970.     menuStr(hmenu,"次検索(&N)",IDD_CMDSEL_SEARCHNEXT);
  1971.     menuSepa(hmenu);
  1972.     BOOL fBase = IDB_ISBASE(_idbCmdsel);
  1973.     BOOL fCmd = IDB_ISCMD(_idbCmdsel);
  1974.     AppendMenu(hmenu,MF_STRING|(MF_CHECKED*!fBase),IDD_CMDSEL_DISPALL,"全て表示(&A)");
  1975.     AppendMenu(hmenu,MF_STRING|(MF_CHECKED*fBase),IDD_CMDSEL_DISPBASE,"基本のみ表示(&B)");
  1976. #ifdef __FLAT__    //3.00A2 970506 API一覧の操作「分類一覧を見る」はWZ16では無効だったので、削除した
  1977.     menuSepa(hmenu);
  1978.     menuStr(hmenu,"分類一覧を見る(&C)",IDD_CMDSEL_DISPCATEGORY);
  1979. #endif
  1980.     //
  1981.     POINT point;
  1982.     if (_point) {
  1983.         point = *_point;
  1984.     } else {
  1985.         point.x = 65535;
  1986.     }
  1987.     if (point.x == 65535) {// by keyboard
  1988.         HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_TREELIST);
  1989.         #ifdef __FLAT__
  1990.         HTREEITEM h = TreeView_GetSelection(hctrl);
  1991.         if (h) {
  1992.             RECT rcItem;
  1993.             TreeView_GetItemRect(hctrl,h,&rcItem,TRUE);
  1994.             point.x = rcItem.right;
  1995.             point.y = rcItem.bottom;
  1996.             ClientToScreen(hctrl,&point);
  1997.         }
  1998.         #else
  1999.         point.x = point.y = 0;
  2000.         #endif
  2001.     }
  2002.     TrackPopupMenu(hmenu,TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_LEFTALIGN,point.x,point.y,0,hwnd,NULL);
  2003.     menuDelete(hmenu);
  2004. }
  2005.  
  2006. static void cmdselFlushSel(HWND hwnd)
  2007. {
  2008. //3.00B1 970520 new
  2009.     HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_TREELIST);
  2010.     if (hctrl) {
  2011.     } else {
  2012.         ListBox_SetCurSel(GetDlgItem(hwnd,IDD_CMDSEL_CATEGORY),0);
  2013.         FORWARD_WM_COMMAND(hwnd,IDD_CMDSEL_CATEGORY,GetDlgItem(hwnd,IDD_CMDSEL_CATEGORY),LBN_SELCHANGE,SendMessage);
  2014.     }
  2015. }
  2016.  
  2017. BOOL dlgprocCmdsel(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  2018. {
  2019.     switch(message) {
  2020.         case WM_INITDIALOG: {
  2021.             cmdselFlush(hwnd);
  2022.             HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_SEARCHNEXT);
  2023.             if (hctrl) EnableWindow(hctrl,FALSE);
  2024.             break;
  2025.         }
  2026.         case WM_DESTROY: {
  2027. #if 0// 開きっぱなしにして高速化
  2028.             textCmdselTerm();
  2029. #endif
  2030.             break;
  2031.         }
  2032.         case WM_COMMAND: {
  2033.             int id = WM_COMMAND_GetId(wParam);
  2034.             int notify = WM_COMMAND_GetNotify(wParam,lParam);
  2035.             
  2036.             if (notify == LBN_SELCHANGE || notify == CBN_SELCHANGE) {
  2037.                 if (id == IDD_CMDSEL_CATEGORY) {
  2038.                     HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_CATEGORY);
  2039.                     int isel = SendMessage(hctrl,_fListboxCategory ? LB_GETCURSEL : CB_GETCURSEL,0,0);
  2040. //information("%d",isel);
  2041.                     if (isel >= 0) {
  2042.                         NPARA npara = cmdselSelected(hwnd,textCmdsel(1),isel+1);
  2043. //information("%d",npara);
  2044.                         if (npara) {
  2045.                             TX* text = textCmdselOpen(2);
  2046.                             TX* db = apidb2GetText(_idbCmdsel);
  2047.                             txJumpNpara(db,npara);
  2048.                             apidb2MakeCommandtext(text,_idbCmdsel);
  2049.                             if (_fListboxList) {
  2050.                                 listboxFromText(GetDlgItem(hwnd,IDD_CMDSEL_LIST),text);
  2051.                             } else {
  2052.                                 comboboxFromText(GetDlgItem(hwnd,IDD_CMDSEL_LIST),text);
  2053.                             }
  2054.                         }
  2055.                     }
  2056.                 } else if (id == IDD_CMDSEL_LIST) {
  2057.                     HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_LIST);
  2058.                     int isel = SendMessage(hctrl,_fListboxList ? LB_GETCURSEL : CB_GETCURSEL,0,0);
  2059.                     if (isel >= 0) {
  2060.                         cmdselSelected(hwnd,textCmdsel(2),isel+1);
  2061.                     } else {
  2062.                         ListBox_ResetContent(GetDlgItem(hwnd,IDD_CMDSEL_EXPLAIN));
  2063.                     }
  2064.                 }
  2065.             }
  2066.             switch(id) {
  2067.                 case IDD_CMDSEL_SEARCH: {
  2068. #if 0// TreeView_GetRootを使うとソートできない。再帰ソートの仕方不明
  2069. HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_TREELIST);
  2070. HTREEITEM h = TreeView_GetSelection(hctrl);
  2071. h = NULL;
  2072. TreeView_SortChildren(hctrl,h,2);
  2073. return TRUE;
  2074. #endif
  2075.                     cmdselUiSearch(hwnd);
  2076.                     return TRUE;
  2077.                 }
  2078.                 case IDD_CMDSEL_SEARCHNEXT: {
  2079.                     cmdselSearchNext(hwnd);
  2080.                     return TRUE;
  2081.                 }
  2082.                 case IDD_CMDSEL_DISPALL: {
  2083.                     BOOL fBase = IDB_ISBASE(_idbCmdsel);
  2084.                     BOOL fCmd = IDB_ISCMD(_idbCmdsel);
  2085.                     if (fBase) {
  2086.                         _idbCmdsel = fCmd ? IDB_CMD : IDB_API;
  2087.                         cmdselFlush(hwnd);
  2088.                         fCmd ? (_fCmdBase = FALSE) : (_fApiBase = FALSE);
  2089.                         cmdselFlushSel(hwnd);//3.00B1 970520 
  2090.                     }
  2091.                     break;
  2092.                 }
  2093.                 case IDD_CMDSEL_DISPBASE: {
  2094.                     BOOL fBase = IDB_ISBASE(_idbCmdsel);
  2095.                     BOOL fCmd = IDB_ISCMD(_idbCmdsel);
  2096.                     if (!fBase) {
  2097.                         _idbCmdsel = fCmd ? IDB_CMDBASE : IDB_APIBASE;
  2098.                         cmdselFlush(hwnd);
  2099.                         fCmd ? (_fCmdBase = TRUE) : (_fApiBase = TRUE);
  2100.                         cmdselFlushSel(hwnd);//3.00B1 970520 
  2101.                     }
  2102.                     break;
  2103.                 }
  2104.                 case IDD_CMDSEL_CONTEXTMENU: //2.99A 970321 
  2105.                 case IDD_CONTEXTMENU: {
  2106.                     //2.95 970131 
  2107.                     HWND hctrl = GetDlgItem(hwnd,id);
  2108.                     RECT r;
  2109.                     GetWindowRect(hctrl,&r);
  2110.                     POINT p;
  2111.                     p.x = r.left + rectCx(&r) / 2;
  2112.                     p.y = r.top + rectCy(&r) / 2;
  2113.                     contextmenu(hwnd,&p);
  2114.                     break;
  2115.                 }
  2116. #ifdef __FLAT__
  2117.                 case IDD_CMDSEL_DISPCATEGORY: {
  2118.                     HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_TREELIST);
  2119.                     HTREEITEM h = TreeView_GetRoot(hctrl);
  2120.                     while(h) {
  2121.                         TreeView_Expand(hctrl,h,TVE_COLLAPSE);
  2122.                         h = TreeView_GetNextSibling(hctrl,h);
  2123.                     }
  2124.                     break;
  2125.                 }
  2126. #endif
  2127.             }
  2128.             break;
  2129.         }
  2130. #ifdef __FLAT__
  2131.         case WM_CONTEXTMENU: {
  2132.             if (wParam == GetDlgItem(hwnd,IDD_CMDSEL_TREELIST)) {
  2133.                 POINT point;
  2134.                 point.x = LOWORD(lParam);
  2135.                 point.y = HIWORD(lParam);
  2136.                 contextmenu(hwnd,&point);
  2137.                 return TRUE;
  2138.             }
  2139.             break;
  2140.         }
  2141.         case WM_NOTIFY: {
  2142.             TV_DISPINFO* nm = (LPVOID)lParam;
  2143.             if (nm->hdr.idFrom == IDD_CMDSEL_TREELIST) {
  2144.                 switch(nm->hdr.code) {
  2145.                     case TVN_SELCHANGED: {
  2146.                         HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_TREELIST);
  2147.                         LPARAM lParam = treeviewGetParam(hctrl,TreeView_GetSelection(hctrl));
  2148.                         cmdselSelected(hwnd,textCmdsel(0),lParam);
  2149.                         break;
  2150.                     }
  2151.                 }
  2152.             }
  2153.             break;
  2154.         }
  2155. #endif
  2156.         case CS_SETSZCMD: {
  2157.             cmdselSetSzcmd(hwnd,(mchar*)lParam,0);
  2158.             break;
  2159.         }
  2160.     }
  2161.     return FALSE;
  2162. }
  2163.  
  2164. //##応用関数
  2165.  
  2166. #define IDD_EXEC        1000
  2167. #define IDD_INSERTTEXT    1001
  2168.  
  2169. mchar* _szSearchApi;
  2170. #define WM_TXSEARCHCMD    (WM_USER + 5)
  2171.  
  2172. BOOL dlgprocCmdselAp(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  2173. {
  2174.     static WZCMD wzcmd;
  2175.     CMDSEL_HOOK
  2176.     switch(message) {
  2177.         case WM_INITDIALOG: {
  2178.             wzcmd = 0;
  2179.             if (_szSearchApi) PostMessage(hwnd,WM_TXSEARCHCMD,0,_szSearchApi);
  2180.             break;
  2181.         }
  2182.         case WM_COMMAND: {
  2183.             int id = WM_COMMAND_GetId(wParam);
  2184.             int notify = WM_COMMAND_GetNotify(wParam,lParam);
  2185.             switch(id) {
  2186.                 case IDD_EXEC: {
  2187.                     if (wzcmd) {
  2188.                         PostMessage(text->hwndbase,WM_COMMAND,IDM_WZCMDTOP + wzcmd,0);
  2189.                     } else {
  2190.                         return TRUE;
  2191.                     }
  2192.                     break;
  2193.                 }
  2194.                 case IDD_INSERTTEXT: {
  2195.                     if (wzcmd) {
  2196.                         if (IDB_ISCMD(_idbCmdsel)) {
  2197.                             txInsertf(text,"call(\"%s\");",wzcmdToSzcmd(wzcmd));
  2198.                         } else {
  2199.                             txJumpParaTop(text);
  2200.                             //
  2201.                             HWND hctrl = GetDlgItem(hwnd,IDD_CMDSEL_EXPLAIN);
  2202.                             int n = ListBox_GetCount(hctrl);
  2203.                             for (int i = 0;i < n;i++) {
  2204.                                 int lch = ListBox_GetTextLen(hctrl,i);
  2205.                                 mchar buff[CCHWORD];
  2206.                                 if (lch < cchof(buff)) {
  2207.                                     ListBox_GetText(hctrl,i,buff);
  2208.                                     txInsertLine(text,buff);
  2209.                                 }
  2210.                             }
  2211.                         }
  2212.                     } else {
  2213.                         return TRUE;
  2214.                     }
  2215.                     break;
  2216.                 }
  2217.             }
  2218.             break;
  2219.         }
  2220.         case CSN_SETSZCMD: {
  2221.             mchar* szcmd = (LPVOID)lParam;
  2222.             if (szcmd) {
  2223.                 wzcmd = wzcmdRegister(szcmd);
  2224.             }
  2225.             break;
  2226.         }
  2227.         case WM_TXSEARCHCMD: {
  2228.             mchar* szcmd = (LPVOID)lParam;
  2229.             if (szcmd) {
  2230.                 if (!cmdselSetSzcmd(hwnd,szcmd,SEARCH_NOSENSECASE)) {
  2231. //                    histAdd(HIST_SEARCH,szcmd);
  2232. #if 1//2.99C 970324 txapihelp 省略形TXAPIも検索できるようにした
  2233.                     BOOL f = FALSE;
  2234.                     if (strnicmp(szcmd,"tx",2)) {
  2235.                         txstr sz = "tx";
  2236.                         sz += szcmd;
  2237.     #if 1//2.99F 970404 "open2"の省略形TXAPI検索に対応
  2238.                         mchar* p = strGetLast(sz);
  2239.                         if (p && *p == '2') *p = 0;
  2240.     #endif
  2241.                         f = cmdselSetSzcmd(hwnd,sz,SEARCH_NOSENSECASE);
  2242.                     }
  2243.                     if (!f) cmdselUiSearchInit(hwnd,szcmd,SEARCH_NOSENSECASE);
  2244. #else
  2245.                     cmdselUiSearchInit(hwnd,szcmd,SEARCH_NOSENSECASE);
  2246. #endif
  2247.                 }
  2248.             }
  2249.             break;
  2250.         }
  2251.     }
  2252.     return FALSE;
  2253. }
  2254.  
  2255. cmdlist(int idb)
  2256. {
  2257.     BOOL fApi = FALSE;
  2258.     cmdselSetIdb(idb);
  2259.     HDIALOG hd;
  2260.     if (idb == IDB_API || idb == IDB_APIBASE) {
  2261.         fApi = TRUE;
  2262.         hd = dialog("API一覧");
  2263.     } else {
  2264.         hd = dialog("機能一覧");
  2265.     }
  2266.     dialogSetHookEx(hd,"\m.dlgprocCmdselAp");
  2267.     //
  2268.     if (_fwin40) {
  2269.         #ifdef __FLAT__
  2270.         dialogControlID(hd,IDD_CMDSEL_TREELIST);
  2271.         dialogTree(hd,"コマンド(&C):",NULL,61,15);//2.99C 970326 60->61,20->15 VGAで機能一覧がはみ出た
  2272.         #endif
  2273.     } else {
  2274.         #if 1
  2275.             dialogControlID(hd,IDD_CMDSEL_CATEGORY);
  2276.             dialogList(hd,"分類(&C):",NULL,30,10);
  2277.             dialogLFV(hd);
  2278.             dialogControlID(hd,IDD_CMDSEL_LIST);
  2279.             dialogList(hd,"コマンド(&M):",NULL,30,10);
  2280.             dialogLF(hd);
  2281.         #else
  2282.             DTRECT r1,r2;
  2283.             dialogGetPos(hd,&r1);
  2284.             r1.cx = DTCX * 12;r1.cy = DTCY;
  2285.             r2.x = r1.x + r1.cx + DTCX;
  2286.             r2.y = r1.y;
  2287.             r2.cx = DTCX * 18;r2.cy = DTCYBOX;
  2288.             //
  2289.             r2.cy = DTCY * 10;
  2290.             _dialogAddLtext(hd,"分類(&C):",&r1);
  2291.             _dialogAddCombobox(hd,IDD_CMDSEL_CATEGORY,&r2);
  2292.             dialogControlHelp(hd,359);
  2293.             _dialogAddControlInfo(hd,IDD_CMDSEL_CATEGORY);
  2294.             r1.y = r2.y = r2.y + DTCY * 2;
  2295.             //
  2296.             _dialogAddLtext(hd,"コマンド(&M):",&r1);
  2297.             r2.x = r1.x;r2.cx = DTCX * 31;r2.y += DTCY*3/2;//2.00B コマンド一覧を大きくした
  2298.             _dialogAddCombobox(hd,IDD_CMDSEL_LIST,&r2);
  2299.             _dialogAddControlInfo(hd,IDD_CMDSEL_LIST);
  2300.             r1.y = r2.y = r2.y + DTCY * 2;
  2301.             dialogSetPosY(hd,r1.y);
  2302.         #endif
  2303.     }
  2304. #if 0//2.99C 970326 
  2305.     if (IDB_ISCMD(idb)) {
  2306.         dialogLFV(hd);
  2307.         dialogControlID(hd,IDD_CMDSEL_KEYLIST);
  2308.         dialogControlHelp(hd,230);
  2309.         dialogList(hd,"キー割り当て(&K):",NULL,20,4);
  2310.         dialogLF(hd);
  2311.     }
  2312. #endif
  2313.     dialogSetH(hd);//2.99C 970326 
  2314.     //2.95 970131 
  2315.     dialogControlID(hd,IDD_CONTEXTMENU);
  2316.     dialogButton(hd,fApi ? "API一覧の操作(&O)..." : "機能一覧の操作(&O)...",NULL,20);//2.99C 970326 旧「コンテキストメニュー(&C)...」
  2317.     //2.99C 970326 
  2318.     if (IDB_ISCMD(idb)) {
  2319.         dialogIndent(hd,4);
  2320.         dialogCaptionDynamic(hd,"キー割り当て(&K):",_fwin40 ? 14 : 15);
  2321.         dialogControlID(hd,IDD_CMDSEL_KEYLIST);
  2322.         dialogControlHelp(hd,230);
  2323.         dialogList(hd,NULL,NULL,20,_fwin40 ? 4 : 3);
  2324.     }
  2325.     dialogLFSetV(hd);
  2326.     DTRECT rCmd;    // コマンドボタンを配置する位置
  2327.     {
  2328.         DTRECT r;
  2329.         dialogGetPos(hd,&r);
  2330.         dialogCmdLFV(hd);
  2331.         dialogGetPos(hd,&rCmd);
  2332.         dialogSetPos(hd,&r);
  2333.     }
  2334.     //
  2335.     dialogSetIntXY(hd,0,0);
  2336.     dialogCaption(hd,"詳細(&D):");
  2337.     dialogResetInt(hd);
  2338.     DTRECT r;
  2339.     dialogGetPos(hd,&r);
  2340.     r.cx = DTCX * 80;
  2341.     r.cy = DTCY * 8;
  2342.     _dialogAddListbox(hd,IDD_CMDSEL_EXPLAIN,&r);
  2343.     dialogControlHelp(hd,372);
  2344.     _dialogAddControlInfo(hd,IDD_CMDSEL_EXPLAIN);
  2345.     //
  2346.     dialogLFV(hd);
  2347.     dialogSetPos(hd,&rCmd);//2.99C 970326 
  2348.     int cx = 16;
  2349.     dialogControlID(hd,IDCANCEL);
  2350.     dialogCmdDefault(hd,"閉じる",cx);
  2351.     dialogControlID(hd,IDD_EXEC);
  2352.     dialogCmd(hd,"実行(&X)",cx);
  2353.     dialogSpaceV(hd);
  2354.     dialogControlID(hd,IDD_INSERTTEXT);
  2355.     dialogCmd(hd,"テキストに挿入(&I)",cx);
  2356.     dialogControlID(hd,IDD_CMDSEL_SEARCH);
  2357.     dialogButtonCmd(hd,"検索(&F)",NULL,cx);
  2358.     dialogControlID(hd,IDD_CMDSEL_SEARCHNEXT);
  2359.     dialogButtonCmd(hd,"次検索(&N)",NULL,cx);
  2360.     //
  2361.     return dialogOpen(hd);
  2362. }
  2363.  
  2364. BOOL TXCMDBASE TXAPI uiCmdList(TX* text)
  2365. {
  2366. // 機能一覧を表示
  2367. //{#VZ} {Esc}M %M ^%W
  2368. //{#MS} +{F1}
  2369. //{#EMACS} %M
  2370.     cmdlist(IDB_CMDDEFAULT);
  2371.     return TRUE;
  2372. }
  2373.  
  2374. BOOL TXCMDBASE TXAPI uiApiList(TX* text)
  2375. {
  2376. // API一覧を表示
  2377.     cmdlist(IDB_APIDEFAULT);
  2378.     return TRUE;
  2379. }
  2380.  
  2381. void TXAPI uiApiListSearch(mchar* szapi)
  2382. {
  2383. // API一覧を表示し、szapiを検索して説明を表示します。
  2384.     _szSearchApi = szapi;
  2385.     cmdlist(IDB_API);
  2386.     _szSearchApi = NULL;
  2387. }
  2388.  
  2389. //{###コマンドチップヘルプ}
  2390.  
  2391. extern "dialoga" int _contexthelp(TX* text,int x,int y);
  2392.  
  2393. BOOL TXAPI apidb2TipHelp(mchar* szcmd)
  2394. {
  2395. //3.00B1 970522 new
  2396.     BOOL ret = FALSE;
  2397.     int idb = IDB_CMD;
  2398.     TX* db = apidb2Open(idb);
  2399.     if (db) {
  2400.         txstr szfind = "(Cmd:";
  2401.         szfind += szcmd;
  2402.         szfind += ")";
  2403.         txJumpFileTop(db);
  2404.         if (txSearchEx(db,szfind,SEARCH_NOSENSECASE)) {
  2405.             TX* text = textopen(NULL);
  2406.             if (text) {
  2407.                 apidb2GetExplain(idb,text);
  2408.                 RECT r;
  2409.                 GetWindowRect(textf->hwndbase,&r);
  2410.                 _contexthelp(text,r.left + systemfontGetCx()*10,r.top + systemfontGetCy()*5);
  2411.             }
  2412.             textclose(text);
  2413.         }
  2414.     }
  2415.     return ret;
  2416. }
  2417.  
  2418. void main(void)
  2419. {
  2420. //call("custmize.uiKeyCust");return;
  2421. //test();return;
  2422.     apidb2Remake();
  2423.     call("custmize.createEnglishMenuForMaster");
  2424.     return;
  2425. //    uiCmdList();
  2426. //uiApiList();
  2427. }
  2428.  
  2429. void TXAPI apidb2FlushCache(void)
  2430. {
  2431. // キャッシングをフラッシュします
  2432.     apidb2CloseAll();
  2433.     textCmdselTerm();
  2434. }
  2435.  
  2436. __delete
  2437. {
  2438.     apidb2FlushCache();
  2439. }
  2440.  
  2441.