📜 ⬆️ ⬇️

Perl and GUI. Application Interaction

Sometimes it becomes necessary to exchange data between applications (for example, to execute a command in Internet Explorer, Excel).
The Microsoft Windows platform provides us with several mechanisms, including OLE, COM, and ... DDE.

DDE was introduced in 1987, was later NetDDE network implementation, and is still in use.
Working with DDE is very simple, you do not need to connect additional modules with CPAN, everything is in tkkit.

Consider the example of two applications receiver and sender.
')
image

Description and code under habrakatom.


To work, you must connect the package dde

In tcl, it would look like this:
 package require dde


Before the program starts to exchange information, you must specify the name of "our server".
Let it be “PerlDDE”

The receiver program can reverse two commands:
message - display a message
image

and oops is called when the user closes the client program.
Before us will be such a sad picture:

image

Receiver program code:

 #! / usr / bin / perl
 use strict;
 use feature ': 5.10';
 use Tkx;

 # Connect the module to work with DDE
 Tkx :: package_require ('dde');

 # Install handler
 Tkx :: dde_servername (-handler => \ & dde_handle, 'PerlDDE');

 # Create a window
 my% UI = ();
 my $ mw = Tkx :: widget-> new ('.');

 $ mw-> g_wm_title ('Perl / Tkx DDE');
 $ mw-> g_wm_minsize (qw (300,200));

 my $ label = $ mw-> new_ttk__label (-text => 'Receiver:');
 my $ entry = $ mw-> new_ttk__entry (-textvariable => \ $ UI {entry},
                                 -state => 'readonly');

 Tkx :: grid ($ label, -row => 0, -column => 0, -sticky => 'ew', -padx => 4, -pady => 4);
 Tkx :: grid ($ entry, -row => 1, -column => 0, -sticky => 'ew', -padx => 4, -pady => 4);

 Tkx :: grid (columnconfigure => $ mw, 0, -weight => 1);

 Tkx :: MainLoop ();
 one;

 sub dde_handle {
    
     PROCESS_DDE_ARGS:
     foreach my $ ddeval (@_) {
         next PROCESS_DDE_ARGS if ref ($ ddeval);
        
         $ UI {entry} = $ ddeval;
         my ($ key, $ value) = Tkx :: SplitList ($ ddeval);
        
         given ($ key) {             
             when ('message') {
                 Tkx :: tk ___ messageBox (
                     -title => 'DDE Receiver',
                     -message => "Received message: \ n $ value",
                 ) if length $ value;
             }
            
             when ('oops') {
                 $ UI {entry} = 'Oops, sender was terminated';
             }
            
             # ...
         }
     }
 }


Sender program code:

 #! / usr / bin / perl
 use strict;
 use Tkx;

 Tkx :: package_require ('dde');

 my% UI;
 my $ mw = Tkx :: widget-> new ('.');
 $ mw-> g_wm_title ('Perl / Tkx DDE');
 $ mw-> g_wm_minsize (qw (300,200));

 my $ label = $ mw-> new_ttk__label (-text => 'Sender:');
 my $ copy = $ mw-> new_ttk__label (-text => 'santeri.habrahabr.ru');
 my $ msg_e = $ mw-> new_ttk__entry (-textvariable => \ $ UI {msg});
 my $ msg_b = $ mw-> new_ttk__button (
     -text => 'Message :)',
     -command => sub {
         send_message (message => $ UI {msg});
     },
 );

 Tkx :: bind ($ msg_e => '<Return>', sub {
     $ msg_b-> invoke ();
 });

 # oops, if you closed the program
 $ mw-> g_wm_protocol (WM_DELETE_WINDOW => sub {
     send_message ('oops');
     $ mw-> g_destroy ();
 });

 Tkx :: grid ($ label, -row => 0, -column => 0, -sticky => 'ew', -padx => 4, -pady => 4);
 Tkx :: grid ($ msg_e, -row => 1, -column => 0, -sticky => 'ew', -padx => 4, -pady => 4);
 Tkx :: grid ($ msg_b, -row => 1, -column => 1, -sticky => 'ew', -padx => 4, -pady => 4);
 Tkx :: grid ($ copy, -row => 2, -column => 0, -sticky => 'se', -padx => 4, -pady => 4,
                   -columnspan => 2);

 Tkx :: grid (rowconfigure => $ mw, 2, -weight => 1);
 Tkx :: grid (columnconfigure => $ mw, 0, -weight => 1);

 Tkx :: MainLoop ();
 one;

 # TclEval is the name of the DDE service for Tcl
 sub send_message {
     my ($ key, $ val) = @_;
     return if! defined $ key;
    
     eval {
         my $ value = $ val ||  q {};
         Tkx :: dde_execute (TclEval => 'PerlDDE', "$ key {$ value}");  
     };
 }


References:

http://en.wikipedia.org/wiki/Dynamic_Data_Exchange
http://tmml.sourceforge.net/doc/tcl/dde.html

PS:

Use DDE to test Windows applications, work with Explorer, Internet Explorer, Firefox ...
In large projects, Win32 :: OLE, DBus is better.

In the future, DDE may be cut out :)

Source: https://habr.com/ru/post/74743/


All Articles