home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1999 February / VPR9902A.BIN / APUPDATE / VC / Tx300d / TX300D.LZH / DDEWZ.C < prev    next >
Text File  |  1997-05-06  |  11KB  |  458 lines

  1. // WZ EDITOR 標準TLL
  2. // DDEWZ -- DDE クライアント/サーバを実現
  3. // Thanks dieさん,M.Ishidaさん
  4.  
  5. // コンパイルするためには windows.h の他に ddeml.h が必要。
  6. // 現状の TX-C では DDEML.H をそのままコンパイルできないため、
  7. // DDEML.H 自身を少し修正しなくてはならない。
  8. // BC3.1 に付属の DDEML.H を使うなら、FNCALLBACK, PFNCALLBACK
  9. // の定義を外し、DdeInitialize() のプロトタイプを変更する。
  10. //
  11. // 95/04/26 最初のバージョン
  12.  
  13. //{###DDEサポート}
  14. //DDEクライアント/サーバを実現します
  15. //thanks dieさん
  16.  
  17. // ----- M.Ishida 変更履歴 -----
  18. // 95/08/30 ポーク トランザクションと要求トランザクションを追加した。
  19. //     正式版が出るまでのつなぎです。
  20. // 95/10/25 データバッファをアロケートするようにした。
  21. // 95/11/30 WZ32対応及びソース公開のための整理
  22. // 96/05/05 WZ2.0対応
  23. // 96/05/15 ロジックは変えずにソースをWZ のオリジナルと調整
  24. // 96/06/06 WZ16 でVisual Cのddeml.hならば修正を加えなくてもコンパイル可能に
  25. // 96/06/12 ddeExecuteEx追加(ddeExecute の結果付きバージョン)
  26. // 96/07/08 ddeRequest修正
  27. // 96/08/31 ddeExecuteEx修正(DdeClientTransactionの戻り値を返す)
  28. //            ddeShowError追加
  29. //            ddeGetLastError追加
  30. // 97/03/15 ddeRequest修正(エラー時対処強化)
  31. // -----------------------------
  32.  
  33. #pragma TLL
  34.  
  35. #include "wintxx.h"
  36. #if __WZ__ < 0x2000
  37. #include "txc.h"
  38. #endif
  39.  
  40. #export
  41. #define DDEWZ_CMDMAX        512
  42. #define DDEWZ_ARGMAX        4        // これは変更できません!
  43. #endexport
  44.  
  45. #ifndef __FLAT__
  46. #pragma multidef+
  47. extern "ddeml.dll" {
  48. #include "ddeml.h"
  49. }
  50. #pragma multidef-
  51. #endif
  52.  
  53. static const mchar szTLL[] = "DDEWZ";
  54.  
  55. DWORD g_ddeId;
  56. FARPROC g_farprcCallBack;
  57. HSZ g_hszNowService;
  58. HCONV g_hTargetConv;
  59. HSZ g_hszTargetService;
  60. HSZ g_hszTargetTopic;
  61.  
  62.  
  63.  
  64. // "wz:\*" を展開する
  65. // pszDst が NULL の場合、pszSrc を潰す。
  66. static void ExpandWzDir(mchar* pszSrc, mchar* pszDst)
  67. {
  68.     static const mchar szPrefix[] = "wz:\\";
  69.     mchar szTmp[CCHPATHNAME];
  70.     if (pszDst == NULL) {
  71.         strcpy(szTmp, pszSrc);
  72.         pszDst = pszSrc;
  73.         pszSrc = szTmp;
  74.     }
  75.     if (strnicmp(pszSrc, szPrefix, strlen(szPrefix)) == 0) {
  76.         sprintf(pszDst, "%s%s", text->szexedir, pszSrc + strlen(szPrefix));
  77.     }
  78. }
  79.  
  80.  
  81. // トピック名のチェック
  82. // トピック名は "wz:\*" 形式を受け付ける
  83. static BOOL CheckTopic(HSZ hszTopic)
  84. {
  85.     mchar szPath[CCHPATHNAME];
  86.     DdeQueryString(g_ddeId, hszTopic, szPath, CCHPATHNAME, CP_WINANSI);
  87.     ExpandWzDir(szPath, NULL);
  88.     return (stricmp(szPath, text->szfilename) == 0) ? TRUE : FALSE;
  89. }
  90.  
  91.  
  92. // DDE 実行トランザクション
  93. // txXXX(text) は "!txXXX" という簡易記法を使うことが出来る。
  94. // 他は "funcname,nnn,"str"" の形式。'*' は text とみなす。
  95. BOOL ddeTargetExecute(mchar* pszCmd)
  96. {
  97.     if (pszCmd[0] == '!') {
  98.         // 簡易形式
  99.         wndtxCall(text->hwndbase,&pszCmd[1]);
  100.     } else {
  101.         // 一般形式
  102.         WORD nCount = 0;
  103.         DWORD dwArg[DDEWZ_ARGMAX];
  104.         mchar* p = pszCmd;
  105.         do {
  106.             p = strchr(p, ',');
  107.             if (p != NULL) {
  108.                 *(p ++) = '\0';
  109.                 switch (*(p ++)) {
  110.                 case '*':
  111.                     dwArg[nCount] = (DWORD)text;
  112.                     break;
  113.                 case '"':
  114.                     dwArg[nCount] = (DWORD)p;
  115.                     p = strchr(p, '"');
  116.                     *(p ++)= '\0';
  117.                     break;
  118.                 default:
  119.                     p --;
  120.                     dwArg[nCount] = (DWORD)atoi(p);
  121.                     break;
  122.                 }
  123.                 nCount ++;
  124.             }
  125.         } while(p != NULL);
  126.         macroCall(pszCmd, 0, nCount,
  127.                     dwArg[0], dwArg[1], dwArg[2], dwArg[3]);
  128.     }
  129.     return TRUE;
  130. }
  131.  
  132.  
  133. // DDE コールバック
  134. //1.00H WZ32対応
  135. HDDEDATA TXCALLBACK
  136. ddeCallBack(UINT type, UINT fmt, HCONV hconv, HSZ hsz1, HSZ hsz2,
  137.             HDDEDATA hData, DWORD dwData1, DWORD dwData2)
  138. {
  139.     switch (type) {
  140.         case XTYP_CONNECT: {
  141.             // 接続要求
  142.             if (g_hszNowService == NULL) {
  143.                 break;
  144.             }
  145.             if (DdeCmpStringHandles(g_hszNowService, hsz2) == 0) {
  146.                 return CheckTopic(hsz1);
  147.             }
  148.             break;
  149.         }
  150.         case XTYP_EXECUTE: {
  151.             // 実行トランザクション
  152.             if (CheckTopic(hsz1)) {
  153.                 mchar szCmd[DDEWZ_CMDMAX];
  154.                 DdeGetData(hData, szCmd, DDEWZ_CMDMAX, 0);
  155.                 return ddeTargetExecute(szCmd) ? DDE_FACK : DDE_FNOTPROCESSED;
  156.             }
  157.             break;
  158.         }
  159.     }
  160.     
  161.     return 0;
  162. }
  163.  
  164.  
  165. // マクロロード
  166. BOOL __new(void)
  167. {
  168.     g_ddeId = NULL;
  169.     g_farprcCallBack = NULL;
  170.     g_hszNowService = NULL;
  171.     g_hTargetConv = NULL;
  172.     
  173.     // DDE 初期化
  174. #ifdef __FLAT__
  175.     g_farprcCallBack = macroMakeCallBackProc("ddeCallBack", 32);
  176. #else
  177.     g_farprcCallBack = macroMakeCallBackProc("ddeCallBack", 28);
  178. #endif
  179.     if (DdeInitialize(&g_ddeId, g_farprcCallBack, APPCLASS_STANDARD, 0)) {
  180.         attention("%s: DDEを初期化できません", szTLL);
  181.         return FALSE;
  182.     }
  183.     
  184.     return TRUE;
  185. }
  186.  
  187.  
  188. // マクロ廃棄
  189. BOOL __delete(void)
  190. {
  191.     // リソース廃棄
  192.     if (g_hszNowService != NULL) {
  193.         DdeNameService(g_ddeId, NULL, NULL, DNS_UNREGISTER);
  194.         DdeFreeStringHandle(g_ddeId, g_hszNowService);
  195.         g_hszNowService = NULL;
  196.     }
  197.     if (g_farprcCallBack != NULL) {
  198.         if (g_ddeId != NULL) {
  199.             DdeUninitialize(g_ddeId);
  200.             g_ddeId = NULL;
  201.         }
  202.         macroFreeCallBackProc(g_farprcCallBack);
  203.         g_farprcCallBack = NULL;
  204.     }
  205.     return TRUE;
  206. }
  207.  
  208.  
  209. BOOL TXAPI ddeStartService(void)
  210. {
  211. // サーバ開始
  212. // autoexec.__txopen() に挿入する。
  213.     mchar szPath[CCHPATHNAME];
  214.     
  215.     if (text->szfilename[0] == '\0') {
  216.         // とりあえず通すことにしてるけど・・
  217.         //return FALSE;
  218.     }
  219.     
  220.     // サービス名登録
  221.     if (g_hszNowService == NULL) {
  222.         g_hszNowService = DdeCreateStringHandle(g_ddeId, szTLL, CP_WINANSI);
  223.         DdeNameService(g_ddeId, g_hszNowService, NULL, DNS_REGISTER);
  224.     }
  225.     
  226.     return TRUE;
  227. }
  228.  
  229.  
  230. BOOL TXAPI ddeEndService(void)
  231. {
  232. // サーバ終了
  233. // autoexec.__txclose() に挿入する。
  234.     // 現在は何もしていない(^^;
  235.     return TRUE;
  236. }
  237.  
  238. BOOL TXAPI ddeConnect(mchar* pszService, mchar* pszTopic)
  239. {
  240. // 接続要求
  241.     if ((g_ddeId == NULL) || (g_hTargetConv != NULL)) {
  242.         return FALSE;
  243.     }
  244.     
  245.     g_hszTargetService = DdeCreateStringHandle(
  246.                             g_ddeId, pszService, CP_WINANSI);
  247.     g_hszTargetTopic = DdeCreateStringHandle(g_ddeId, pszTopic, CP_WINANSI);
  248.     
  249.     g_hTargetConv = DdeConnect(g_ddeId,
  250.                                 g_hszTargetService, g_hszTargetTopic, NULL);
  251.     BOOL f = (g_hTargetConv != NULL) ? TRUE : FALSE;
  252.     
  253.     return f;
  254. }
  255.  
  256.  
  257. BOOL TXAPI ddeConnectWz(mchar* szPath)
  258. {
  259. // 対 WZ 接続要求
  260.     return ddeConnect(szTLL, szPath);
  261. }
  262.  
  263.  
  264. BOOL TXAPI ddeDisconnect(void)
  265. {
  266. // 切断要求
  267.     if ((g_ddeId != NULL) && (g_hTargetConv != NULL)) {
  268.         DdeDisconnect(g_hTargetConv);
  269.         DdeFreeStringHandle(g_ddeId, g_hszTargetService);
  270.         DdeFreeStringHandle(g_ddeId, g_hszTargetTopic);
  271.         g_hTargetConv = NULL;
  272.     }
  273.     return TRUE;
  274. }
  275.  
  276.  
  277. BOOL TXAPI ddeDisconnectWz(void)
  278. {
  279. // 対 WZ 切断要求
  280.     return ddeDisconnect();
  281. }
  282.  
  283.  
  284. BOOL TXAPI ddeExecute(mchar* pszCmd)
  285. {
  286. // 実行トランザクション
  287.     if (g_hTargetConv == NULL) {
  288.         return FALSE;
  289.     }
  290.     
  291.     BOOL fResult = FALSE;
  292.     
  293.     // データ作成
  294.     HDDEDATA hdata = DdeCreateDataHandle(
  295.                             g_ddeId, pszCmd, strlen(pszCmd) + 1, 0,
  296.                             NULL, CF_TEXT, 0);
  297.     if (hdata != NULL) {
  298.         // 実行
  299.         DdeClientTransaction((void*)hdata, -1, g_hTargetConv, NULL,
  300.                                 CF_TEXT, XTYP_EXECUTE, 60000, NULL);
  301.         DdeFreeDataHandle(hdata);
  302.         fResult = TRUE;
  303.     }
  304.     
  305.     return fResult;
  306. }
  307.  
  308. BOOL TXAPI ddeExecuteEx(mchar* pszCmd,DWORD *dwResult)
  309. {
  310. // 実行トランザクション(結果付き、戻り値を返す)
  311.     if (g_hTargetConv == NULL) {
  312.         return FALSE;
  313.     }
  314.     
  315.     BOOL fResult = FALSE;
  316.  
  317.     // データ作成
  318.     HDDEDATA hdata = DdeCreateDataHandle(
  319.                             g_ddeId, pszCmd, strlen(pszCmd) + 1, 0,
  320.                             NULL, CF_TEXT, 0);
  321.     if (hdata != NULL) {
  322.         // 実行
  323.         fResult = DdeClientTransaction((void*)hdata, -1, g_hTargetConv, NULL,
  324.                                 CF_TEXT, XTYP_EXECUTE, 60000, dwResult);
  325.         DdeFreeDataHandle(hdata);
  326.     }
  327.     return fResult;
  328. }
  329.  
  330. BOOL TXAPI ddePoke(mchar* szItem,mchar* szData)
  331. {
  332. //ポーク トランザクション
  333.     HDDEDATA    hitem;
  334.     HDDEDATA    hdata = NULL;
  335.     HDDEDATA    hresult = FALSE;
  336.  
  337.     if (g_hTargetConv == NULL) {
  338.         return FALSE;
  339.     }
  340.  
  341.     hitem = DdeCreateStringHandle(g_ddeId, szItem, CP_WINANSI);
  342.     if (hitem != NULL) {
  343.         if (*szData != 0) {
  344.             hdata = DdeCreateDataHandle(g_ddeId, szData, strlen(szData)+1,0,hitem,CF_TEXT,0);
  345.         }
  346.         if (hdata != NULL) {
  347.             hresult = DdeClientTransaction((void FAR*)hdata, -1, g_hTargetConv,hitem ,
  348.                             CF_TEXT, XTYP_POKE, 10000, NULL);
  349.         } else {
  350.             hresult = DdeClientTransaction("",1, g_hTargetConv,hitem ,
  351.                             CF_TEXT, XTYP_POKE, 10000, NULL);
  352.         }
  353.         DdeFreeStringHandle(g_ddeId,hitem);
  354.         if (hdata != NULL)
  355.             DdeFreeDataHandle(hdata);
  356.     }
  357.     return (BOOL)hresult;
  358. }
  359.  
  360. BOOL TXAPI ddeRequest(mchar* szItem,mchar** szData)
  361. {
  362. // 要求トランザクション
  363. // 戻り値がTRUEの場合のみ、szDataは有効である。
  364. // データバッファの用済み後はコール元が解放しなければならない
  365. // memFree(szData);
  366.  
  367. //(例)
  368. //    mchar *szstr;
  369. //    ddeRequest("ItemName",&szstr);
  370. //    printf(sstr + "\n");
  371. //    memFree(szstr);
  372.  
  373.     HDDEDATA    hitem;
  374.     HDDEDATA    hdata;
  375.     LPBYTE        lpszData;
  376.     DWORD        cbDataLen;
  377.     mchar         *buff = NULL;
  378.  
  379.     if (g_hTargetConv == NULL) {
  380.         return FALSE;
  381.     }
  382.  
  383.     hitem = DdeCreateStringHandle(g_ddeId, szItem, CP_WINANSI);
  384.     if (hitem != NULL) {
  385.         hdata = DdeClientTransaction(NULL,0, g_hTargetConv,hitem ,
  386.                             CF_TEXT, XTYP_REQUEST, 10000, NULL);
  387.         if (hdata) {
  388.             lpszData = DdeAccessData(hdata,&cbDataLen);
  389.             if (lpszData != NULL) {
  390.                 buff = memAlloc(cbDataLen);
  391.                 if (buff != NULL) {
  392.                     memcpy(buff,lpszData,cbDataLen);
  393.                     *szData = buff;
  394.                 }
  395.             }
  396.             DdeUnaccessData(hdata);
  397.             DdeFreeDataHandle(hdata);
  398.         }
  399.         DdeFreeStringHandle(g_ddeId,hitem);
  400.     }
  401.     if (buff)
  402.         return TRUE;
  403.     else return FALSE;
  404. }
  405.  
  406. // オリジナルはVCのサンプル
  407. static    PSTR Error2String(WORD error)
  408. {
  409.     static mchar szErr[23];
  410.     static mchar *e2s[] = {
  411.         "通告受領タイムアウト",
  412.         "ビジー",
  413.         "データ受領タイムアウト",
  414.         "DLLが初期化されていない",
  415.         "DLLが使用中",
  416.         "実行受領タイムアウト",
  417.         "パラメータが無効",
  418.         "メモリ不足警告",
  419.         "メモリエラー",
  420.         "未処理",
  421.         "対話未確立",
  422.         "ポーク受領タイムアウト",
  423.         "メッセージ送信に失敗",
  424.         "再入",
  425.         "サーバー停止",
  426.         "システムエラー",
  427.         "通告停止受領タイムアウト",
  428.         "キューIDが見つからない"
  429.     };
  430.     if (!error) {
  431.         strcpy(szErr, "0");
  432.     } else if (error > DMLERR_LAST || error < DMLERR_FIRST) {
  433.         strcpy(szErr, "???");
  434.     } else {
  435.         strcpy(szErr, e2s[error - DMLERR_FIRST]);
  436.     }
  437.     return(szErr);
  438. }
  439.  
  440. void _txapi ddeShowError(void)
  441. {
  442. // DDE のエラー表示
  443.     information("DDE エラー :\n  " + Error2String(DdeGetLastError(g_ddeId)));
  444. }
  445.  
  446. UINT _txapi    ddeGetLastError(void)
  447. {
  448. // DDE の最新エラー値の取得
  449.     return DdeGetLastError(g_ddeId);
  450. }
  451.  
  452. #if 0
  453. main {
  454.         ddeStartService();
  455. }
  456. #endif
  457.  
  458.