| PREVIOUS | HEAD |
The DDE service name is ``TrueTeX'', the topic is ``View'', and the items are the commands listed below. The TRUETEX DDE commands follow the standard syntax of Microsoft Excel and the Windows Program Manager.
Here are the commands implemented:
TRUETEX will interpret command-line in the same way as a command line given in a launch via the Windows Program Manager, Windows 95 Start arguments, or a WinExec() call. Exception: issuing a print command via DDE (that is, the -w option in an execute string) will not cause the previewer to automatically exit after printing, unlike the automatic exit which normally follows with a Start, Program Manager, or WinExec() launch for printing. Follow DDE printing command(s) with a DDE Exit when you want the previewer to exit.
DDE client applications should specify file names in DDE execute strings as fully qualified paths, since there is no reliable way for clients to know the previewer's current directory. Names unqualified by a directory or qualified by a relative directory are potentially ambiguous.
Although the Open command opens a document preview window in the previewer's MDI frame window, it will not bring the frame window to the top of the Windows desktop. Typically you will want to follow an Open with a Show or SetPos command to bring the document into view.
Since the previewer examines the DVI file for changes on each repaint (if the Re-Open DVI Files on Change preference item is enabled), you need not close a previewed document when re-formatting. Simply ensure a repaint with a Show command.
You may give more than one argument to Open or Close, separated by commas; the previewer will interpret each in turn. The Show and SetPos execute strings require the prescribed arguments. Exit must not have any arguments.
TRUETEX interprets backslash (\) as an escape character in DDE execute strings to allow you to put commas, quotation marks, white space, newlines, etc., into string arguments. TRUETEX interprets the character immediately following a backslash literally, instead of using the normal syntax rules. This is similar to the C language syntax, although octal escapes and special characters (\n, \r, etc.) are not supported. You can also insert double-quotation marks by putting them in pairs, as in the style of Microsoft Excel or Visual Basic.
Note that you must use double backslashes in an execute string to indicate each single backslash in directory paths. A C program giving a literal string for a file name in an execute string therefore needs four backslashes to indicate each single directory backslash!
Double quotes around arguments are optional, but must surround any argument containing unescaped white space.
You can concatenate DDE commands into a single DDE execute string. Syntax errors (unquoted argument, incorrect number of arguments, etc.) in a given execute string will cause the DDE server to ignore the command and proceed to the next square-bracketed command ([...]) in the same execute string. An unknown command (for example, misspelling ``Open'') will abort execution of the rest of the execute string.
Semantic errors (files not found, malformed DVI files, missing fonts, etc.) will cause the previewer to display message boxes, as if the commands were given on the program item command line, but this will not affect the status value returned to the client. TRUETEX does not support any protocol for returning result information to the DDE client application, other than success (bAppReturnCode = 0) or failure (bAppReturnCode = 0). ``Success'' merely indicates that the command passed syntactical tests; it does not indicate any semantic success such as a file being successfully opened or printed.
The Options Expert DDE Server preference item controls whether TRUETEX previewer responds to DDE commands. Disabling the service prevents the previewer from responding, which may be useful in debugging unexpected behaviors.
A DDE client will also receive no response if the TRUETEX previewer is not running. That is, the client or the user, when expecting previewer DDE service, must ensure that the previewer has already been launched, either from the Windows Program Manager or from an application (perhaps the client application itself) via a WinExec() call. Unlike the more advanced OLE servers, the Windows system has no registry of DDE servers to launch when a client requests a given DDE topic.
Various permutations of the Windows version versus the WIN16 or WIN32 executable versions of the program affect whether DDE execute strings work. In general, DDE will certainly work when the TRUETEX DDE server and the host system both use the same API word-length (WIN16 versus WIN32). That is, DVIGDI32.EXE DDE service always responds on Windows 95 or Windows NT, without regard to whether the DDE client is WIN16 or WIN32; likewise DVIGDI16.EXE DDE service always responds on Windows 3.1. The exceptions are in the following cases: DVIGDI32.EXE on Windows 3.1 does not respond to any DDE clients, WIN16 or WIN32; and DVIGDI16.EXE on Windows 95 does not respond to WIN32 DDE clients, although it does respond to WIN16 DDE clients.
The following table lists all the possible permutations:
| Will | Host | DDE Client | TRUETEX |
| Respond | System | WIN16/WIN32 | DDE Server |
| Yes | Windows 3.1 | WIN16 | DVIGDI16.EXE |
| No | Windows 3.1 + Win32s | WIN16 | DVIGDI32.EXE |
| Yes | Windows 3.1 + Win32s | WIN32 | DVIGDI16.EXE |
| No | Windows 3.1 + Win32s | WIN32 | DVIGDI32.EXE |
| Yes | Windows 95 | WIN16 | DVIGDI16.EXE |
| Yes | " | WIN16 | DVIGDI32.EXE |
| No | " | WIN32 | DVIGDI16.EXE |
| Yes | " | WIN32 | DVIGDI32.EXE |
| Yes | Windows NT | WIN16 | DVIGDI16.EXE |
| Yes | " | WIN16 | DVIGDI32.EXE |
| Yes | " | WIN32 | DVIGDI16.EXE |
| Yes | " | WIN32 | DVIGDI32.EXE |
Adding DDE client features to your C application requires a small amount of new code: a few extra lines in your message-handling switch, and some short functions. TRUETEX uses ``raw DDE'' and your DDE client will be most economical in doing likewise, rather than using the Windows DDEML (DDE Management Library DLL) or the ``standard DDE'' library found on the Microsoft Develeper Network. Raw DDE is appropriate, since DDE execute strings do not involve hot links, Clipboard data passing, or other advanced DDE features.
The paper titled, ``Raw DDE'' on the Microsoft Developer Network is an excellent reference on this programming subject. The sample application ``DDEPOP1'' in Petzold's book Programming Windows 3.1 gives a complete example of programming a DDE client. Note that this sample, however, does not provide for the WIN32 API.
Below are code excerpts from ddetst.c, a DDE client test application which compiles with Visual C++ (both WIN16 or WIN32 APIs, via a small amount of conditional compilation). This source code is available on DDETST.ZIP on the TRUETEX Setup disks (you must manually install this), or from our Web page (http://www.truetex.com). The excerpts below give only the code peculiar to raw DDE and omit the ``boilerplate'' Windows application code.
...
#include <dde.h>
...
HWND hServerWnd; /* DDE server window */
...
/* We maintain a state variable to track the progress of a DDE execute */
/* string conversation from initiation, to execution, to termination. */
#define IDLE 1 /* Idle, awaiting user input */
#define INITIATING 2 /* Sent initiate, awaiting server ACK */
#define EXECUTING 3 /* Sent execute, awaiting server ACK */
#define TERMINATING 4 /* Got server's exec ACK, terminating */
int ConversationState = IDLE;
case WM_DDE_ACK:
/* DDE server response. The ACK for both the */
/* initiate and the execute arrive here, so we */
/* must take care to discriminate between them */
/* by examining the transaction state. */
/* The first ACK we might get is the server's */
/* response to our initiation. */
if (ConversationState==INITIATING) {
ConversationState = EXECUTING;
hServerWnd = (HWND) wParam;
DoDDE(
"[Open(\\\\kcc\\\\chk\\\\4192.dvi)]"
"[Open(\\\\kcc\\\\chk\\\\4196.dvi)]"
"[Open(\\\\kcc\\\\chk\\\\4197.dvi)]"
"[Open(\\\\kcc\\\\chk\\\\4198.dvi)]"
);
ConversationState = TERMINATING;
TermDDE();
ConversationState = IDLE;
}
/* Otherwise we have the ACK for the execute; */
else if (ConversationState==EXECUTING) {
/* Here we could examine the return status */
}
/* This case is an error of synchronization */
else {
}
break;
void
IniDDE(void) {
/* Initialize conversation with DDE server */
ATOM app, topic;
app = GlobalAddAtom("TrueTeX");
topic = GlobalAddAtom("View");
SendMessage(HWND_BROADCAST,WM_DDE_INITIATE,(WPARAM)hMainWnd,
MAKELPARAM(app,topic));
if (app) GlobalDeleteAtom(app);
if (topic) GlobalDeleteAtom(topic);
}
BOOL
DoDDE(char *cmds) {
/* Send DDE commands to DDE server. Return whether apparently */
/* successful. */
HGLOBAL hCmds;
char FAR *p;
if (hServerWnd==NULL) {
MessageBox(hMainWnd,"Cannot connect to DDE server!",Title,MB_OK);
return(FALSE);
}
hCmds = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,strlen(cmds)+1);
if (hCmds==NULL) {
MessageBox(hMainWnd,"No memory for DDE!",Title,MB_OK);
return(FALSE);
}
p = GlobalLock(hCmds);
if (p==NULL) {
GlobalFree(hCmds);
MessageBox(hMainWnd,"No memory for DDE!",Title,MB_OK);
return(FALSE);
}
lstrcpy(p,cmds);
GlobalUnlock(hCmds); p = NULL;
if (!PostMessage(hServerWnd,WM_DDE_EXECUTE,(WPARAM)hMainWnd,
#if _WIN16
MAKELPARAM(0,hCmds)
#elif _WIN32
(LPARAM)hCmds
#endif
)) {
GlobalFree(hCmds);
MessageBox(hMainWnd,"Cannot connect to DDE server!",Title,MB_OK);
}
return(TRUE);
}
void
TermDDE(void) {
/* Terminate conversation with DDE server */
if (hServerWnd==NULL) return;
PostMessage(hServerWnd,WM_DDE_TERMINATE,(WPARAM)hMainWnd,0L);
hServerWnd = NULL;
}
| NEXT | HEAD |