0

Is there a way to check in the code in a form if the form is being used as a caller for another form that is currently open?

user3660338
  • 296
  • 5
  • 23

3 Answers3

0

As far as I know, out of the box there is no way to check this. If you have a small set of specific forms (say one caller form and 2 or 3 called forms), it should be pretty easy to manage a list of called forms in the caller form by calling a method in the caller form from the called forms.

If you want a generic solution that works for all forms, things get interesting. You probably want to take a look at the SysSetupForm[Run] and SysForm[Run] classes and try to extend these with a similar called forms management logic. It may be necessary to store the data of the called forms management in the global cache.

That said I suggest you rethink your form design. Usually such a requirement is a result of bad design.

FH-Inway
  • 4,432
  • 1
  • 20
  • 37
0

This is just an idea, which I haven't tried but I don't see why it wouldn't work. I didn't optimise the code, so use this idea just as an inspiration.

First, in each form being called from the main form modify the init method as follows:

public void init()
{
    super();

    blahblah::addHandleToCache(element.hWnd());
}

This is the code of blahblah::addHandleToCache:

public static client void addHandleToCache(int _handle)
{
    #define.CACHE_OWNER('MyCallerForm')
    container con;
    int hWnd;
    int i;

    //get a container with open window handles from the cache
    if (infolog.globalCache().isSet(#CACHE_OWNER, curUserId()))
    {
        con = infolog.globalCache().get(#CACHE_OWNER, curUserId());
    }

    //remove handles of closed windows from the container
    for (i = conLen(con); i >= 1; i--)
    {
        hWnd = conPeek(con, i);

        if (!WinApi::isWindow(hWnd))
        {
            conDel(con, i, 1);
        }
    }

    //add the current window handle to the container
    con += _handle;

    //save the container in the cache
    infolog.globalCache().set(#CACHE_OWNER, curUserId(), con);
}

Now when you want to check whether your main form is being used as a caller for other open forms you can use the following check:

public boolean hasOpenChildForms()
{
    #define.CACHE_OWNER('MyCallerForm')
    container con;
    int hWnd;
    boolean ret;

    //get a container with open window handles from the cache
    if (infolog.globalCache().isSet(#CACHE_OWNER, curUserId()))
    {
        con = infolog.globalCache().get(#CACHE_OWNER, curUserId());
    }

    for (i = conLen(con); i >= 1; i--)
    {
        hWnd = conPeek(con, i);

        if (WinApi::isWindow(hWnd))
        {
            //the form is open
            ret = true
        }
        else
        {
            //remove handles of closed windows from the container
            conDel(con, i, 1);
        }
    }

    return ret;
}
10p
  • 5,488
  • 22
  • 30
-1

Yes, there is.

Your code should look something like this for AX 2009:

Object caller = element.args().caller();

if (SysDictClass::isEqualOrSuperclass(classIdGet(caller), classNum(FormRun)))
{
    // ...
}

And something like this for AX 2012:

Object caller = element.args().caller();

if (caller is FormRun)
{
   // ...
}

But please note that the caller() will only be set at this point if the form was called through a menu item. If you invoke a method directly, you'll have to manually set the caller() in the Args object.

If you want to call a method on the caller form, I've blogged about this in the past:

http://devexpp.blogspot.com.br/2013/09/calling-methods-on-caller-dynamics-ax.html

Smur
  • 3,075
  • 7
  • 28
  • 46
  • Maybe I did not understand the question correctly, but I think @user3660338 wants to know if a form has called any forms. Your code would help him to check if a form has been called by a form. – FH-Inway Jul 28 '15 at 18:41