Next Previous Up Top Contents Index

4 Advanced Uses of the FLI

4.1 Passing a string to a Windows function

The following example shows how to define a Lisp function which calls a Win32 API function to change the title of the active window. It demonstrates the use ofdefine-foreign-function andwith-foreign-string to pass a Lisp string to a Windows function.

The first step involves defining an FLI type to correspond to the Windowshwnd type, which is the window handle type.

(fli:define-c-typedef fli-hwnd
  (:unsigned :long))

The next step consists of the foreign function definitions. The first foreign function returns the window handle of the active window, by calling the Windows functionGetActiveWindow. It takes no arguments.

(fli:define-foreign-function (get-act-window "GetActiveWindow")
    ()
  :result-type fli-hwnd
  :documentation "Returns the window handle of the active window for the current thread. If no active window is associated with the current thread then it returns 0.")

The next foreign function uses the Windows functionSetWindowText to set the text of the active window titlebar. It takes a window handle and a pointer to an FLI string as its arguments.

(fli:define-foreign-function (set-win-text "SetWindowText" :dbcs)
    ((hwnd fli-hwnd)
     (lpstring :pointer))
  :result-type :boolean
  :documentation "Sets the text of the window titlebar.")

The foreign functionset-win-text returns a boolean to indicate whether it has successfully changed the title bar.

The required FLI data types and foreign functions have been defined. What is now required is a Lisp function which uses them to change the titlebar of the active window. The next function does this:

(defun set-active-window-text (new-text)
  (let ((active-window (get-act-window))
        (external-format (if (string= (software-type)
                                      "Windows NT")
                             :unicode
                           :ascii)))
    (unless (zerop active-window)
      (fli:with-foreign-string (new-ptr element-count byte-count 
                                :external-format external-format)
                               new-text
        (declare (ignore element-count byte-count))
        (set-win-text active-window new-ptr)))))

The functionset-active-window-text takes a Lisp string as its argument, and does the following:

1. It calls the foreign functionget-act-window to set the variableactive-window to be the handle of the active window. If no window is active, this will be zero.
2. The variableexternal-format is set to be:unicode if the operating system is Windows NT (which expects strings to be passed to it in unicode format), otherwise it is set to be:ascii.
3. Ifactive-window is zero, then there is no active window, and the function terminates, returningnil.
4. Ifactive-window is not zero, then it contains a window handle, and the following happens:
The function usesfli:with-foreign-string to convert the Lisp string argument of the function into an FLI string, and a pointer to the FLI string is allocated, ready to be handed to the foreign functionset-win-text that we defined earlier. The format of the string is set to beexternal-format, which is the suitable format for the operating system running on the computer. Once the window title has been set,with-foreign-string automatically deallocates the memory that was allocated for the FLI string and the pointer. The function then terminates, returningt.

You can test that this is what happens by entering the command:

(set-active-window-text "A new title for the active window")

See with-foreign-string, page 86, for more details on the use of foreign strings.


LispWorks Foreign Language Interface - 12 Oct 1998

Next Previous Up Top Contents Index

Generated with Harlequin WebMaker