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>

Reply via email to