DDEML.au3 - DDE Client + Server

90 posts in this topic

Posted (edited)

It's been frequently asked here, but no complete solution provided. Well, now it's here!

With DDEML UDF one can use an AutoIt script as a DDE client or server.

Version 1.5.4

DDEML: invalid struct declaration in _DdeGetData() fixed

DDEML: presence of callback functions checked more thoroughly

Version 1.5.3

DDEML: missing _DdeGetData() and _DdeGetDataAsStruct() added

DDEML Samples: working XTYP_POKE example added

Version 1.5.2

DDEML: references to @ProcessorArch updated to @OSArch

DDEML Samples: Opt("OnAutoItExit") replaced with OnAutoItExitRegister()

Version 1.5.1

DDEML: _DDEML_CreateDataStruct returning wrong size for UNICODE strings fixed

DDEML: _DdeCallback not passing item handle to server in XTYP_ADVREQ and XTYP_REQUEST fixed

DDEML Samples: working XTYP_REQUEST example added

Version 1.5 (first AutoIt 3.3 compatible release)

DDEML: references to @Unicode/@AutoItUnicode replaced with global $_DDEML_UNICODE

DDEML: ClipboardConstants.au3 dumped in favor of Clipboard.au3 (shipped with AutoIt)

DDEML Samples: obsolete includes replaced

Version 1.4

DDEML: ALL global constants are now in DDEMLConstants.au3, other global declarations are checked allowing usage from within OnAutoItStart()

DDEMLClient: undeclared local struct fixed

Version 1.3

DDEML: Support for built-in DllCallback facilities (AutoIt v 3.2.10) added

DDEML: HANDLE type made configurable (64 bit compatibility)

DDEML: Constants moved to separate include DDEMLConstants.au3

DDEML: _DdeIsInitialized() added

Version 1.2 (AutoIt v 3.1 compatible, disontinued)

DDEML: UNICODE support improved

Version 1.1

DDEML: Wokraround for server not supporting UNICODE applied

DDEML Samples: StatelessDDEGetURL.au3 replaced by StatelessDDEBrowserControl.au3 (2-way communication)

Download current version (1.5.4)

au3_ddeml_v1.2.zip

Edited by doudou
1 person likes this

Share this post


Link to post
Share on other sites



Posted (edited)

NOTE: DDEML ver. 1.2 and older requires DllCallBack

Edited by doudou

Share this post


Link to post
Share on other sites

Posted (edited)

@doudou

Seems powerfull but any script I ran gave a lot of errors.

>"C:\Program Files\AutoIt3\SciTe\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /beta /ErrorStdOut /in "C:\_\Apps\AutoIT3\CallBack\DDE\StatelessDDEURLOpen.au3" /autoit3dir "C:\Program Files\AutoIt3\beta" /UserParams    
+> Starting AutoIt3Wrapper v.1.7.5
>Running AU3Check (1.54.9.0)  params:  from:C:\Program Files\AutoIt3\beta
C:\_\Apps\AutoIT3\CallBack\DDE\DDEML.au3(672,68) : ERROR: syntax error
Func _DdeCreateDataHandle($data, $afCmd = 0, $hszItem = 0, $wFmt = $CF_TEXT
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEML.au3(674,55) : WARNING: $wFmt: possibly used before declaration.
    $cb = _DDEML_CreateDataStruct($data, $pData, $wFmt)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEML.au3(734,61) : ERROR: syntax error
Func _DDEML_CreateDataStruct($data, ByRef $pStruct, $wFmt = $CF_TEXT
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEML.au3(734,70) : ERROR: _DDEML_CreateDataStruct() called by a previous line with 3 arg(s). Min = 0. First previous line calling this Func is 674.
Func _DDEML_CreateDataStruct($data, ByRef $pStruct, $wFmt = $CF_TEXT)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEMLClient.au3(174,64) : ERROR: _DDEML_CreateDataStruct() called with wrong number of args.
            $cb = _DDEML_CreateDataStruct($data, $struct, $wFmt)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEML.au3(734,70) : REF: definition of _DDEML_CreateDataStruct().
Func _DDEML_CreateDataStruct($data, ByRef $pStruct, $wFmt = $CF_TEXT)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEMLClient.au3(260,55) : ERROR: _DDEML_CreateDataStruct() called with wrong number of args.
        If _DDEML_CreateDataStruct($szCommand, $stData)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEML.au3(734,70) : REF: definition of _DDEML_CreateDataStruct().
Func _DDEML_CreateDataStruct($data, ByRef $pStruct, $wFmt = $CF_TEXT)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEMLClient.au3(261,56) : ERROR: _DdeCreateDataHandle() called with wrong number of args.
            Local $hData = _DdeCreateDataHandle($stData)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEML.au3(672,77) : REF: definition of _DdeCreateDataHandle().
Func _DdeCreateDataHandle($data, $afCmd = 0, $hszItem = 0, $wFmt = $CF_TEXT)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEMLClient.au3(274,70) : ERROR: syntax error
Func _DDEMLClient_Poke($szService, $szTopic, $szItem, $data, $wFmt = $CF_TEXT
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEMLClient.au3(290,50) : WARNING: $stData: possibly used before declaration.
        If _DDEML_CreateDataStruct($data, $stData)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEMLClient.au3(290,50) : ERROR: _DDEML_CreateDataStruct() called with wrong number of args.
        If _DDEML_CreateDataStruct($data, $stData)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEML.au3(734,70) : REF: definition of _DDEML_CreateDataStruct().
Func _DDEML_CreateDataStruct($data, ByRef $pStruct, $wFmt = $CF_TEXT)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEMLClient.au3(291,56) : ERROR: _DdeCreateDataHandle() called with wrong number of args.
            Local $hData = _DdeCreateDataHandle($stData)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\DDEML.au3(672,77) : REF: definition of _DdeCreateDataHandle().
Func _DdeCreateDataHandle($data, $afCmd = 0, $hszItem = 0, $wFmt = $CF_TEXT)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\_\Apps\AutoIT3\CallBack\DDE\StatelessDDEURLOpen.au3 - 9 error(s), 2 warning(s)
!>AU3Check ended.rc:2
>Exit code: 0   Time: 2.288

So I can't judge it yet.

regards

ptrex

Edited by ptrex

Share this post


Link to post
Share on other sites

Posted

ditto what pretex said.

imho, i'd prefer example scripts were written:

#include "DDEML.au3"

#include "DDEMLServer.au3"

rather than:

#include <DDEML.au3>

#include <DDEMLServer.au3>

bit early yet to be dumping untested files into the includes directory.

Share this post


Link to post
Share on other sites

Posted

Thanks for feedback, folks.

Au3Check seems to have problems with named constants as values for optional parameters in functions while AutoIt interpreter does not. Teach me right if I err: if you insert some console out at the lines Au3Check complains about you'd see that $wFmt and other variables always contain the right default values.

Does any of the samples fail running (no syntax check)?

As for #include <>: you are free to put the includes wherever you wish, those <> make no difference as long AutoIt finds the scripts (s. online help).

Share this post


Link to post
Share on other sites

Posted

I double checked those 'error reports' and it's quite sure a bug of Au3Check.

See this example

Share this post


Link to post
Share on other sites

Posted

Nice!

How can i use this to get info from browsers? (from IE as example)

Share this post


Link to post
Share on other sites

Posted

Nice!

Thanks. <_<

How can i use this to get info from browsers? (from IE as example)

Well, generally you can get (string) data from a DDE server by calling _DDEMLClient_RequestString() (DDEMLClient.au3). You will need proper 'Service', 'Topic' and 'Item' though, so I would refer you to IE documentation (as far as MS gives one out).

For other data type (binaries) there's some more work to do as _DDEMLClient_Request() is planned for the next release of DDEML.au3.

Share this post


Link to post
Share on other sites

Posted

You will need proper 'Service', 'Topic' and 'Item' though, so I would refer you to IE documentation

I need to get Url from different browsers, for now i need at least from firefox, where you seguest to read about it? or you not familiar with the firefox?

Thanks.

Share this post


Link to post
Share on other sites

Posted

I need to get Url from different browsers, for now i need at least from firefox, where you seguest to read about it? or you not familiar with the firefox?

What I did is google "dde firefox".

And I found:

Service: "firefox"

Topic: "WWW_GetWindowInfo"

Item: "0xFFFFFFFF"

But I didn't test it yet, so if you would share your expirience afer you've tried?

Share this post


Link to post
Share on other sites

Posted

I need to get Url from different browsers, for now i need at least from firefox, where you seguest to read about it? or you not familiar with the firefox?

I found out how to make it work with all browsers!

However some changes had to be done on DDEML.au3 - new release is shipping tonight.

Share this post


Link to post
Share on other sites

Posted

Version 1.1 released (s. 1st post)

Share this post


Link to post
Share on other sites

Posted

I found out how to make it work with all browsers!

Excelent!

Version 1.1 released

Thanks!

Share this post


Link to post
Share on other sites

Posted

Can this be used across the network, or are you limited to use on the same machine?

Example: Client running on Workstation1, and Server running on Workstation2?

Share this post


Link to post
Share on other sites

Posted

Can this be used across the network, or are you limited to use on the same machine?

Since we use standard DDE it should be as well usable across network. The keyword here is NetDDE - if it is properly configured there's no difference to local connections from client's or server's point of view.

Share this post


Link to post
Share on other sites

Posted

How difficult would it be to update this to use the built-in callback functions?

Share this post


Link to post
Share on other sites

Posted

How difficult would it be to update this to use the built-in callback functions?

Done already. See version 1.3.

Share this post


Link to post
Share on other sites

Posted

Done already. See version 1.3.

Excellent!

Share this post


Link to post
Share on other sites

Posted

Done already. See version 1.3.

Today I rewrote an application using these routines. I replaced the prior EXE (written using Clarion) with the compiled script, and everything is working with one exception:

Windows launches the application upon the initial DDE request to the server. However, the DDE request isn't being performed. Subsequent DDE requests are properly executed. I've tried adjusting the registry settings and adding an IfExec subkey to no avail.

Any ideas?

Dan

Share this post


Link to post
Share on other sites

Posted

Windows launches the application upon the initial DDE request to the server. However, the DDE request isn't being performed. Subsequent DDE requests are properly executed. I've tried adjusting the registry settings and adding an IfExec subkey to no avail.

Any ideas?

Yep. I encountered this problem with my AutoIt-App too when it is supposed to be started by Windows shell. The catch is: ShellExecute doesn't wait for the application's message loop to run but tries to connect to DDE server as soon as the PID of the app becomes valid.

The only way I was able to work around this in AutoIt is via a proxy-EXE which could look like:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_OutFile=URLOpen.exe
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#NoTrayIcon
Opt("TrayIconHide", 1)
Opt("TrayMenuMode", 1)
Opt("RunErrorsFatal", 0)

Func OnAutoItStart()
    If ProcessExists("URLHandler.exe") Then Exit
    Local $s = ""
    For $i = 1 To $CmdLine[0]
        $s &= ' "' & $CmdLine[$i] & '"'
    Next
    Local $r = RunWait('URLHandler.exe' & $s, @WorkingDir)
    If @error Then $r = RunWait('"' & @ScriptDir & '\URLHandler.exe"' & $s, @ScriptDir)
    Exit $r
EndFunc ;==>OnAutoItStart

Thus my actual DDE server resides in URLHandler.exe but the registry key 'shell\open\command' points to URLOpen.exe. Adminstering some tricks with start-up parameters and window titles/classes it could be even done with a single EXE, I don't think however it is worth the hassle.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.