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?
3 Answers
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.

- 4,432
- 1
- 20
- 37
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;
}

- 5,488
- 22
- 30
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

- 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