home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1999 March
/
VPR9903A.BIN
/
APUPDATE
/
VC
/
Tx300d
/
TX300D.LZH
/
DDEWZ.C
< prev
next >
Wrap
Text File
|
1997-05-06
|
11KB
|
458 lines
// WZ EDITOR 標準TLL
// DDEWZ -- DDE クライアント/サーバを実現
// Thanks dieさん,M.Ishidaさん
// コンパイルするためには windows.h の他に ddeml.h が必要。
// 現状の TX-C では DDEML.H をそのままコンパイルできないため、
// DDEML.H 自身を少し修正しなくてはならない。
// BC3.1 に付属の DDEML.H を使うなら、FNCALLBACK, PFNCALLBACK
// の定義を外し、DdeInitialize() のプロトタイプを変更する。
//
// 95/04/26 最初のバージョン
//{###DDEサポート}
//DDEクライアント/サーバを実現します
//thanks dieさん
// ----- M.Ishida 変更履歴 -----
// 95/08/30 ポーク トランザクションと要求トランザクションを追加した。
// 正式版が出るまでのつなぎです。
// 95/10/25 データバッファをアロケートするようにした。
// 95/11/30 WZ32対応及びソース公開のための整理
// 96/05/05 WZ2.0対応
// 96/05/15 ロジックは変えずにソースをWZ のオリジナルと調整
// 96/06/06 WZ16 でVisual Cのddeml.hならば修正を加えなくてもコンパイル可能に
// 96/06/12 ddeExecuteEx追加(ddeExecute の結果付きバージョン)
// 96/07/08 ddeRequest修正
// 96/08/31 ddeExecuteEx修正(DdeClientTransactionの戻り値を返す)
// ddeShowError追加
// ddeGetLastError追加
// 97/03/15 ddeRequest修正(エラー時対処強化)
// -----------------------------
#pragma TLL
#include "wintxx.h"
#if __WZ__ < 0x2000
#include "txc.h"
#endif
#export
#define DDEWZ_CMDMAX 512
#define DDEWZ_ARGMAX 4 // これは変更できません!
#endexport
#ifndef __FLAT__
#pragma multidef+
extern "ddeml.dll" {
#include "ddeml.h"
}
#pragma multidef-
#endif
static const mchar szTLL[] = "DDEWZ";
DWORD g_ddeId;
FARPROC g_farprcCallBack;
HSZ g_hszNowService;
HCONV g_hTargetConv;
HSZ g_hszTargetService;
HSZ g_hszTargetTopic;
// "wz:\*" を展開する
// pszDst が NULL の場合、pszSrc を潰す。
static void ExpandWzDir(mchar* pszSrc, mchar* pszDst)
{
static const mchar szPrefix[] = "wz:\\";
mchar szTmp[CCHPATHNAME];
if (pszDst == NULL) {
strcpy(szTmp, pszSrc);
pszDst = pszSrc;
pszSrc = szTmp;
}
if (strnicmp(pszSrc, szPrefix, strlen(szPrefix)) == 0) {
sprintf(pszDst, "%s%s", text->szexedir, pszSrc + strlen(szPrefix));
}
}
// トピック名のチェック
// トピック名は "wz:\*" 形式を受け付ける
static BOOL CheckTopic(HSZ hszTopic)
{
mchar szPath[CCHPATHNAME];
DdeQueryString(g_ddeId, hszTopic, szPath, CCHPATHNAME, CP_WINANSI);
ExpandWzDir(szPath, NULL);
return (stricmp(szPath, text->szfilename) == 0) ? TRUE : FALSE;
}
// DDE 実行トランザクション
// txXXX(text) は "!txXXX" という簡易記法を使うことが出来る。
// 他は "funcname,nnn,"str"" の形式。'*' は text とみなす。
BOOL ddeTargetExecute(mchar* pszCmd)
{
if (pszCmd[0] == '!') {
// 簡易形式
wndtxCall(text->hwndbase,&pszCmd[1]);
} else {
// 一般形式
WORD nCount = 0;
DWORD dwArg[DDEWZ_ARGMAX];
mchar* p = pszCmd;
do {
p = strchr(p, ',');
if (p != NULL) {
*(p ++) = '\0';
switch (*(p ++)) {
case '*':
dwArg[nCount] = (DWORD)text;
break;
case '"':
dwArg[nCount] = (DWORD)p;
p = strchr(p, '"');
*(p ++)= '\0';
break;
default:
p --;
dwArg[nCount] = (DWORD)atoi(p);
break;
}
nCount ++;
}
} while(p != NULL);
macroCall(pszCmd, 0, nCount,
dwArg[0], dwArg[1], dwArg[2], dwArg[3]);
}
return TRUE;
}
// DDE コールバック
//1.00H WZ32対応
HDDEDATA TXCALLBACK
ddeCallBack(UINT type, UINT fmt, HCONV hconv, HSZ hsz1, HSZ hsz2,
HDDEDATA hData, DWORD dwData1, DWORD dwData2)
{
switch (type) {
case XTYP_CONNECT: {
// 接続要求
if (g_hszNowService == NULL) {
break;
}
if (DdeCmpStringHandles(g_hszNowService, hsz2) == 0) {
return CheckTopic(hsz1);
}
break;
}
case XTYP_EXECUTE: {
// 実行トランザクション
if (CheckTopic(hsz1)) {
mchar szCmd[DDEWZ_CMDMAX];
DdeGetData(hData, szCmd, DDEWZ_CMDMAX, 0);
return ddeTargetExecute(szCmd) ? DDE_FACK : DDE_FNOTPROCESSED;
}
break;
}
}
return 0;
}
// マクロロード
BOOL __new(void)
{
g_ddeId = NULL;
g_farprcCallBack = NULL;
g_hszNowService = NULL;
g_hTargetConv = NULL;
// DDE 初期化
#ifdef __FLAT__
g_farprcCallBack = macroMakeCallBackProc("ddeCallBack", 32);
#else
g_farprcCallBack = macroMakeCallBackProc("ddeCallBack", 28);
#endif
if (DdeInitialize(&g_ddeId, g_farprcCallBack, APPCLASS_STANDARD, 0)) {
attention("%s: DDEを初期化できません", szTLL);
return FALSE;
}
return TRUE;
}
// マクロ廃棄
BOOL __delete(void)
{
// リソース廃棄
if (g_hszNowService != NULL) {
DdeNameService(g_ddeId, NULL, NULL, DNS_UNREGISTER);
DdeFreeStringHandle(g_ddeId, g_hszNowService);
g_hszNowService = NULL;
}
if (g_farprcCallBack != NULL) {
if (g_ddeId != NULL) {
DdeUninitialize(g_ddeId);
g_ddeId = NULL;
}
macroFreeCallBackProc(g_farprcCallBack);
g_farprcCallBack = NULL;
}
return TRUE;
}
BOOL TXAPI ddeStartService(void)
{
// サーバ開始
// autoexec.__txopen() に挿入する。
mchar szPath[CCHPATHNAME];
if (text->szfilename[0] == '\0') {
// とりあえず通すことにしてるけど・・
//return FALSE;
}
// サービス名登録
if (g_hszNowService == NULL) {
g_hszNowService = DdeCreateStringHandle(g_ddeId, szTLL, CP_WINANSI);
DdeNameService(g_ddeId, g_hszNowService, NULL, DNS_REGISTER);
}
return TRUE;
}
BOOL TXAPI ddeEndService(void)
{
// サーバ終了
// autoexec.__txclose() に挿入する。
// 現在は何もしていない(^^;
return TRUE;
}
BOOL TXAPI ddeConnect(mchar* pszService, mchar* pszTopic)
{
// 接続要求
if ((g_ddeId == NULL) || (g_hTargetConv != NULL)) {
return FALSE;
}
g_hszTargetService = DdeCreateStringHandle(
g_ddeId, pszService, CP_WINANSI);
g_hszTargetTopic = DdeCreateStringHandle(g_ddeId, pszTopic, CP_WINANSI);
g_hTargetConv = DdeConnect(g_ddeId,
g_hszTargetService, g_hszTargetTopic, NULL);
BOOL f = (g_hTargetConv != NULL) ? TRUE : FALSE;
return f;
}
BOOL TXAPI ddeConnectWz(mchar* szPath)
{
// 対 WZ 接続要求
return ddeConnect(szTLL, szPath);
}
BOOL TXAPI ddeDisconnect(void)
{
// 切断要求
if ((g_ddeId != NULL) && (g_hTargetConv != NULL)) {
DdeDisconnect(g_hTargetConv);
DdeFreeStringHandle(g_ddeId, g_hszTargetService);
DdeFreeStringHandle(g_ddeId, g_hszTargetTopic);
g_hTargetConv = NULL;
}
return TRUE;
}
BOOL TXAPI ddeDisconnectWz(void)
{
// 対 WZ 切断要求
return ddeDisconnect();
}
BOOL TXAPI ddeExecute(mchar* pszCmd)
{
// 実行トランザクション
if (g_hTargetConv == NULL) {
return FALSE;
}
BOOL fResult = FALSE;
// データ作成
HDDEDATA hdata = DdeCreateDataHandle(
g_ddeId, pszCmd, strlen(pszCmd) + 1, 0,
NULL, CF_TEXT, 0);
if (hdata != NULL) {
// 実行
DdeClientTransaction((void*)hdata, -1, g_hTargetConv, NULL,
CF_TEXT, XTYP_EXECUTE, 60000, NULL);
DdeFreeDataHandle(hdata);
fResult = TRUE;
}
return fResult;
}
BOOL TXAPI ddeExecuteEx(mchar* pszCmd,DWORD *dwResult)
{
// 実行トランザクション(結果付き、戻り値を返す)
if (g_hTargetConv == NULL) {
return FALSE;
}
BOOL fResult = FALSE;
// データ作成
HDDEDATA hdata = DdeCreateDataHandle(
g_ddeId, pszCmd, strlen(pszCmd) + 1, 0,
NULL, CF_TEXT, 0);
if (hdata != NULL) {
// 実行
fResult = DdeClientTransaction((void*)hdata, -1, g_hTargetConv, NULL,
CF_TEXT, XTYP_EXECUTE, 60000, dwResult);
DdeFreeDataHandle(hdata);
}
return fResult;
}
BOOL TXAPI ddePoke(mchar* szItem,mchar* szData)
{
//ポーク トランザクション
HDDEDATA hitem;
HDDEDATA hdata = NULL;
HDDEDATA hresult = FALSE;
if (g_hTargetConv == NULL) {
return FALSE;
}
hitem = DdeCreateStringHandle(g_ddeId, szItem, CP_WINANSI);
if (hitem != NULL) {
if (*szData != 0) {
hdata = DdeCreateDataHandle(g_ddeId, szData, strlen(szData)+1,0,hitem,CF_TEXT,0);
}
if (hdata != NULL) {
hresult = DdeClientTransaction((void FAR*)hdata, -1, g_hTargetConv,hitem ,
CF_TEXT, XTYP_POKE, 10000, NULL);
} else {
hresult = DdeClientTransaction("",1, g_hTargetConv,hitem ,
CF_TEXT, XTYP_POKE, 10000, NULL);
}
DdeFreeStringHandle(g_ddeId,hitem);
if (hdata != NULL)
DdeFreeDataHandle(hdata);
}
return (BOOL)hresult;
}
BOOL TXAPI ddeRequest(mchar* szItem,mchar** szData)
{
// 要求トランザクション
// 戻り値がTRUEの場合のみ、szDataは有効である。
// データバッファの用済み後はコール元が解放しなければならない
// memFree(szData);
//(例)
// mchar *szstr;
// ddeRequest("ItemName",&szstr);
// printf(sstr + "\n");
// memFree(szstr);
HDDEDATA hitem;
HDDEDATA hdata;
LPBYTE lpszData;
DWORD cbDataLen;
mchar *buff = NULL;
if (g_hTargetConv == NULL) {
return FALSE;
}
hitem = DdeCreateStringHandle(g_ddeId, szItem, CP_WINANSI);
if (hitem != NULL) {
hdata = DdeClientTransaction(NULL,0, g_hTargetConv,hitem ,
CF_TEXT, XTYP_REQUEST, 10000, NULL);
if (hdata) {
lpszData = DdeAccessData(hdata,&cbDataLen);
if (lpszData != NULL) {
buff = memAlloc(cbDataLen);
if (buff != NULL) {
memcpy(buff,lpszData,cbDataLen);
*szData = buff;
}
}
DdeUnaccessData(hdata);
DdeFreeDataHandle(hdata);
}
DdeFreeStringHandle(g_ddeId,hitem);
}
if (buff)
return TRUE;
else return FALSE;
}
// オリジナルはVCのサンプル
static PSTR Error2String(WORD error)
{
static mchar szErr[23];
static mchar *e2s[] = {
"通告受領タイムアウト",
"ビジー",
"データ受領タイムアウト",
"DLLが初期化されていない",
"DLLが使用中",
"実行受領タイムアウト",
"パラメータが無効",
"メモリ不足警告",
"メモリエラー",
"未処理",
"対話未確立",
"ポーク受領タイムアウト",
"メッセージ送信に失敗",
"再入",
"サーバー停止",
"システムエラー",
"通告停止受領タイムアウト",
"キューIDが見つからない"
};
if (!error) {
strcpy(szErr, "0");
} else if (error > DMLERR_LAST || error < DMLERR_FIRST) {
strcpy(szErr, "???");
} else {
strcpy(szErr, e2s[error - DMLERR_FIRST]);
}
return(szErr);
}
void _txapi ddeShowError(void)
{
// DDE のエラー表示
information("DDE エラー :\n " + Error2String(DdeGetLastError(g_ddeId)));
}
UINT _txapi ddeGetLastError(void)
{
// DDE の最新エラー値の取得
return DdeGetLastError(g_ddeId);
}
#if 0
main {
ddeStartService();
}
#endif