This model works in the following manner MDIFrameParentControl This is the outside window. any activations within this window will be performed in the following manner 1) If this isnt the active frame it will be set as the active frame and any menus and accelerators will be set. 2) When a command is issued it will be redirected by the WindowController to the active frame via the HandleCall method. Except for the following circumstances. If the Window contains the handle for the command (based on lParam) Diagarm _________________________/----- MDIFrameParentControl (WndProc) Window class ='SuBtnfaceArrow' | ______________________|__/-- MDIFrameControl (Controller) | | | | | _______________________|__/---MDIinternalFrameControl(WndProc) Window class ='MDICLIENT' | | | | | | | | | | | | | | | | | | | | Createing an MDI application Generally you would want to subclass the MDIFrameControl to customize the global menus and global commands for your application. When a new child window is created it retrieves the information given in the GetGlobalMenu and GetGlobalCommands to build its menu and commands. The MDIChildWindow is aware of which direction a commands has come from the global commands are sent upstream of the ChildWindow via the windows variable .Mdiparent.Send command Note: There is always 1 hidden window in the MDIinternalFrameControl. This window is used to create menus and accelerator keys when there are no other windows open. If you want additional controls in the MDIFrameControl you can add them by specifing the Controls: but you must define the following two methods GetWindowFrame() Returns the MDIinternalFrame constructed Object GetWindowControl() Returns the MDIWindow contructed Object The default controls are Controls:#(Vert MDIWindow MDIinternalFrameControl ) The default Methods to return the appropiate controls are GetWindowFrame() { return .Vert.MDIinternalFrame } GetWindowControl() { return .Vert.MDIWindow; } Some basic rules If there is no active child windows in the frame the frame will revert to using the global menu and global commands. This is performed by a base window which when created will assume the focus even though it is never visible. Persistent ========== Persistent applications should call the GetState and SetState methods of the MDIFrameControl object. These will save the window(s) positions and names The last active window information is not currently stored. On startup it will add all the windows to the Frame in the order that they were originally added. MDIWindowController Startup =========================== This is really a class. On creation it inserts itself as the event handler for the window. It then posts a COMMAND event which when recieved it will tell the frames that they can add there windows. This is done so the main window does not recieve an activate event prior to the control being created Event Handling ============== Event control is performed through the MDIWindowController. When a FrameControl is initiated it attempts to register with the MDIWindowController thru a static method. The MDIWindowController examines the control.Window object for a member called MDIWindowController if it does not find one it creates one. By Createing a new instance of this it Subclasses the window callback. This is done to intercept all calls. When intercepting a call it determines which (if any) frame is active If a frame is active it will dispatch the call to the frame through the method HandleCall. The MDIWindowController also intercepts the MOUSEACTIVATE and ACTIVATE messages to properly set menus and accelerators depending on which Frame is active. Focus ===== If you wish to change the focus from a control to another window's control you must first setthe focus on the other window prior to moving the focus to the other control. This will cause the other window to be activated in the frame and allow you to move the focus there. This also includes moving the focus on the main window's controls if a child frame control or window wishes to set the focus on another control's window must have the SetFocus called on it. The window's MDIController will then set the activeframe to false and the focus may be moved Common Programming functions ============================ MDIFrameControl --------------- +AddWindow(control,persistIfClosed=false,windowargs=false,windowtitle=false,position=false,objectstate=false) control - the control to be added to the MDIChildWindow persistIfClosed - if true then when the window is closed the classstate will be persisted till it is opened again windowargs - additional arguements sent to the window windowtitle - override the windows default title to this position - position of the window within the frame objectstate - the class state data. Notes: This will only add windows after the PostQuedWindows method has been called by the MDIWindowController +CreateWindow(@args) You can over ride this to create a specific window of a base type of MDIChildWindow (If neccessary) +GetGlobalMenu(window) Override this method to change or add to the global menu. The window is the Window requesting the menu, You can examine window.BaseWindow, if it is true then this is the window which is active when all others are closed. Returns an object of the Menu +GetGlobalCommands(window) Override this method to change or add to the global commands. The window is the Window requesting the commands, You can examine window.BaseWindow, if it is true then this is the window which is active when all others are closed. Note: Accelerators in the GetGlobalCommands take precedence over accelerators in the created window controls Returns an object of the commands +SetActiveWindow(windowTitle) This method allows you to activate the window from said windowTitle if the windowTitle exists the focus will be moved to the window. Returns true if window exisits false otherwise +GetWindows() Returns an object of all the windows available Do not modify the returned object or else this will cause problems +GetState() Returns an object with the state information +SetState(value) Sets the state information for this control. This adds the windows to the Control based on the state information object in value +MapRedirect(control) Sent from the MDIChildWindow after it has been created, this allows you to redirect all events directed to the MDIChildWindow.Ctrl object Samples ======= Refer to the S_WorkspaceControl for a typical application Refer to the SplitWorkspaceControl for a split frame application Persistent exapmple - PersistentWindow(#(S_Workspace)); Bonus ===== Also in this package is some tools which I also found useful SplitScintillaControl. Provides a direct replacement for the Scintilla control but it allows for 2 working panes SplitLibViewControl Same as LibViewControl but uses the SplitScintillaControl