package com.sun.jna.platform.win32;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
import com.sun.jna.platform.win32.Ddeml.CONVINFO;
import com.sun.jna.platform.win32.Ddeml.HCONV;
import com.sun.jna.platform.win32.Ddeml.HDDEDATA;
import com.sun.jna.platform.win32.Ddeml.HSZ;
import com.sun.jna.platform.win32.DdemlUtil.DdeAdapter;
import com.sun.jna.platform.win32.DdemlUtil.IDdeConnection;
import com.sun.jna.platform.win32.DdemlUtil.StandaloneDdeClient;
import java.io.Closeable;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.hamcrest.core.Is.is;
import org.junit.Assert;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import org.junit.BeforeClass;
import org.junit.Test;
import com.sun.jna.platform.win32.DdemlUtil.AdvstartHandler;
import com.sun.jna.platform.win32.DdemlUtil.ConnectHandler;
import com.sun.jna.platform.win32.DdemlUtil.AdvreqHandler;
import com.sun.jna.platform.win32.DdemlUtil.RequestHandler;
import com.sun.jna.platform.win32.DdemlUtil.WildconnectHandler;
import com.sun.jna.platform.win32.DdemlUtil.AdvdataHandler;
import com.sun.jna.platform.win32.DdemlUtil.ConnectConfirmHandler;
import com.sun.jna.platform.win32.DdemlUtil.DisconnectHandler;
import com.sun.jna.platform.win32.DdemlUtil.RegisterHandler;
import com.sun.jna.platform.win32.DdemlUtil.XactCompleteHandler;
import com.sun.jna.platform.win32.DdemlUtil.ExecuteHandler;
import com.sun.jna.platform.win32.DdemlUtil.PokeHandler;
public class DdemlUtilTest {
@BeforeClass
public static void init() {
Logger rootLogger = Logger.getLogger("");
rootLogger.getHandlers()[0].setLevel(Level.ALL);
Logger.getLogger(DdeAdapter.class.getName()).setLevel(Level.FINE);
}
@Test
public void testNameService() throws InterruptedException {
final String serviceName = "TestService";
final CountDownLatch latch = new CountDownLatch(1);
StandaloneDdeClient client = null;
StandaloneDdeClient server = null;
try {
client = new StandaloneDdeClient() {
private final RegisterHandler registerHandler = new RegisterHandler() {
public void onRegister(int transactionType, HSZ baseServiceName, HSZ instanceSpecificServiceName) {
if (serviceName.equals(queryString(baseServiceName))) {
latch.countDown();
}
}
};
{
registerRegisterHandler(registerHandler);
this.initialize(Ddeml.APPCMD_CLIENTONLY);
}
};
server = new StandaloneDdeClient() {
{
this.initialize(Ddeml.APPCMD_FILTERINITS
| Ddeml.CBF_SKIP_ALLNOTIFICATIONS
| Ddeml.CBF_FAIL_ALLSVRXACTIONS);
}
};
server.nameService(serviceName, Ddeml.DNS_REGISTER);
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
} finally {
closeQuietly(server);
closeQuietly(client);
}
}
@Test
public void testConnectDisconnect() throws InterruptedException {
final String serviceName = "TestService";
final String topicName = "TestTopic";
final CountDownLatch connectLatch = new CountDownLatch(1);
final CountDownLatch disconnectLatch = new CountDownLatch(1);
StandaloneDdeClient client = null;
StandaloneDdeClient server = null;
try {
client = new StandaloneDdeClient() {
{
this.initialize(Ddeml.APPCMD_CLIENTONLY
| Ddeml.CBF_SKIP_REGISTRATIONS
| Ddeml.CBF_SKIP_UNREGISTRATIONS);
}
};
server = new StandaloneDdeClient() {
private final ConnectHandler connectHandler = new ConnectHandler() {
public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) {
return topicName.equals(queryString(topic));
}
};
private final ConnectConfirmHandler connectConfirmHandler = new ConnectConfirmHandler() {
public void onConnectConfirm(int transactionType, HCONV hconv, HSZ topic, HSZ service, boolean sameInstance) {
if (topicName.equals(queryString(topic))) {
connectLatch.countDown();
}
}
};
private final DisconnectHandler disconnectHandler = new DisconnectHandler() {
public void onDisconnect(int transactionType, HCONV hconv, boolean sameInstance) {
disconnectLatch.countDown();
}
};
{
registerConnectHandler(connectHandler);
registerConnectConfirmHandler(connectConfirmHandler);
registerDisconnectHandler(disconnectHandler);
this.initialize(Ddeml.APPCMD_FILTERINITS
| Ddeml.CBF_SKIP_REGISTRATIONS
| Ddeml.CBF_SKIP_UNREGISTRATIONS
);
}
};
server.nameService(serviceName, Ddeml.DNS_REGISTER);
IDdeConnection connection = client.connect(serviceName, topicName, null);
assertTrue("Failed to connect", connectLatch.await(5, TimeUnit.SECONDS));
connection.close();
assertTrue("Failed to disconnect", disconnectLatch.await(5, TimeUnit.SECONDS));
} finally {
closeQuietly(client);
closeQuietly(server);
}
}
@Test
public void testConnectListDisconnectListQueryNextServer() throws InterruptedException {
final String serviceName = "TestService";
final String topicName = "TestTopic";
final CountDownLatch connectLatch1 = new CountDownLatch(1);
final CountDownLatch disconnectLatch1 = new CountDownLatch(1);
final CountDownLatch connectLatch2 = new CountDownLatch(1);
final CountDownLatch disconnectLatch2 = new CountDownLatch(1);
StandaloneDdeClient client = null;
StandaloneDdeClient server1 = null;
StandaloneDdeClient server2 = null;
try {
client = new StandaloneDdeClient() {
{
this.initialize(Ddeml.APPCMD_CLIENTONLY
| Ddeml.CBF_SKIP_REGISTRATIONS
| Ddeml.CBF_SKIP_UNREGISTRATIONS);
}
};
class Server extends StandaloneDdeClient {
private final CountDownLatch connectLatch;
private final CountDownLatch disconnectLatch;
private final ConnectHandler connectHandler = new ConnectHandler() {
public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) {
return topicName.equals(queryString(topic));
}
};
private final ConnectConfirmHandler connectConfirmHandler = new ConnectConfirmHandler() {
public void onConnectConfirm(int transactionType, Ddeml.HCONV hconv, HSZ topic, HSZ service, boolean sameInstance) {
if (topicName.equals(queryString(topic))) {
connectLatch.countDown();
}
}
};
private final DisconnectHandler disconnectHandler = new DisconnectHandler() {
public void onDisconnect(int transactionType, HCONV hconv, boolean sameInstance) {
disconnectLatch.countDown();
}
};
private final WildconnectHandler wildconnectHandler = new WildconnectHandler() {
public List<Ddeml.HSZPAIR> onWildconnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) {
return Collections.singletonList(new Ddeml.HSZPAIR(service, topic));
}
};
public Server(CountDownLatch connectLatch, CountDownLatch disconnectLatch) {
registerConnectHandler(connectHandler);
registerConnectConfirmHandler(connectConfirmHandler);
registerDisconnectHandler(disconnectHandler);
registerWildconnectHandler(wildconnectHandler);
this.initialize(Ddeml.APPCMD_FILTERINITS
| Ddeml.CBF_SKIP_REGISTRATIONS
| Ddeml.CBF_SKIP_UNREGISTRATIONS
);
this.connectLatch = connectLatch;
this.disconnectLatch = disconnectLatch;
}
};
server1 = new Server(connectLatch1, disconnectLatch1);
server2 = new Server(connectLatch2, disconnectLatch2);
server1.nameService(serviceName, Ddeml.DNS_REGISTER);
server2.nameService(serviceName, Ddeml.DNS_REGISTER);
DdemlUtil.IDdeConnectionList connectionList = client.connectList(serviceName, topicName, null, null);
IDdeConnection con1 = connectionList.queryNextServer(null);
assertNotNull(con1);
IDdeConnection con2 = connectionList.queryNextServer(con1);
assertNotNull(con2);
IDdeConnection con3 = connectionList.queryNextServer(con2);
assertNull(con3);
connectionList.close();
assertTrue(connectLatch1.await(5, TimeUnit.SECONDS));
assertTrue(connectLatch2.await(5, TimeUnit.SECONDS));
assertTrue(disconnectLatch1.await(5, TimeUnit.SECONDS));
assertTrue(disconnectLatch2.await(5, TimeUnit.SECONDS));
} finally {
closeQuietly(client);
closeQuietly(server1);
closeQuietly(server2);
}
}
@Test
public void testExecute() throws InterruptedException {
final String serviceName = "TestService";
final String topicName = "TestTopic";
final String testExecute = "Execute�������";
final CountDownLatch executeReceived = new CountDownLatch(1);
StandaloneDdeClient client = null;
StandaloneDdeClient server = null;
try {
client = new StandaloneDdeClient() {
{
this.initialize(Ddeml.APPCMD_CLIENTONLY
| Ddeml.CBF_SKIP_REGISTRATIONS
| Ddeml.CBF_SKIP_UNREGISTRATIONS);
}
};
server = new StandaloneDdeClient() {
private final ConnectHandler connectHandler = new ConnectHandler() {
public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) {
return topicName.equals(queryString(topic));
}
};
private final ExecuteHandler executeHandler = new ExecuteHandler() {
public int onExecute(int transactionType, HCONV hconv, HSZ topic, Ddeml.HDDEDATA commandStringData) {
Pointer[] pointer = new Pointer[] { accessData(commandStringData, null) };
try {
String commandString = pointer[0].getWideString(0);
if(testExecute.equals(commandString) && queryString(topic).equals(topicName)) {
executeReceived.countDown();
return Ddeml.DDE_FACK;
}
} finally {
synchronized(pointer) {
unaccessData(commandStringData);
}
}
return Ddeml.DDE_FNOTPROCESSED;
}
};
{
registerConnectHandler(connectHandler);
registerExecuteHandler(executeHandler);
this.initialize(Ddeml.APPCMD_FILTERINITS
| Ddeml.CBF_SKIP_ALLNOTIFICATIONS
);
}
};
server.nameService(serviceName, Ddeml.DNS_REGISTER);
IDdeConnection con = client.connect(serviceName, topicName, null);
con.execute(testExecute, 5 * 1000, null, null);
assertTrue(executeReceived.await(5, TimeUnit.SECONDS));
} finally {
closeQuietly(client);
closeQuietly(server);
}
}
@Test
public void testPoke() throws InterruptedException {
final String serviceName = "TestService";
final String topicName = "TestTopic";
final String itemName = "TestItem";
final String testValue = "Execute�������";
final CountDownLatch pokeReceived = new CountDownLatch(1);
StandaloneDdeClient client = null;
StandaloneDdeClient server = null;
try {
client = new StandaloneDdeClient() {
{
this.initialize(Ddeml.APPCMD_CLIENTONLY
| Ddeml.CBF_SKIP_REGISTRATIONS
| Ddeml.CBF_SKIP_UNREGISTRATIONS);
}
};
server = new StandaloneDdeClient() {
private final ConnectHandler connectHandler = new ConnectHandler() {
public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) {
return topicName.equals(queryString(topic));
}
};
private final PokeHandler pokeHandler = new PokeHandler() {
@Override
public int onPoke(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item, Ddeml.HDDEDATA hdata) {
Pointer[] pointer = new Pointer[]{accessData(hdata, null)};
try {
String commandString = pointer[0].getWideString(0);
if (testValue.equals(commandString) && queryString(topic).equals(topicName) && queryString(item).equals(itemName)) {
pokeReceived.countDown();
return Ddeml.DDE_FACK;
}
} finally {
synchronized (pointer) {
}
}
return Ddeml.DDE_FNOTPROCESSED;
}
};
{
registerConnectHandler(connectHandler);
registerPokeHandler(pokeHandler);
this.initialize(Ddeml.APPCMD_FILTERINITS
| Ddeml.CBF_SKIP_ALLNOTIFICATIONS
);
}
};
server.nameService(serviceName, Ddeml.DNS_REGISTER);
IDdeConnection con = client.connect(serviceName, topicName, null);
Memory mem = new Memory( (testValue.length() + 1 ) * 2);
mem.setWideString(0, testValue);
con.poke(mem, (int) mem.size(), itemName, WinUser.CF_UNICODETEXT, 5 * 1000, null, null);
assertTrue(pokeReceived.await(5, TimeUnit.SECONDS));
} finally {
closeQuietly(client);
closeQuietly(server);
}
}
@Test
public void testRequest() throws InterruptedException {
final String serviceName = "TestService";
final String topicName = "TestTopic";
final String itemName = "TestItem";
final String testValue = "Execute�������";
final CountDownLatch pokeReceived = new CountDownLatch(1);
StandaloneDdeClient client = null;
StandaloneDdeClient server = null;
try {
client = new StandaloneDdeClient() {
{
this.initialize(Ddeml.APPCMD_CLIENTONLY
| Ddeml.CBF_SKIP_REGISTRATIONS
| Ddeml.CBF_SKIP_UNREGISTRATIONS);
}
};
server = new StandaloneDdeClient() {
private final ConnectHandler connectHandler = new ConnectHandler() {
public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) {
return topicName.equals(queryString(topic));
}
};
private final RequestHandler requestHandler = new RequestHandler() {
public HDDEDATA onRequest(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item) {
if (dataFormat == WinUser.CF_UNICODETEXT && queryString(topic).equals(topicName) && queryString(item).equals(itemName)) {
Memory mem = new Memory((testValue.length() + 1) * 2);
mem.setWideString(0, testValue);
HDDEDATA result = createDataHandle(mem, (int) mem.size(), 0, item, dataFormat, 0);
pokeReceived.countDown();
return result;
} else {
return null;
}
}
};
{
registerConnectHandler(connectHandler);
registerRequestHandler(requestHandler);
this.initialize(Ddeml.APPCMD_FILTERINITS
| Ddeml.CBF_SKIP_ALLNOTIFICATIONS
);
}
};
server.nameService(serviceName, Ddeml.DNS_REGISTER);
IDdeConnection con = client.connect(serviceName, topicName, null);
HDDEDATA data = con.request(itemName, WinUser.CF_UNICODETEXT, 5 * 1000, null, null);
try {
try {
Pointer pointer = server.accessData(data, null);
assertThat(pointer.getWideString(0), is(testValue));
} finally {
server.unaccessData(data);
}
} finally {
server.freeDataHandle(data);
}
assertTrue(pokeReceived.await(5, TimeUnit.SECONDS));
} finally {
closeQuietly(client);
closeQuietly(server);
}
}
@Test
public void testAbandonTransaction() throws InterruptedException {
final String serviceName = "TestService";
final String topicName = "TestTopic";
final String testExecute = "Execute�������";
final CountDownLatch allTransactionsInvoked = new CountDownLatch(1);
final CountDownLatch executesProcessed = new CountDownLatch(3);
StandaloneDdeClient client = null;
StandaloneDdeClient server = null;
try {
client = new StandaloneDdeClient() {
private final XactCompleteHandler xactCompleteHandler = new XactCompleteHandler() {
public void onXactComplete(int transactionType, int dataFormat, HCONV hConv, HSZ topic, HSZ item, HDDEDATA hdata, ULONG_PTR transactionIdentifier, ULONG_PTR statusFlag) {
executesProcessed.countDown();
}
};
{
registerXactCompleteHandler(xactCompleteHandler);
this.initialize(Ddeml.APPCMD_CLIENTONLY
| Ddeml.CBF_SKIP_REGISTRATIONS
| Ddeml.CBF_SKIP_UNREGISTRATIONS);
}
};
server = new StandaloneDdeClient() {
private final ConnectHandler connectHandler = new ConnectHandler() {
public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) {
return topicName.equals(queryString(topic));
}
};
private final ExecuteHandler executeHandler = new ExecuteHandler() {
public int onExecute(int transactionType, HCONV hconv, HSZ topic, Ddeml.HDDEDATA commandStringData) {
try {
if(! allTransactionsInvoked.await(5, TimeUnit.SECONDS)) {
return Ddeml.DDE_FNOTPROCESSED;
}
Pointer[] pointer = new Pointer[] { accessData(commandStringData, null) };
try {
String commandString = pointer[0].getWideString(0);
if(testExecute.equals(commandString) && queryString(topic).equals(topicName)) {
return Ddeml.DDE_FACK;
}
} finally {
synchronized(pointer) {
unaccessData(commandStringData);
}
}
return Ddeml.DDE_FNOTPROCESSED;
} catch (InterruptedException ex) {
Logger.getLogger(DdemlUtilTest.class.getName()).log(Level.SEVERE, null, ex);
return Ddeml.DDE_FNOTPROCESSED;
}
}
};
{
registerConnectHandler(connectHandler);
registerExecuteHandler(executeHandler);
this.initialize(Ddeml.APPCMD_FILTERINITS
| Ddeml.CBF_SKIP_ALLNOTIFICATIONS
);
}
};
server.nameService(serviceName, Ddeml.DNS_REGISTER);
IDdeConnection con = client.connect(serviceName, topicName, null);
WinDef.DWORDByReference result = new WinDef.DWORDByReference();
con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, result, null);
con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, result, null);
int transactionId2 = result.getValue().intValue();
con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, result, null);
con.abandonTransaction(transactionId2);
allTransactionsInvoked.countDown();
assertFalse(executesProcessed.await(2, TimeUnit.SECONDS));
assertThat(executesProcessed.getCount(), is(1L));
} finally {
closeQuietly(client);
closeQuietly(server);
}
}
@Test
public void testEnableCallback() throws InterruptedException {
final String serviceName = "TestService";
final String topicName = "TestTopic";
final String testExecute = "Execute�������";
final CountDownLatch executesProcessed = new CountDownLatch(3);
StandaloneDdeClient client = null;
StandaloneDdeClient server = null;
try {
client = new StandaloneDdeClient() {
private final XactCompleteHandler xactCompleteHandler = new XactCompleteHandler() {
public void onXactComplete(int transactionType, int dataFormat, HCONV hConv, HSZ topic, HSZ item, HDDEDATA hdata, ULONG_PTR transactionIdentifier, ULONG_PTR statusFlag) {
executesProcessed.countDown();
}
};
{
registerXactCompleteHandler(xactCompleteHandler);
this.initialize(Ddeml.APPCMD_CLIENTONLY
| Ddeml.CBF_SKIP_REGISTRATIONS
| Ddeml.CBF_SKIP_UNREGISTRATIONS);
}
};
server = new StandaloneDdeClient() {
private final ConnectHandler connectHandler = new ConnectHandler() {
public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) {
return topicName.equals(queryString(topic));
}
};
private final ExecuteHandler executeHandler = new ExecuteHandler() {
public int onExecute(int transactionType, HCONV hconv, HSZ topic, Ddeml.HDDEDATA commandStringData) {
Pointer[] pointer = new Pointer[] { accessData(commandStringData, null) };
try {
String commandString = pointer[0].getWideString(0);
if(testExecute.equals(commandString) && queryString(topic).equals(topicName)) {
return Ddeml.DDE_FACK;
}
} finally {
synchronized(pointer) {
unaccessData(commandStringData);
}
}
return Ddeml.DDE_FNOTPROCESSED;
}
};
{
registerConnectHandler(connectHandler);
registerExecuteHandler(executeHandler);
this.initialize(Ddeml.APPCMD_FILTERINITS
| Ddeml.CBF_SKIP_ALLNOTIFICATIONS
);
}
};
server.nameService(serviceName, Ddeml.DNS_REGISTER);
server.enableCallback(Ddeml.EC_DISABLE);
assertThat(server.enableCallback(Ddeml.EC_QUERYWAITING), is(false));
IDdeConnection con = client.connect(serviceName, topicName, null);
WinDef.DWORDByReference result = new WinDef.DWORDByReference();
con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, result, null);
con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, result, null);
con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, result, null);
assertThat(server.enableCallback(Ddeml.EC_QUERYWAITING), is(true));
server.enableCallback(Ddeml.EC_ENABLEALL);
assertTrue(executesProcessed.await(3, TimeUnit.SECONDS));
} finally {
closeQuietly(client);
closeQuietly(server);
}
}
@Test
public void testQueryConvInfoSetUserHandle() throws InterruptedException {
final String serviceName = "TestService";
final String topicName = "TestTopic";
final String testExecute = "Execute�������";
final CountDownLatch executesProcessed = new CountDownLatch(1);
StandaloneDdeClient client = null;
StandaloneDdeClient server = null;
try {
client = new StandaloneDdeClient() {
private final XactCompleteHandler xactCompleteHandler = new XactCompleteHandler() {
public void onXactComplete(int transactionType, int dataFormat, HCONV hConv, HSZ topic, HSZ item, HDDEDATA hdata, ULONG_PTR transactionIdentifier, ULONG_PTR statusFlag) {
CONVINFO convInfo = wrap(hConv).queryConvInfo(transactionIdentifier.intValue());
if(convInfo.hUser.intValue() == 42) {
executesProcessed.countDown();
}
}
};
{
registerXactCompleteHandler(xactCompleteHandler);
this.initialize(Ddeml.APPCMD_CLIENTONLY
| Ddeml.CBF_SKIP_REGISTRATIONS
| Ddeml.CBF_SKIP_UNREGISTRATIONS);
}
};
server = new StandaloneDdeClient() {
private final ConnectHandler connectHandler = new ConnectHandler() {
public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) {
return topicName.equals(queryString(topic));
}
};
private final ExecuteHandler executeHandler = new ExecuteHandler() {
public int onExecute(int transactionType, HCONV hconv, HSZ topic, Ddeml.HDDEDATA commandStringData) {
Pointer[] pointer = new Pointer[] { accessData(commandStringData, null) };
try {
String commandString = pointer[0].getWideString(0);
if(testExecute.equals(commandString) && queryString(topic).equals(topicName)) {
return Ddeml.DDE_FACK;
}
} finally {
synchronized(pointer) {
unaccessData(commandStringData);
}
}
return Ddeml.DDE_FNOTPROCESSED;
}
};
{
registerConnectHandler(connectHandler);
registerExecuteHandler(executeHandler);
this.initialize(Ddeml.APPCMD_FILTERINITS
| Ddeml.CBF_SKIP_ALLNOTIFICATIONS
);
}
};
server.nameService(serviceName, Ddeml.DNS_REGISTER);
IDdeConnection con = client.connect(serviceName, topicName, null);
con.execute(testExecute, Ddeml.TIMEOUT_ASYNC, null, new BaseTSD.DWORD_PTR(42L));
assertTrue(executesProcessed.await(3, TimeUnit.SECONDS));
} finally {
closeQuietly(client);
closeQuietly(server);
}
}
@Test
public void testAdvise() throws InterruptedException {
final String serviceName = "TestService";
final String topicName = "TestTopic";
final String itemName = "TestItem";
final String testValue = "Execute�������";
final CountDownLatch adviseStartReceived = new CountDownLatch(1);
final CountDownLatch adviseDataRequestReceived = new CountDownLatch(1);
final CountDownLatch adviseDataReceived = new CountDownLatch(1);
StandaloneDdeClient client = null;
StandaloneDdeClient server = null;
try {
client = new StandaloneDdeClient() {
private final AdvdataHandler advdataHandler = new DdemlUtil.AdvdataHandler() {
public int onAdvdata(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item, HDDEDATA hdata) {
if (dataFormat == WinUser.CF_UNICODETEXT
&& topicName.equals(queryString(topic))
&& itemName.equals(queryString(item))) {
Pointer pointer = accessData(hdata, null);
try {
if (testValue.equals(pointer.getWideString(0))) {
adviseDataReceived.countDown();
}
} finally {
unaccessData(hdata);
}
}
return Ddeml.DDE_FACK;
}
};
{
registerAdvdataHandler(advdataHandler);
this.initialize(Ddeml.APPCMD_CLIENTONLY
| Ddeml.CBF_SKIP_REGISTRATIONS
| Ddeml.CBF_SKIP_UNREGISTRATIONS);
}
};
server = new StandaloneDdeClient() {
private final ConnectHandler connectHandler = new ConnectHandler() {
public boolean onConnect(int transactionType, HSZ topic, HSZ service, Ddeml.CONVCONTEXT convcontext, boolean sameInstance) {
return topicName.equals(queryString(topic));
}
};
private final AdvreqHandler advreqHandler = new AdvreqHandler() {
public HDDEDATA onAdvreq(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item, int count) {
adviseDataRequestReceived.countDown();
Memory mem = new Memory( (testValue.length() + 1) * 2);
mem.setWideString(0, testValue);
return createDataHandle(mem, (int) mem.size(), 0, item, dataFormat, 0);
}
};
private final AdvstartHandler advstartHandler = new AdvstartHandler() {
public boolean onAdvstart(int transactionType, int dataFormat, HCONV hconv, HSZ topic, HSZ item) {
adviseStartReceived.countDown();
return dataFormat == WinUser.CF_UNICODETEXT
&& topicName.equals(queryString(topic))
&& itemName.equals(queryString(item));
}
};
{
registerConnectHandler(connectHandler);
registerAdvReqHandler(advreqHandler);
registerAdvstartHandler(advstartHandler);
this.initialize(Ddeml.APPCMD_FILTERINITS
| Ddeml.CBF_SKIP_ALLNOTIFICATIONS
);
}
};
server.nameService(serviceName, Ddeml.DNS_REGISTER);
IDdeConnection con = client.connect(serviceName, topicName, null);
con.advstart(itemName, WinUser.CF_UNICODETEXT, 5 * 1000, null, null);
assertTrue(adviseStartReceived.await(5, TimeUnit.SECONDS));
server.postAdvise(topicName, itemName);
assertTrue(adviseDataRequestReceived.await(5, TimeUnit.SECONDS));
assertTrue(adviseDataReceived.await(5, TimeUnit.SECONDS));
} finally {
closeQuietly(client);
closeQuietly(server);
}
}
private static void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (Exception ex) {
}
}
}
}