Getting parent window like a ContainerControl does

I’ve been using a modified container control as one of my classes simply so that it is able to get the handle from the Window that it is embedded within. It works great, but I don’t require 99% of what is inside a ContainerControl - only that small piece of functionality aforementioned.

How does the ContainerControl know what window it is embedded within? I’ve tried to use parentWindow but I must be doing it wrong, because it’s not working the same.

Have you tried .parent?

Containers, windows, and controls (on the desktop, not web) have a TrueWindow property that returns the enclosing window (or Nil, if none.

Thanks for the replies.

If I wanted to mimic the TrueWindow property for my class, how would I do it? If I created a property called Window or Rectcontrol in my class, I don’t know what to do beyond that point to get that property to store the parent window.

Why would you want to mimic something existing?

Anyhow, in the open event of the container set your property to the TrueWindow property.

I want to mimic the thing that exists in only one aspect, not in its entirety. To explain it with an analogy: “I want to wear the feather of the bird and discard its body, rather than wear the entire bird.” In the same way, I want to use the way a ContainerControl knows which Window it’s embedded in, but without all the rest of the stuff like “Width”, “Height”, etc. My class should be embedded in a Window but it will never be seen. Most of the things in a ContainerControl aren’t needed, so I seek to strip them away.

Due to all of that, my class has no events. I might have the answer though, by passing in a parent from the constructor. If it works, I’ll report back that it did.

With much cursing and some help I got it to behave sort of how I want it to. The downsides are that I have to initialise the class in the open event of a Window and it no longer behaves like an invisible control. Fortunately, it leaves a smaller memory footprint than it did.

What I did:

  1. Made a new computed property in the class called “Parent” as a WeakRef
    Set is blank, Get is:
  dim anObject as Object
  if mParent <> nil then
    anObject = mParent.Value
    if anObject isA Window then
      return Window(anObject)
    end if
  end if[/code]
2.  New constructor with parameter: theParent as object
[code]  mParent = new WeakRef(theParent)
  1. Initialise the class in the open event of my window:
myClass = new class1(self)

Now the class has the Window that it needs.

Poking around in the debugger, I’ve found something that might work.

Using Introspection, you can get a reference to the undocumented ownerWindow property. This property appears to belong to the Object class, from which all other classes inherit.

Function GetOwner(MyObject As Object) As Window
  ' Pass any non-nil object. Returns a reference to the object's window, or Nil if no window.
  Dim props() As Introspection.PropertyInfo = Introspection.GetType(MyObject).GetProperties
  Dim ParentWindow As Window
  For Each p As Introspection.PropertyInfo In props
    If p.Name = "ownerWindow" Then
      ParentWindow = p.Value(MyObject)
      Exit For
    End If
  Next
  Return ParentWindow
End Function

Since ownerWindow is apparently undocumented, it may be altered or removed in future versions without warning.

I’m not sure why this is so confusing, but yeah - since your class is an abstract class (not a user interface element) it has no implicit knowledge of even being embedded into a window, because it could just as well be a property of some other abstract class that has nothing to do with a window.

Since its associated window will never change, you can store a reference to the window in the class itself. When the window opens, you’ll need to pass a reference to the window into it; I usually have an Init(w as window) method that gets called in Window.Open.

Note, however, that your class may not have been instantiated by the time Window.Open does its thing. The safest way to get around this is to declare a property of the window that stores a reference to an instantiation of your class; then, in Window.Open, do an explicit instantiation (myProperty=New MyClass) and initialize it from there. Your constructor might even be MyClass.Constructor(containingWindow) to prevent the class from being created without receiving a reference to a window, if that’s important for its operation…

If you drop an instance of a class onto a window, then the window will call the nearest constructor that expects no parameters (all the way up to Object.Constructor().) This is true even if the nearest such constructor is protected; if the nearest Constructor() is private, the compiler will give you a rather unhelpful error and refuse to build.

Take into consideration that ‘ownerwindow’ is undocumented and in fact not recommended to use in new projects.

ownerWindow WILL disappear
It’s an implementation detail that leaked out

I am afraid we woke up sleeping dogs :slight_smile:

add an event that you can raise that ASKS for the window
then you can call it just like any function in your class & it can get whatever the implementor of that event returns

… or introspect the Window() method of RectControl like Norman proposed here:
https://forum.xojo.com/36171-ownerwindow-weakref