CCF HAT - Making use of DDAs from Legacy Adapters

Although Data Driven Adapters (DDAs) are mainly designed for Automation Adapters in HAT, we can make use of them from legacy adapters, too. Here's an example of an external VB application, which is configured to use a legacy application adapter and a WinDataDrivenAdapter with the corresponding bindings:

<?xml version="1.0" encoding="utf-16"?>

<initstring>

    <interopAssembly>

        <URL>C:\MyApp.exe</URL>

        <WorkingDirectory>C:\</WorkingDirectory>

        <hostInside />

    </interopAssembly>

    <UseTopLevelWindow class="ThunderRT6Form" />

    <adapter>

        <URL>C:\MyApplicationAdapters.dll</URL>

        <type>Microsoft.Ccf.QuickStarts.MyExtVBAppAdapter</type>

    </adapter>

    <DataDrivenAdapterBindings>

        <Type>Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter.WinDataDrivenAdapter,

              Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter</Type>

        <Controls>

            <AccControl name="button1">

                <Path>

                    <Next>OK</Next>

                </Path>

            </AccControl>

        </Controls>

    </DataDrivenAdapterBindings>

    <optimumSize x="800" y="600" />

    <minimumSize x="640" y="480" />

</initstring>

 

One thing to take into account is that, if the application uses an alternative top level window, the DDA must be instantiated with that top level window instead of the process MainWindowHandle. The picture shows how the alternate top level window configuration is seen in the Admin Console:

And here is the code of the legacy adapter making use of the data driven adapter to automate the hosted application's UI:

using System;

using Microsoft.Ccf.Csr;

using Microsoft.Ccf.HostedApplicationToolkit.DataDrivenAdapter;

namespace Microsoft.Ccf.BancoGalicia.ApplicationAdapters

{

    public class MyExtVBAppAdapter : ApplicationAdapter

    {

        protected DataDrivenAdapterBase _dda;

        public override bool Initialize()

        {

            //IntPtr topLevelWnd = Process.MainWindowHandle;//this won't work for a VB app

            IntPtr topLevelWnd = GetTopLevelWndHandle();

            //Initialize Data Driven Adapter with proper top level window handle

            _dda = DataDrivenAdapterBase.CreateInstance(ApplicationInitString, topLevelWnd);

            return _dda != null;

        }

        public override bool DoAction(Action action, RequestActionEventArgs args)

        {

            switch (args.Action)

            {

                case "DefaultAction":

                    break;

                case "PressButton":

                    PressButton();

                    break;

            }

            return base.DoAction(action, args);

        }

        private void PressButton()

        {

            if (_dda.FindControl("button1"))

            {

                _dda.ExecuteControlAction("button1");

            }

        }

        //Find the top level window of the VB application (for example of class "ThunderRT6Form")

        private IntPtr GetTopLevelWndHandle()

        {

            IntPtr agentDesktopPtr = Win32API.FindWindow(null, "Agent Desktio");

            if (agentDesktopPtr != IntPtr.Zero)

            {

                IntPtr tabWindowHandle = Win32API.FindWindowByText(agentDesktopPtr, "MyApp");

                if (tabWindowHandle != IntPtr.Zero)

                {

                    return Win32API.FindWindowByText(tabWindowHandle, "MyAppTopLevelWndCaption");

                }

            }

            return IntPtr.Zero;

        }

    }

1 Comment

  • Process.MainWindowHandle - this won't work in app that cannot be hosted inside Agent Desktop by normal configuration - include app where "Use Find Window" is checked. Very annoying.

Comments have been disabled for this content.