Jump to content



Photo

DDEML.au3 - DDE Client + Server


  • Please log in to reply
86 replies to this topic

#41 khimik

khimik

    Seeker

  • Active Members
  • 10 posts

Posted 24 September 2008 - 02:47 PM

I think there is a problem with Unicode implementation in DDEML. The following script uses POKE transaction to put "24" in Excel cell R2C2. Book1.xls should be open in Excel.

#include <DDEML.au3> #include <DDEMLClient.au3> _DdeInitialize("", BitOR($APPCMD_CLIENTONLY, $CBF_SKIP_ALLNOTIFICATIONS)) $hszService = _DdeCreateStringHandle("excel") $hszTopic = _DdeCreateStringHandle("[Book1.xls]Sheet1") $hConvSrv = _DdeConnect($hszService, $hszTopic) $hszItem = _DdeCreateStringHandle("R2C2") $res = _DdeClientTransaction($XTYP_POKE, $hConvSrv, 24, 1000, $hszItem, $CF_TEXT) _DdeFreeStringHandle($hszService) _DdeFreeStringHandle($hszTopic) _DdeDisconnect($hConvSrv) _DdeUninitialize()


However this code will only work if compiled as ANSI. If it is compiled as Unicode, only the first symbol ("2") is sent to the Excel cell (even if $CF_TEXT is replaced with $CF_UNICODETEXT). If "wchar" is replaced with "char" in line 619 of DDEML.au3, everything works fine. The alternative way of doing the POKE transaction which sends a data handle rather than a pointer to user32.dll, does not work. Stateless _DDEMLClient_Poke("excel", "[Book1.xls]Sheet1", "R2C2", "24", $CF_UNICODETEXT) does not work either (also with $CF_TEXT). I think these issues are also connected with the Unicode problems.

Thanks!







#42 Affimunny

Affimunny

    Seeker

  • Active Members
  • 5 posts

Posted 06 October 2008 - 08:31 PM

How i may contact admin this site? I have a question.
iijiivei
http://xxxporntube.iespana.es - Best porn archive on net

#43 doudou

doudou

    reverse engineer, the evil twin of the obverse decomposer

  • Active Members
  • PipPipPipPipPipPip
  • 335 posts

Posted 26 December 2008 - 10:32 AM

Sorry, everyone who was expecting an answer: something is wrong with topic subscription here and I was to busy to check the posts manually.
UDFS:Apps:Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE

#44 doudou

doudou

    reverse engineer, the evil twin of the obverse decomposer

  • Active Members
  • PipPipPipPipPipPip
  • 335 posts

Posted 26 December 2008 - 10:39 AM

@doudou - thank you for this

My pleasure.

I have tried to make a simple Gui (with a label having data from a file) to work as a DDE Server for the Excel (client) - without success.

Is it possible at all? - if yes, i would appreciate some advice.

As long as there are mechanisms in Excel to talk to a DDE server it is surely possible. I didn't investigate Excel DDE capabilities but if You post the code of Your efforts (both sides, client and server), I'd take a look at it and try to help.
UDFS:Apps:Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE

#45 doudou

doudou

    reverse engineer, the evil twin of the obverse decomposer

  • Active Members
  • PipPipPipPipPipPip
  • 335 posts

Posted 26 December 2008 - 10:43 AM

I downloaded au3_ddeml_v1.4.zip and au3_ddeml_samples.zip, But I can't execute the examples within the samples.

Can you give a simple and clear sample code ? Thanks!

In case You still have problems with that can You please state more precisely what You were doing and what the outcome was?
UDFS:Apps:Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE

#46 doudou

doudou

    reverse engineer, the evil twin of the obverse decomposer

  • Active Members
  • PipPipPipPipPipPip
  • 335 posts

Posted 26 December 2008 - 10:55 AM

If I had set a excel's cell which value is "=YES|DQ!'&TWTK1.Price'" , It can update the DDE data souce.

How Can I write the same code by autoit and DDEML ?

Shame on me - absolutely no idea, what You are talking about. How can a cell in Excel update DDE data source? What is after all this DDE data source?

I think it is impossible to help out requests of such chunked format because all the context is missing. Like in:

- Officer, if I go 60 mph can I get ticket for speeding?
- Well, it depends...
UDFS:Apps:Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE

#47 doudou

doudou

    reverse engineer, the evil twin of the obverse decomposer

  • Active Members
  • PipPipPipPipPipPip
  • 335 posts

Posted 26 December 2008 - 11:17 AM

I think there is a problem with Unicode implementation in DDEML. The following script uses POKE transaction to put "24" in Excel cell R2C2. Book1.xls should be open in Excel.

#include <DDEML.au3> #include <DDEMLClient.au3> _DdeInitialize("", BitOR($APPCMD_CLIENTONLY, $CBF_SKIP_ALLNOTIFICATIONS)) $hszService = _DdeCreateStringHandle("excel") $hszTopic = _DdeCreateStringHandle("[Book1.xls]Sheet1") $hConvSrv = _DdeConnect($hszService, $hszTopic) $hszItem = _DdeCreateStringHandle("R2C2") $res = _DdeClientTransaction($XTYP_POKE, $hConvSrv, 24, 1000, $hszItem, $CF_TEXT) _DdeFreeStringHandle($hszService) _DdeFreeStringHandle($hszTopic) _DdeDisconnect($hConvSrv) _DdeUninitialize()

However this code will only work if compiled as ANSI. If it is compiled as Unicode, only the first symbol ("2") is sent to the Excel cell (even if $CF_TEXT is replaced with $CF_UNICODETEXT). If "wchar" is replaced with "char" in line 619 of DDEML.au3, everything works fine. The alternative way of doing the POKE transaction which sends a data handle rather than a pointer to user32.dll, does not work. Stateless _DDEMLClient_Poke("excel", "[Book1.xls]Sheet1", "R2C2", "24", $CF_UNICODETEXT) does not work either (also with $CF_TEXT). I think these issues are also connected with the Unicode problems.

A very similar problem had been handled time ago in another topic DDE Command.
This has to do with DDE implementation generally: if the server talks ANSI only, You HAVE TO compile Your client as ANSI. We could of course break up the UNICODE automatism in the UDF leaving the choice of all arguments to API calls to the programmer but this way one could use Win32 as well directly.

Edited by doudou, 26 December 2008 - 11:58 AM.

UDFS:Apps:Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE

#48 Keymaker

Keymaker

    Seeker

  • Active Members
  • 20 posts

Posted 23 January 2009 - 06:31 PM

Hello,

I am writing a DDE server in AutoIT3 using a slightly modified version of the sample Server program provided by this UDF. I will be communicating with it using a client program written in C# .NET using the NDde.dll class libraries and it's DDE functions.

To request information from the server, I will be using the NDde command: client.Request (string Command, int Timeout) to request data from the AutoIT3 based server. Will this work with the sample server program?

In other words, can anyone give me an example of what I need to add to the (sample)server script to have it return data when it receives a client.Request() command from a client program?

Thanks!
Keymaker

Edited by Keymaker, 24 January 2009 - 05:40 PM.


#49 doudou

doudou

    reverse engineer, the evil twin of the obverse decomposer

  • Active Members
  • PipPipPipPipPipPip
  • 335 posts

Posted 27 January 2009 - 11:58 PM

To request information from the server, I will be using the NDde command: client.Request (string Command, int Timeout) to request data from the AutoIT3 based server. Will this work with the sample server program?

In other words, can anyone give me an example of what I need to add to the (sample)server script to have it return data when it receives a client.Request() command from a client program?

Essentially all You have to do is add a callback to Your server (here addition to SampleDDEServer):

Func OnDDE_Request($szTopic, $szItem, $uFmt, $hConv)     ConsoleWrite("OnDDE_Request(" & $szTopic & ", " & $szItem & ")" & @CRLF)     return _DdeCreateDataHandle("My data") EndFunc


You can pass any data (binaries too) as result handle, You will have to set the last optional parameter $wFmt of _DdeCreateDataHandle appropriately then (s. ClipboardConstants.au3).
UDFS:Apps:Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE

#50 Keymaker

Keymaker

    Seeker

  • Active Members
  • 20 posts

Posted 28 January 2009 - 05:40 AM

Essentially all You have to do is add a callback to Your server (here addition to SampleDDEServer):

Func OnDDE_Request($szTopic, $szItem, $uFmt, $hConv)     ConsoleWrite("OnDDE_Request(" & $szTopic & ", " & $szItem & ")" & @CRLF)     return _DdeCreateDataHandle("My data") EndFunc


You can pass any data (binaries too) as result handle, You will have to set the last optional parameter $wFmt of _DdeCreateDataHandle appropriately then (s. ClipboardConstants.au3).

Thanks i'll try that.

One last question. Why is it when I run Syntax check, I get errors saying: "@Unicode is an undefined macro" ?

Thanks

#51 ptrex

ptrex

    Universalist

  • MVPs
  • 2,399 posts

Posted 01 February 2009 - 02:22 PM

@keymaker

Changed: @Unicode renamed to @AutoItUnicode. @Unicode is an alias for now. It will be removed > 3.2.14.0


regards

ptrex

#52 doudou

doudou

    reverse engineer, the evil twin of the obverse decomposer

  • Active Members
  • PipPipPipPipPipPip
  • 335 posts

Posted 01 February 2009 - 11:28 PM

One last question. Why is it when I run Syntax check, I get errors saying: "@Unicode is an undefined macro" ?


New macro @AutoItUnicode will be integrated in v. 1.5 of DDEML, keep checking this thread.
UDFS:Apps:Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE

#53 doudou

doudou

    reverse engineer, the evil twin of the obverse decomposer

  • Active Members
  • PipPipPipPipPipPip
  • 335 posts

Posted 03 February 2009 - 03:46 AM

One last question. Why is it when I run Syntax check, I get errors saying: "@Unicode is an undefined macro" ?


Fixed: version 1.5 is online - works with AutoIt 3.3 (s. the very top post in this topic).
UDFS:Apps:Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE

#54 Keymaker

Keymaker

    Seeker

  • Active Members
  • 20 posts

Posted 10 February 2009 - 04:38 PM

Essentially all You have to do is add a callback to Your server (here addition to SampleDDEServer):

Func OnDDE_Request($szTopic, $szItem, $uFmt, $hConv)     ConsoleWrite("OnDDE_Request(" & $szTopic & ", " & $szItem & ")" & @CRLF)     return _DdeCreateDataHandle("My data") EndFunc

You can pass any data (binaries too) as result handle, You will have to set the last optional parameter $wFmt of _DdeCreateDataHandle appropriately then (s. ClipboardConstants.au3).

Ok, I still can't get this work with my application. My application requests info from the DDE server using the following .NET code:

Plain Text         
        private void SendInfoRequest_Click(object sender, EventArgs e)         {             string Command = String.Empty;             byte[] data = new byte[1024];             System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();             try             {                using (DdeClient Client = new DdeClient("Player", InfoTopic.Text))                {                     Client.TryConnect(); // Connect to the server.                     if (Client.IsConnected)                         Messages.Text = "Connected successfully!" + "\r\n";                     Command = InfoCommand.Text;                     if (Command != String.Empty)                     {                          Client.TryRequest(Command, 1, 5000, out data);                          Messages.Text = enc.GetString(data);                     }                     else                         Messages.Text = "No command to send. Please enter a valid command.";                 }             }             catch (Exception ex)             {                 Messages.Text = ex.ToString();             }         }

As you can see, the Client.TryRequest() expects data to be returned in a byte array. When I execute this using the OnDDE_Request code provided above I get an error saying the byte array is null. It looks like the OnDDE_Request function returns a handle instead of byte data.

I know my code works because I have tried it on two other DDE server apps and they return data in the correct format (byte data). What changes need to be made to the OnDDE_Request function so that it returns data as a byte array?

Thanks
Keymaker.

Edited by Keymaker, 10 February 2009 - 04:39 PM.


#55 doudou

doudou

    reverse engineer, the evil twin of the obverse decomposer

  • Active Members
  • PipPipPipPipPipPip
  • 335 posts

Posted 12 February 2009 - 01:57 AM

Ok, I still can't get this work with my application. My application requests info from the DDE server using the following .NET code:

Plain Text         
        private void SendInfoRequest_Click(object sender, EventArgs e)         {             string Command = String.Empty;             byte[] data = new byte[1024];             System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();             try             {                using (DdeClient Client = new DdeClient("Player", InfoTopic.Text))                {                     Client.TryConnect(); // Connect to the server.                     if (Client.IsConnected)                         Messages.Text = "Connected successfully!" + "\r\n";                     Command = InfoCommand.Text;                     if (Command != String.Empty)                     {                          Client.TryRequest(Command, 1, 5000, out data);                          Messages.Text = enc.GetString(data);                     }                     else                         Messages.Text = "No command to send. Please enter a valid command.";                 }             }             catch (Exception ex)             {                 Messages.Text = ex.ToString();             }         }

As you can see, the Client.TryRequest() expects data to be returned in a byte array. When I execute this using the OnDDE_Request code provided above I get an error saying the byte array is null. It looks like the OnDDE_Request function returns a handle instead of byte data.

I know my code works because I have tried it on two other DDE server apps and they return data in the correct format (byte data). What changes need to be made to the OnDDE_Request function so that it returns data as a byte array?

Thanks
Keymaker.

Sorry, the last release of DDEML was buggy. I submitted v. 1.5.1 (s. 1st post) along with functioning examples for DDE request (SampleDDEClient, SampleDDEServer).

Working with requests 2 things are absolutely essential:

1. The requested item must be the same one used in server for returned data handle (therefore OnDDE_Request callback receives now hszItem instead of converted string).
2. The requested data format must match returned one (i.e. if request was sent for CF_UNICODETEXT, server should create data handle for CF_UNICODETEXT as well).

Unless both conditions are met Win API would always return DDE_FNOTPROCESSED to the client regardless of what the server actually replied. If You don't know what string formats Your client is set for, You can try both CF_TEXT and CF_UNICODETEXT by manually setting

Global Const $_DDEML_UNICODE = 1

accordingly in Your server code BEFORE including DDEML.au3.

General tip: the best way to find out, what is going wrong during a DDE conversation is running DDE Spy tool from Windows SDK at the same time. Providing the output of the Spy here would help me a lot to help You in case of troubles with DDEML.
UDFS:Apps:Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE

#56 byseob

byseob

    Seeker

  • New Members
  • 2 posts

Posted 22 February 2009 - 09:45 AM

Thank you for good modules!
but, i have one question.
( i'm korean. sorry for my english.. )

How can i use the DDE server's $XTYP_ADVREQ call back fuctions?
any example for DDE server's $XTYP_ADVREQ callback functions?

i want to update the client's input box from server realtime datas.
i called my vars like below.

func SetMyVarsToClient()    _DdePostAdvise( _DdeQueryString($topic) , _DdeQueryString('10') ); EndFunc Func OnDDE_AdvReq($dwData1,$szTopic, $hszItem, $uFmt, $hConv)     Local $szItem = _DdeQueryString($hszItem)     if $szItem='10' then        return _DdeCreateDataHandle( '5678' , 0, $szItem, $uFmt)     endif EndFunc


but, the value (5678) is not retuned to client.

please... any idea?

#57 doudou

doudou

    reverse engineer, the evil twin of the obverse decomposer

  • Active Members
  • PipPipPipPipPipPip
  • 335 posts

Posted 23 February 2009 - 04:49 PM

Thank you for good modules!

My pleasure.

How can i use the DDE server's $XTYP_ADVREQ call back fuctions?
any example for DDE server's $XTYP_ADVREQ callback functions?

i want to update the client's input box from server realtime datas.
i called my vars like below.

func SetMyVarsToClient()    _DdePostAdvise( _DdeQueryString($topic) , _DdeQueryString('10') ); EndFunc Func OnDDE_AdvReq($dwData1,$szTopic, $hszItem, $uFmt, $hConv)     Local $szItem = _DdeQueryString($hszItem)     if $szItem='10' then        return _DdeCreateDataHandle( '5678' , 0, $szItem, $uFmt)     endif EndFunc

but, the value (5678) is not retuned to client.

please... any idea?

As already discussed here using DDE advise loops is most complicated and I would not recommend that. If You must go this way, please refer to the mentioned post and particularly these MSDN articles:

http://msdn.microsoft.com/en-us/library/ms648716(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms648714(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms648717(VS.85).aspx
UDFS:Apps:Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE

#58 byseob

byseob

    Seeker

  • New Members
  • 2 posts

Posted 24 February 2009 - 03:51 PM

Thank you "Dr."doudou :-)

i knew these msdn sites articles already.
however, i can't understand these documents.
so.... i'm sorry but, i need your help. :)

i made the advise loop DDE Client already.
My DDE Client used OnDDE_AdvData( ... ) CallBack Functions.
and this DDE Server (My DDE Client connected.) was not made by AutoIT3.
it's a good job!

But,

now. i need to make DDE Server.
so, i use autoIt3 too.

the DDE Client is same program.
I make DDE Server hard.

but, i can't understand the DDE Server Advise looping mechanism..
because of my ability in English.
i can't find any korean documents about it.. ( MSDN korea, too )

so i need "Advise looping about AutoIT3 DDE Server Example Source.. using DDEML.au3 UDF.

here is my sample test code.
please teach me, or some hints..

Plain Text         
#include <DDEML.au3> #include <DDEMLServer.au3> Opt("OnExitFunc", "CleanExit") $hszSrvService = 0 $topic = ''; $_flag = False; If $DMLERR_NO_ERROR = _DdeInitialize("OnDDE_", $APPCLASS_STANDARD) Then     $hszSrvService = _DdeCreateStringHandle("TESTSERVER")     If Not _DdeNameService($hszSrvService, $DNS_REGISTER) Then MsgBox(0, 'error', "error for init") Else     MsgBox(0, 'error', "error for init 2") EndIf ; main loop While 1         if $_flag = True then         _DdePostAdvise( _DdeCreateStringHandle($topic) , _DdeCreateStringHandle('10')  );           endif     WEnd Func OnDDE_Connect($szTopic, $szService)     $topic = $szTopic;     ConsoleWrite("OnDDE_Connect(" & $szTopic & ", " & $szService & ")" & @CRLF)     $_flag = True;     Return 1 EndFunc Func OnDDE_AdvStart( $hsz1, $hsz2, $uFmt, $hConv)     ConsoleWrite( 'start ' &  $hsz1 & ' / ' &  $hsz2 & @CRLF );     ; return 1 = return True?     return 1; EndFunc Func OnDDE_Disconnect($hConv)     ConsoleWrite("OnDDE_Disconnect()" & @CRLF)     Return 0 EndFunc Func OnDDE_AdvReq($dwData1,$szTopic, $hszItem, $uFmt, $hConv) ; test moving value.     $test_data = Random(1,10);     $item = _DdeQueryString( $hszItem );     ; Event Callback test     ConsoleWrite( 'req ' &  $szTopic & ' / ' &$item & @CRLF );]     Local $hData = _DdeCreateDataHandle($test_data, 0, $hszItem)     If @error Then ConsoleWriteError("data alloc error (0x" & StringFormat("%x", @error) & ")" & @CRLF)     return $hData EndFunc Func OnDDE_Request($szTopic, $hszItem, $uFmt, $hConv) ; request test ; this query is one time only by client call.     Local $hData = _DdeCreateDataHandle('first time request', 0, $hszItem)     If @error Then ConsoleWriteError("data alloc error (0x" & StringFormat("%x", @error) & ")" & @CRLF)     return $hData EndFunc Func CleanExit()     If 0 <> $hszSrvService Then         _DdeNameService($hszSrvService, $DNS_UNREGISTER)         _DdeFreeStringHandle($hszSrvService)     EndIf     _DdeUninitialize() EndFunc

i did change above source code after first posting.. ( some error fixed, sorry. )

thank in advance!

Edited by byseob, 24 February 2009 - 03:58 PM.


#59 doudou

doudou

    reverse engineer, the evil twin of the obverse decomposer

  • Active Members
  • PipPipPipPipPipPip
  • 335 posts

Posted 23 February 2010 - 05:06 PM

Version 1.5.2 includes some updates due to AutoIt changes.
UDFS:Apps:Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE

#60 doudou

doudou

    reverse engineer, the evil twin of the obverse decomposer

  • Active Members
  • PipPipPipPipPipPip
  • 335 posts

Posted 17 April 2010 - 05:06 AM

Some functionality for exchanging raw data was missing. I've added it in 1.5.3 release.
UDFS:Apps:Coder's last words before final release: WE APOLOGIZE FOR INCONVENIENCE




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users