Tcl Source Code

Changes On Branch tip-106-impl
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch tip-106-impl Excluding Merge-Ins

This is equivalent to a diff from d36a06647e to 5199131175

2012-05-21
11:31
TIP #106: Add Encoding Abilities to the [dde] Command check-in: caff0b1e87 user: jan.nijtmans tags: trunk
2012-05-16
09:29
FRQ 3527238: first experiment implementing CF_UNICODETEXT for dde check-in: ba88b2a19d user: jan.nijtmans tags: frq-3527238
2012-05-13
14:53
Protect against receiving strings without ending \0, as external applications (or Tcl with TIP #106)... check-in: 7e5a842ffb user: jan.nijtmans tags: trunk
11:04
merge trunk check-in: b939500e30 user: dkf tags: tip-400-impl
2012-05-11
12:50
fix handling of closing '\0' for -binary data update dde version to 1.4.0 Closed-Leaf check-in: 5199131175 user: jan.nijtmans tags: tip-106-impl
2012-05-10
22:01
merge trunk check-in: 965fe4924b user: jan.nijtmans tags: tip-106-impl
21:57
first shot at internationalization of dde check-in: d36a06647e user: jan.nijtmans tags: trunk
21:48
[Bug 473946]: special characters not correctly sent check-in: 1aee402b1b user: jan.nijtmans tags: trunk

Changes to doc/dde.n.

13
14
15
16
17
18
19

20

21
22


23
24
25
26
27
28
29
13
14
15
16
17
18
19
20

21
22

23
24
25
26
27
28
29
30
31







+
-
+

-
+
+







dde \- Execute a Dynamic Data Exchange command
.SH SYNOPSIS
.sp
\fBpackage require dde 1.3\fR
.sp
\fBdde servername\fR ?\fB\-force\fR? ?\fB\-handler \fIproc\fR? ?\fB\-\|\-\fR? ?\fItopic\fR?
.sp
.VS 8.6
\fBdde execute\fR ?\fB\-async\fR? \fIservice topic data\fR
\fBdde execute\fR ?\fB\-async\fR? ?\fB\-binary\fR? \fIservice topic data\fR
.sp
\fBdde poke\fR \fIservice topic item data\fR
\fBdde poke\fR ?\fB\-binary\fR? \fIservice topic item data\fR
.VE 8.6
.sp
\fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR
.sp
\fBdde services \fIservice topic\fR
.sp
\fBdde eval\fR ?\fB\-async\fR? \fItopic cmd \fR?\fIarg arg ...\fR?
.BE
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82





83
84

85
86
87
88
89
90
91
92




93
94
95
96
97
98
99
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110







-
+










+
+
+
+
+

-
+








+
+
+
+







The \fB\-handler\fR option specifies a Tcl procedure that will be called to
process calls to the dde server. If the package has been loaded into a
safe interpreter then a \fB\-handler\fR procedure must be defined. The
procedure is called with all the arguments provided by the remote
call.
.RE
.TP
\fBdde execute\fR ?\fB\-async\fR? \fIservice topic data\fR
\fBdde execute\fR ?\fB\-async\fR? ?\fB\-binary\fR? \fIservice topic data\fR
.
\fBdde execute\fR takes the \fIdata\fR and sends it to the server indicated
by \fIservice\fR with the topic indicated by \fItopic\fR. Typically,
\fIservice\fR is the name of an application, and \fItopic\fR is a file to
work on.  The \fIdata\fR field is given to the remote application.
Typically, the application treats the \fIdata\fR field as a script, and the
script is run in the application.  The \fB\-async\fR option requests
asynchronous invocation.  The command returns an error message if the
script did not run, unless the \fB\-async\fR flag was used, in which case
the command returns immediately with no error.
.VS 8.6
The \fB\-binary\fR option treats \fIdata\fR as binary data, otherwise an utf-8
string is sent.  Combining \fB-binary\fR with the result of
\fBencoding convertto\fR may be used to send data in arbitrary encodings.
.VE 8.6
.TP
\fBdde poke \fIservice topic item data\fR
\fBdde poke ?\fB\-binary\fR? \fIservice topic item data\fR
.
\fBdde poke\fR passes the \fIdata\fR to the server indicated by
\fIservice\fR using the \fItopic\fR and \fIitem\fR specified.  Typically,
\fIservice\fR is the name of an application.  \fItopic\fR is application
specific but can be a command to the server or the name of a file to work
on.  The \fIitem\fR is also application specific and is often not used, but
it must always be non-null.  The \fIdata\fR field is given to the remote
application.
.VS 8.6
The \fB\-binary\fR option treats \fIdata\fR as binary data, otherwise an utf-8
string is sent.
.VE 8.6
.TP
\fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR
.
\fBdde request\fR is typically used to get the value of something; the
value of a cell in Microsoft Excel or the text of a selection in
Microsoft Word. \fIservice\fR is typically the name of an application,
\fItopic\fR is typically the name of the file, and \fIitem\fR is
164
165
166
167
168
169
170



175
176
177
178
179
180
181
182
183
184







+
+
+
package require dde
\fBdde execute\fR iexplore WWW_OpenURL http://www.tcl.tk/
.CE
.SH "SEE ALSO"
tk(n), winfo(n), send(n)
.SH KEYWORDS
application, dde, name, remote execution
'\"Local Variables:
'\"mode: nroff
'\"End:

Changes to library/dde/pkgIndex.tcl.

1

2
3
4

5
6

7

1
2
3

4
5

6
7
-
+


-
+

-
+

if {![package vsatisfies [package provide Tcl] 8.5]} return
if {![package vsatisfies [package provide Tcl] 8.4]} return
if {[string compare [info sharedlibextension] .dll]} return
if {[::tcl::pkgconfig get debug]} {
    package ifneeded dde 1.3.3 [list load [file join $dir tcldde13g.dll] dde]
    package ifneeded dde 1.4.0 [list load [file join $dir tcldde14g.dll] dde]
} else {
    package ifneeded dde 1.3.3 [list load [file join $dir tcldde13.dll] dde]
    package ifneeded dde 1.4.0 [list load [file join $dir tcldde14.dll] dde]
}

Changes to tests/winDde.test.

152
153
154
155
156
157
158














159
160
161
162
163
164
165
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179







+
+
+
+
+
+
+
+
+
+
+
+
+
+







    dde eval self set a "foo"
} foo
test winDde-3.5 {DDE request locally} {win dde} {
    set a ""
    dde execute TclEval self {set a "foo"}
    dde request -binary TclEval self a
} "foo\x00"
# Set variable a to A with diaeresis (unicode C4) by relying on the fact
# that utf8 is sent (e.g. "c3 84" on the wire)
test winDde-3.6 {DDE request utf8} {win dde} {
    set a "not set"
    dde execute TclEval self "set a \xc4"
    scan $a %c
} 196
# Set variable a to A with diaeresis (unicode C4) using binary execute
# and compose utf-8 (e.g. "c3 84" ) manualy
test winDde-3.7 {DDE request binary} {win dde} {
    set a "not set"
    dde execute -binary TclEval self "set a \xc3\x84\x00"
    scan $a %c
} 196

# -------------------------------------------------------------------------

test winDde-4.1 {DDE execute remotely} {stdio win dde} {
    set a ""
    set name child-4.1
    set child [createChildProcess $name]
198
199
200
201
202
203
204
205

206
207
208
209
210
211

212
213
214
215
216
217
218
212
213
214
215
216
217
218

219
220
221
222
223
224

225
226
227
228
229
230
231
232







-
+





-
+







    set a
} foo

# -------------------------------------------------------------------------

test winDde-5.1 {check for bad arguments} -constraints {win dde} -body {
    dde execute "" "" "" ""
} -returnCodes error -result {wrong # args: should be "dde execute ?-async? serviceName topicName value"}
} -returnCodes error -result {wrong # args: should be "dde execute ?-async? ?-binary? serviceName topicName value"}
test winDde-5.2 {check for bad arguments} -constraints {win dde} -body {
    dde execute "" "" ""
} -returnCodes error -result {cannot execute null data}
test winDde-5.3 {check for bad arguments} -constraints {win dde} -body {
    dde execute -foo "" "" ""
} -returnCodes error -result {wrong # args: should be "dde execute ?-async? serviceName topicName value"}
} -returnCodes error -result {wrong # args: should be "dde execute ?-async? ?-binary? serviceName topicName value"}
test winDde-5.4 {DDE eval bad arguments} -constraints {win dde} -body {
    dde eval "" "foo"
} -returnCodes error -result {invalid service name ""}

# -------------------------------------------------------------------------

test winDde-6.1 {DDE servername bad arguments} -constraints {win dde} -body {

Changes to win/Makefile.in.

602
603
604
605
606
607
608
609

610
611

612
613
614
615

616
617
618
619

620
621

622
623
624
625

626
627
628
629
630
631
632
602
603
604
605
606
607
608

609
610

611
612
613
614

615
616
617
618

619
620

621
622
623
624

625
626
627
628
629
630
631
632







-
+

-
+



-
+



-
+

-
+



-
+







	    if [ -f $$i ]; then \
		echo "Installing $$i to $(LIB_INSTALL_DIR)/"; \
		$(COPY) $$i "$(LIB_INSTALL_DIR)"; \
	    fi; \
	    done
	@if [ -f $(DDE_DLL_FILE) ]; then \
	    echo installing $(DDE_DLL_FILE); \
	    $(COPY) $(DDE_DLL_FILE) $(LIB_INSTALL_DIR)/dde1.3; \
	    $(COPY) $(DDE_DLL_FILE) $(LIB_INSTALL_DIR)/dde${DDEDOTVER}; \
	    $(COPY) $(ROOT_DIR)/library/dde/pkgIndex.tcl \
		$(LIB_INSTALL_DIR)/dde1.3; \
		$(LIB_INSTALL_DIR)/dde${DDEDOTVER}; \
	    fi
	@if [ -f $(DDE_LIB_FILE) ]; then \
	    echo installing $(DDE_LIB_FILE); \
	    $(COPY) $(DDE_LIB_FILE) $(LIB_INSTALL_DIR)/dde1.3; \
	    $(COPY) $(DDE_LIB_FILE) $(LIB_INSTALL_DIR)/dde${DDEDOTVER}; \
	    fi
	@if [ -f $(REG_DLL_FILE) ]; then \
	    echo installing $(REG_DLL_FILE); \
	    $(COPY) $(REG_DLL_FILE) $(LIB_INSTALL_DIR)/reg1.3; \
	    $(COPY) $(REG_DLL_FILE) $(LIB_INSTALL_DIR)/reg${REGDOTVER}; \
	    $(COPY) $(ROOT_DIR)/library/reg/pkgIndex.tcl \
		$(LIB_INSTALL_DIR)/reg1.3; \
		$(LIB_INSTALL_DIR)/reg${REGDOTVER}; \
	    fi
	@if [ -f $(REG_LIB_FILE) ]; then \
	    echo installing $(REG_LIB_FILE); \
	    $(COPY) $(REG_LIB_FILE) $(LIB_INSTALL_DIR)/reg1.3; \
	    $(COPY) $(REG_LIB_FILE) $(LIB_INSTALL_DIR)/reg${REGDOTVER}; \
	    fi

install-libraries: libraries install-tzdata install-msgs
	@for i in $(prefix)/lib $(INCLUDE_INSTALL_DIR) \
		$(SCRIPT_INSTALL_DIR); \
	    do \
	    if [ ! -d $$i ] ; then \

Changes to win/configure.

1312
1313
1314
1315
1316
1317
1318
1319
1320


1321
1322
1323
1324
1325
1326
1327
1312
1313
1314
1315
1316
1317
1318


1319
1320
1321
1322
1323
1324
1325
1326
1327







-
-
+
+







TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=6
TCL_PATCH_LEVEL="b2"
VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION

TCL_DDE_VERSION=1.3
TCL_DDE_MAJOR_VERSION=1
TCL_DDE_MINOR_VERSION=3
TCL_DDE_PATCH_LEVEL="2"
TCL_DDE_MINOR_VERSION=4
TCL_DDE_PATCH_LEVEL="0"
DDEVER=$TCL_DDE_MAJOR_VERSION$TCL_DDE_MINOR_VERSION

TCL_REG_VERSION=1.3
TCL_REG_MAJOR_VERSION=1
TCL_REG_MINOR_VERSION=3
TCL_REG_PATCH_LEVEL="0"
REGVER=$TCL_REG_MAJOR_VERSION$TCL_REG_MINOR_VERSION

Changes to win/configure.in.

15
16
17
18
19
20
21
22
23


24
25
26
27
28
29
30
15
16
17
18
19
20
21


22
23
24
25
26
27
28
29
30







-
-
+
+







TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=6
TCL_PATCH_LEVEL="b2"
VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION

TCL_DDE_VERSION=1.3
TCL_DDE_MAJOR_VERSION=1
TCL_DDE_MINOR_VERSION=3
TCL_DDE_PATCH_LEVEL="2"
TCL_DDE_MINOR_VERSION=4
TCL_DDE_PATCH_LEVEL="0"
DDEVER=$TCL_DDE_MAJOR_VERSION$TCL_DDE_MINOR_VERSION

TCL_REG_VERSION=1.3
TCL_REG_MAJOR_VERSION=1
TCL_REG_MINOR_VERSION=3
TCL_REG_PATCH_LEVEL="0"
REGVER=$TCL_REG_MAJOR_VERSION$TCL_REG_MINOR_VERSION

Changes to win/tclWinDde.c.

84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98







-
+







 */

static HSZ ddeServiceGlobal = 0;
static DWORD ddeInstance;	/* The application instance handle given to us
				 * by DdeInitialize. */
static int ddeIsServer = 0;

#define TCL_DDE_VERSION		"1.3.3"
#define TCL_DDE_VERSION		"1.4.0"
#define TCL_DDE_PACKAGE_NAME	"dde"
#define TCL_DDE_SERVICE_NAME	TEXT("TclEval")
#define TCL_DDE_EXECUTE_RESULT	TEXT("$TCLEVAL$EXECUTE$RESULT")

TCL_DECLARE_MUTEX(ddeMutex)

/*
1177
1178
1179
1180
1181
1182
1183
1184







1185
1186
1187
1188
1189
1190

1191
1192
1193
1194
1195
1196
1197
1177
1178
1179
1180
1181
1182
1183

1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195

1196
1197
1198
1199
1200
1201
1202
1203







-
+
+
+
+
+
+
+





-
+







    static const char *const ddeSrvOptions[] = {
	"-force", "-handler", "--", NULL
    };
    enum DdeSrvOptions {
	DDE_SERVERNAME_EXACT, DDE_SERVERNAME_HANDLER, DDE_SERVERNAME_LAST,
    };
    static const char *const ddeExecOptions[] = {
	"-async", NULL
	"-async", "-binary", NULL
    };
    enum DdeExecOptions {
        DDE_EXEC_ASYNC, DDE_EXEC_BINARY
    };
    static const char *const ddePokeOptions[] = {
	"-binary", NULL
    };
    static const char *const ddeReqOptions[] = {
	"-binary", NULL
    };

    int index, i, length;
    int index, i, length, argIndex;
    int async = 0, binary = 0, exact = 0;
    int result = TCL_OK, firstArg = 0;
    HSZ ddeService = NULL, ddeTopic = NULL, ddeItem = NULL, ddeCookie = NULL;
    HDDEDATA ddeData = NULL, ddeItemData = NULL, ddeReturn;
    HCONV hConv = NULL;
    const TCHAR *serviceName = NULL, *topicName = NULL;
    const char *string;
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1217
1218
1219
1220
1221
1222
1223

1224
1225
1226
1227
1228
1229
1230







-







	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum DdeSubcommands) index) {
    case DDE_SERVERNAME:
	for (i = 2; i < objc; i++) {
	    int argIndex;
	    if (Tcl_GetIndexFromObj(interp, objv[i], ddeSrvOptions,
		    "option", 0, &argIndex) != TCL_OK) {
		/*
		 * If it is the last argument, it might be a server name
		 * instead of a bad argument.
		 */

1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270











1271
1272
1273




1274

1275
1276

1277
1278
1279
1280
1281
1282

















1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296





1297
1298
1299
1300
1301
1302
1303
1304
1263
1264
1265
1266
1267
1268
1269






1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280



1281
1282
1283
1284
1285
1286
1287

1288
1289
1290




1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307



1308
1309
1310
1311







1312
1313
1314
1315
1316

1317
1318
1319
1320
1321
1322
1323







-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+

+

-
+


-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-




-
-
-
-
-
-
-
+
+
+
+
+
-








	firstArg = (objc == i) ? 1 : i;
	break;
    case DDE_EXECUTE:
	if (objc == 5) {
	    firstArg = 2;
	    break;
	} else if (objc == 6) {
	    int dummy;
	    if (Tcl_GetIndexFromObj(NULL, objv[2], ddeExecOptions, "option", 0,
		    &dummy) == TCL_OK) {
		async = 1;
		firstArg = 3;
	} else if (objc >= 6 && objc <= 7) {
	    firstArg = objc - 3;
	    for (i = 2; i < firstArg; i++) {
		if (Tcl_GetIndexFromObj(interp, objv[i], ddeExecOptions,
			"option", 0, &argIndex) != TCL_OK) {
		    goto wrongDdeExecuteArgs;
		}
		if (argIndex == DDE_EXEC_ASYNC) {
		    async = 1;
		} else {
		    binary = 1;
		break;
	    }
	}
		}
	    }
	    break;
	}
	/* otherwise... */
    wrongDdeExecuteArgs:
	Tcl_WrongNumArgs(interp, 2, objv,
		"?-async? serviceName topicName value");
		"?-async? ?-binary? serviceName topicName value");
	return TCL_ERROR;
    case DDE_POKE:
	if (objc != 6) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "serviceName topicName item value");
	    return TCL_ERROR;
	if (objc == 6) {
	    firstArg = 2;
	    break;
	} else if ((objc == 7) && (Tcl_GetIndexFromObj(NULL, objv[2],
		ddePokeOptions, "option", 0, &argIndex) == TCL_OK)) {
	    binary = 1;
	    firstArg = 3;
	    break;
	}

	/*
	 * Otherwise...
	 */

	Tcl_WrongNumArgs(interp, 2, objv,
		"serviceName ?-binary? topicName item value");
	return TCL_ERROR;
	}
	firstArg = 2;
	break;
    case DDE_REQUEST:
	if (objc == 5) {
	    firstArg = 2;
	    break;
	} else if (objc == 6) {
	    int dummy;
	    if (Tcl_GetIndexFromObj(NULL, objv[2], ddeReqOptions, "option", 0,
		    &dummy) == TCL_OK) {
		binary = 1;
		firstArg = 3;
		break;
	} else if ((objc == 6) && (Tcl_GetIndexFromObj(NULL, objv[2],
		ddeReqOptions, "option", 0, &argIndex) == TCL_OK)) {
	    binary = 1;
	    firstArg = 3;
	    break;
	    }
	}

	/*
	 * Otherwise ...
	 */

	Tcl_WrongNumArgs(interp, 2, objv,
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324

1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338


1339
1340

1341
1342
1343
1344
1345
1346
1347
1348







-
-


-
+







	break;
    case DDE_EVAL:
	if (objc < 4) {
	wrongDdeEvalArgs:
	    Tcl_WrongNumArgs(interp, 2, objv, "?-async? serviceName args");
	    return TCL_ERROR;
	} else {
	    int dummy;

	    firstArg = 2;
	    if (Tcl_GetIndexFromObj(NULL, objv[2], ddeExecOptions, "option",
		    0, &dummy) == TCL_OK) {
		    0, &argIndex) == TCL_OK) {
		if (objc < 5) {
		    goto wrongDdeEvalArgs;
		}
		async = 1;
		firstArg++;
	    }
	    break;
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376












1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394

1395
1396
1397
1398
1399
1400
1401
1383
1384
1385
1386
1387
1388
1389




1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418

1419
1420
1421
1422
1423
1424
1425
1426







-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+

















-
+







	} else {
	    Tcl_ResetResult(interp);
	}
	break;

    case DDE_EXECUTE: {
	int dataLength;
	BYTE *dataString = (BYTE *) Tcl_GetStringFromObj(
		objv[firstArg + 2], &dataLength);

	if (dataLength == 0) {
	BYTE *dataString;

	if (binary) {
	    dataString = (BYTE *)
		    Tcl_GetByteArrayFromObj(objv[firstArg + 2], &dataLength);
	} else {
	    dataString = (BYTE *)
		    Tcl_GetStringFromObj(objv[firstArg + 2], &dataLength);
	    dataLength += 1;
	}

	if (dataLength <= (binary ? 0 : sizeof(TCHAR))) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj("cannot execute null data", -1));
	    Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", NULL);
	    result = TCL_ERROR;
	    break;
	}
	hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL);
	DdeFreeStringHandle(ddeInstance, ddeService);
	DdeFreeStringHandle(ddeInstance, ddeTopic);

	if (hConv == NULL) {
	    SetDdeError(interp);
	    result = TCL_ERROR;
	    break;
	}

	ddeData = DdeCreateDataHandle(ddeInstance, dataString,
		(DWORD) dataLength+1, 0, 0, CF_TEXT, 0);
		(DWORD) dataLength, 0, 0, CF_TEXT, 0);
	if (ddeData != NULL) {
	    if (async) {
		DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF, hConv, 0,
			CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
		DdeAbandonTransaction(ddeInstance, hConv, ddeResult);
	    } else {
		ddeReturn = DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF,
1441
1442
1443
1444
1445
1446
1447
1448
1449


1450
1451
1452
1453
1454
1455
1456
1466
1467
1468
1469
1470
1471
1472


1473
1474
1475
1476
1477
1478
1479
1480
1481







-
-
+
+







		    SetDdeError(interp);
		    result = TCL_ERROR;
		} else {
		    DWORD tmp;
		    const BYTE *dataString = DdeAccessData(ddeData, &tmp);

		    if (binary) {
			returnObjPtr = Tcl_NewByteArrayObj(dataString,
				(int) tmp);
			returnObjPtr =
				Tcl_NewByteArrayObj(dataString, (int) tmp);
		    } else {
			returnObjPtr = Tcl_NewStringObj((char *)dataString, -1);
		    }
		    DdeUnaccessData(ddeData);
		    DdeFreeDataHandle(ddeData);
		    Tcl_SetObjResult(interp, returnObjPtr);
		}
1470
1471
1472
1473
1474
1475
1476

1477
1478







1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491

1492
1493
1494
1495
1496
1497
1498
1495
1496
1497
1498
1499
1500
1501
1502


1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521

1522
1523
1524
1525
1526
1527
1528
1529







+
-
-
+
+
+
+
+
+
+












-
+







	if (length == 0) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj("cannot have a null item", -1));
	    Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", NULL);
	    result = TCL_ERROR;
	    goto cleanup;
	}
	if (binary) {
	dataString = (BYTE *) Tcl_GetStringFromObj(objv[firstArg + 3],
		&length);
	    dataString = (BYTE *)
		    Tcl_GetByteArrayFromObj(objv[firstArg + 3], &length);
	} else {
	    dataString = (BYTE *)
		    Tcl_GetStringFromObj(objv[firstArg + 3], &length);
	    length += 1;
	}

	hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL);
	DdeFreeStringHandle(ddeInstance, ddeService);
	DdeFreeStringHandle(ddeInstance, ddeTopic);

	if (hConv == NULL) {
	    SetDdeError(interp);
	    result = TCL_ERROR;
	} else {
	    ddeItem = DdeCreateStringHandle(ddeInstance, (void *) itemString,
		    CP_WINUNICODE);
	    if (ddeItem != NULL) {
		ddeData = DdeClientTransaction(dataString, (DWORD) length+1,
		ddeData = DdeClientTransaction(dataString, (DWORD) length,
			hConv, ddeItem, CF_TEXT, XTYP_POKE, 5000, NULL);
		if (ddeData == NULL) {
		    SetDdeError(interp);
		    result = TCL_ERROR;
		}
	    } else {
		SetDdeError(interp);