The class document-frame is used to implement MDI.

This works only in LispWorks for Windows.






The class document-frame is used to implement Multiple-Document Interface (MDI) which is a standard technique on MS Windows (see the MSDN for documentation).

To use MDI in the CAPI, define an interface class that inherits from document-frame , and use the two special slots capi:container and capi:windows-menu as described below.

In your interface's layouts, use the symbol capi:container in the description to denote the pane inside the MDI interface in which child interfaces are added.

Interfaces of any type other than subclasses of document-frame may be added as children. To add a child interface in your MDI interface, call display on the child interface and pass the MDI interface as the screen argument. This will display the child interface inside the container pane. To obtain a list of the child interfaces, call the screen reader function screen-interfaces , passing the document-frame as the screen argument.

You can use most of the normal CAPI window operations such as top-level-interface-geometry and activate-pane on windows displayed as children of a document-frame .

The capi:windows-menu slot contains the Windows Menu, which allows the user to manipulate child interfaces. The standard functionality of the Windows Menu is handled by the system and normally you will not need to modify it. However, you will want to specify its position in the menu bar. Do this by adding the symbol capi:windows-menu in the :menu-bar option of your define-interface form.

Note: capi:windows-menu is a special slot in document-frame and this symbol should not appear elsewhere in the define-interface form.

By default the menu bar is made by effectively appending the menu bar of the document-frame interface with the menu bar of the current child. You can customize this behavior with merge-menu-bars.


This example uses document-frame to create a primitive apropos browser.

Firstly we define an interface that lists symbols. There is nothing special about this in itself.

(capi:define-interface symbols-listing ()
  ((symbols :initarg :symbols))
   ( symbols-pane capi:list-panel
                  :items symbols
   :best-width '(character 40)
   :best-height '(character 10)))

Next we define the MDI interface. Note:

  1. It inherits from document-frame .
  2. capi:container is used in the layout description.
  3. capi:windows-menu is in the :menu-bar list.
  4. When the interface showing the symbols is being displayed, the MDI interface is passed as the screen argument to display.

Otherwise, this example uses standard Common Lisp and CAPI functionality.

(capi:define-interface my-apropos-browser 
  ((string :initarg :string))
    (loop for package in (list-all-packages)
          (let ((al (apropos-list string package)))
            (when al 
              (cons (package-name package) al)))
          collect it)
    :print-function 'car
    #'(lambda (mdi-interface name-and-symbols)
          :symbols  (cdr name-and-symbols)
          :title (car name-and-symbols))
         :screen mdi-interface))
    :callback-type :interface-data)
  (:menu-bar capi:windows-menu)
    '(package-list :divider capi:container)
    :ratios '(1 nil 4)))
   :visible-min-height '(character 20)
   :visible-min-width '(character 100)))

To browse apropos of a specific string

 (make-instance 'my-apropos-browser 
                :string "EDITOR"))
See also


LispWorks CAPI Reference Manual - 25 Jul 2006