1/*
2    Title:      Windows application to send an interrupt to Poly
3    Copyright (c) 2003
4        David C.J. Matthews
5
6    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
20*/
21
22/*
23   This program generates an interrupt Windows Poly/ML program in a similar
24   way to sending a SIGINT (Control-C) interrupt in Unix.
25*/
26
27#include <windows.h>
28#include <ddeml.h>
29
30// DDE Commands.
31#define INTERRUPT_POLY  "[Interrupt]"
32#define TERMINATE_POLY  "[Terminate]"
33
34// Default DDE service name.
35#define POLYMLSERVICE   "PolyML"
36
37
38DWORD dwDDEInstance;
39
40
41// DDE Callback function.
42HDDEDATA CALLBACK DdeCallBack(UINT uType, UINT uFmt, HCONV hconv,
43                              HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
44                              DWORD dwData1, DWORD dwData2)
45{
46    return (HDDEDATA) NULL;
47}
48
49void SendDDEMessage(LPCTSTR lpszMessage)
50{
51    HCONV hcDDEConv;
52    HDDEDATA res;
53    // Send a DDE message to the process.
54    DWORD dwInst = dwDDEInstance;
55    HSZ hszServiceName =
56        DdeCreateStringHandle(dwInst, POLYMLSERVICE, CP_WINANSI);
57
58    hcDDEConv =
59        DdeConnect(dwInst, hszServiceName, hszServiceName, NULL);
60    DdeFreeStringHandle(dwInst, hszServiceName);
61    res =
62        DdeClientTransaction((LPBYTE)lpszMessage, sizeof(INTERRUPT_POLY),
63            hcDDEConv, 0L, 0, XTYP_EXECUTE, TIMEOUT_ASYNC, NULL);
64    if (res) DdeFreeDataHandle(res);
65}
66
67// Interrupt the ML process as though control-C had been pressed.
68void RunInterrupt()
69{
70    SendDDEMessage(INTERRUPT_POLY);
71}
72
73
74int WINAPI WinMain(
75  HINSTANCE hInstance,  // handle to current instance
76  HINSTANCE hPrevInstance,  // handle to previous instance
77  LPSTR lpCmdLine,      // pointer to command line
78  int nCmdShow          // show state of window
79)
80{
81    // Initialise DDE.  We only want to be a client.
82    DdeInitialize(&dwDDEInstance, DdeCallBack,
83        APPCMD_CLIENTONLY | CBF_SKIP_CONNECT_CONFIRMS | CBF_SKIP_DISCONNECTS, 0);
84
85    RunInterrupt();
86
87    DdeNameService(dwDDEInstance, 0L, 0L, DNS_UNREGISTER);
88
89    // Unitialise DDE.
90    DdeUninitialize(dwDDEInstance);
91
92    return 0;
93}
94