On Jun 7, 2006, at 1:40 PM, Lisa Sawin wrote:
On Jun 3, 2006, at 11:20 AM, Charles Yeomans wrote:
If you want to write separate window classes for MacOS and Windows
(for ease of layout, perhaps), then you'll need to introduce some
additional classes for delegation of event handling. Here's a way
to do it without massive subclassing. Define a class
CrowdedWindowEventHandler. Move all of the window methods to it.
These methods should only be called from handlers, so you can make
them private. Then start adding a bunch of public methods for
event-handling --
HandleOpen(w as Window)
HandleClose(w as Window)
HandleEnableMenuItems(w as Window)
HandleOpen(b as BevelButton)
HandleAction(b as BevelButton)
HandleKeyDown(e as EditField, key as String) as Boolean
etc.
Passing a reference to the control or window removes the need for
a circular reference.
Now drop an instance of CrowdedWindowEventHandler onto the window;
call this widget EventHandler. Then go to each event handler in
the window and call the corresponding handler --
Sub Open()
EventHandler.HandleOpen me
End Sub
You can then implement window behavior as needed in the handler
methods. If you need to get the state of other controls in a
handler, that's certainly possible. You could do something like
CrowdedWindow(b.Window).EditField1.Text. Casting is generally a
code smell, but since CrowdedWindowEventHandler is auxiliary to
CrowdedWindow, it's a reasonable thing to do in this case.
Wouldn't you have to cast either to MacOSCrowdedWindow or
WindowsCrowdedWindow to get access to a control like editField1?
I'm not sure what exact role CrowdedWindow is playing, but whether
it is an interface or a super to MacOSCrowdedWindow and
WindowsCrowdedWindow, CrowdedWindow doesn't have any controls.
That means every call via casting to a control needs to be done on
a per-target basis, which is even messier! Am I missing something
in your framework?
Unfortunately not; I overlooked this. So we switch to plan B, which
is to reimplement more functionality already provided by REALbasic
for windows (in some sense, this is the point of
CrowdedWindowEventHandler -- the grand plan is more or less to factor
all of the window code into a second class, leaving only the layout
in the window subclass ).
Add the following function to CrowdedWindowEventHandler.
Private Function GetEditField(w as Window, name as String) as EditField)
If w is nil then
Return nil
End if
dim theField as EditField = nil
For i as Integer = 0 to w.ControlCount - 1
If w.Control(i) IsA EditField and w.Control(i).Name = name then
theField = EditField(w.Control(i))
Exit
End if
Next
Return theField
End Function
Then add such a function for every control class you'll need.
The result is that you can now get a reference to a control on a
window by name, with reference cast to the type you expect. Here's a
bit of sample code.
Sub HandleAction(b as BevelButton)
dim s as StaticText = GetStaticText(b.Window, "Label")
If s <> nil then
s.Text = "Foo"
Else
//check to see whether the control name was changed in the window
End if
End Sub
You could also add GetEditField, etc. to a module and change them to
extend the Window class, since they provide a general capability to
look up controls by name. This could also be extended to support
control arrays.
Charles Yeomans
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>
Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>