On Thu, 25 Nov 2004 19:21:49 GMT, "David W. Fenton"
<dX********@bway.net.invalid> wrote:
"Darryl Kerkeslager" <Ke*********@comcast.net> wrote in
news:Uf********************@comcast.com:
My preferred method has been the one you mention first, pushing
the value back from the called form. The problem I ran into with
this is that when I want to re-use the same form by calling it
from multiple forms, I have to pass the calling form's name in the
OpenArgs in order to push it back to the proper form\control.
Use a class module to store the values. In fact, you could wrap the
called form in the class module and have the calling form initialize
the class. Your class could then automatically open the called form
as dialog, and on close, would populate the properties/members of
the class. Then your calling form would simply read the values out
of the class instance and then destroy it.
There are several advantages to this approach:
1. the called form needs to nothing about who called it -- it
communicates only with its wrapper class module.
2. the calling form needs to know nothing about the called form --
it just has to utilize the interface to it provided by the class
module.
You could also make a generic wrapper class module and use an array
in your class module to hold the property/value pairs that are
needed. Obviously, the calling context would need to know exactly
what properties are needed/supplied by the form, but that's the case
with a class module dedicated to a single form, as well.
Steve Jorgensen: comments on this? Have you done this kind of thing?
Any ideas on making it more foolproof with tricks to generate
compile-time errors?
In one application, I had to do an awful lot of opening dialog forms and
getting user responses back, and I ended up with a scheme that combines a
generic helper function with specific wrapper functions for each case. The
call stack looks something like this...
1. Code calls specific wrapper function with parameters.
2. Wrapper function creates a collection, and adds the parameters using
parameter names as keys, and calls helper function, passing a form name and
the parameter collection.
3. Helper function adds the parameters collection to a global collection
variable using the form name as the collection key, and opens the indicated
form in dialog mode.
4. The form calls another helper function, passing Me as an argument.
5. The helper function grabs the parameters collection from the global
collection using <form>.name as the key, deletes that item from the global
collection to prevent collisions next time, and returns the parameters
collection to the form.
6. Now, the user interacts with the form, and selects an option telling the
form to close.
7. The form creates a return values collection, adds return values to the
collection, and calls a generic helper function for returning values, passing
Me and the collection as parameters.
8. The helper function again adds the parameters collection to a global
collection using the form's name as a key.
9. The form closes, and the generic helper function started in step 3
continues running.
10. The helper function that opened the form now gets the return values
collection from the global collection using the form name as a key, and
deletes the item from the global collection.
11. The helper function returns the return values collection to the specific
wrapper function.
12. The specific wrapper function reads the values from the return values
collection, and returns them to the caller either as a function return value,
via ByRef parameters, or both.
This combination of specific and generic layers provides a high degree of code
reuse, and a pretty high level of safety as well. Since the dialog form is
always called via a specific wrapper function with specific parameters and a
specific return type, everything is type-safe at that interface boundary.
Inside the boundary, there is no name or type safety, but if there is a
problem, the code will generally fail early and in obvious ways.
Notes and variations:
1. When I refer to the global collection variables above, that's just a
shorthand to make the explanation simpler. They are really private variables
at the head of the module that contains the helper functions.
2. The specific wrapper function can just as well be a wrapper class. In some
cases, that's helpful, and in other cases, it's way overkill.
3. You can actually pass any kind of an object to/from the form using this
code, not just a collection, so if you'd rather create a class for passing the
values back-and-forth, you can. Usually, this is overkill unless you'll be
passing the same parameters for multiple forms or unless you already have a
wrapper class - see #4 below.
4. Combination of 2 and 3 - If you have a wrapper class, you can have that
class pass itself as the parameter object to the form via the helper function,
and the form can hold a reference to it, and return values directly to members
of the wrapper class. The form does not need to call a helper function to
return values in this case.