A Stop by the Hardware Store

Hi there! Welcome to Hank's Hardware Heaven! We have everything! We have plumbing. We have lighting. We have paints, wallboard, industrial appliances, and 387 types of electrical tape! You want tools? We have tools! Lots of tools! Screwdrivers, wire cutters, wrenches, tape measures, drills, sanders, planers, jigsaws, band saws, hacksaws, power saws, table saws, radial arm saws! We have every conceivable drill bit, every conceivable lathe tool, every

Oh, pipe down. Can you just point me to the toolbars?

Huh? Toolbars? Ain't got none of those.…Better try the object down the street.

The remaining user interface problem that we need to address is the toolbar. If you look back to Figure 22-9, you'll notice that Patron's toolbar is still visible and accessible. For the most part, that's fine because it provides easy access to commands such as File Open, File Save, Edit Copy, and Edit Paste, as well as the commands that also appear on the Page menu. There are two problems with this, however. First, while the object has the user's attention, none of its tools (if it has any) are visible. The second problem is that Edit commands are available on both the menu and the toolbar. The commands on the menu, however, are dispatched to the object, while those on the toolbar end up in the container, which still owns the toolbar. Although the end user sees the same commands on the toolbar and the menu, the commands behave differently. Not good.

For these and other fine reasons, in-place activation gives ownership of toolbars to the in-place object. The exception is the status line at the bottom of the window, which the container maintains for consistency.4 To achieve this, the object has to negotiate with the container for space in the frame or document windows using the RequestBorderSpace member function of IOleInPlaceUIWindow (which is part of IOleInPlaceFrame as well).

The object first calls RequestBorderSpace in the appropriate interface, passing a BORDERWIDTHS structure (defined as a RECT). The structure's left, right, top, and bottom fields indicate the amount of space the object wants to allocate from each side of the window. Here the container can decide whether it wants to surrender that space to the object, and the container has every right to say no. If the container surrenders the space, the object then calls IOleInPlaceUIWindow::SetBorderSpace, at which time the container repositions its windows (like an MDI client) to make space for the object's tools. The object calls IOleInPlaceUIWindow::GetBorder to determine the actual dimensions of the container window and creates its tools as children of the container window to fit. After all this is done, the object has whatever tools it wants inside the container's frame (and document) window. Cosmo itself creates a single toolbar in the frame window, as shown in Figure 22-10. At this point, Cosmo is completely in-place activated.

Figure 22-10.

Cosmo fully in-place activated in Patron.

If a container denies an object's call to RequestBorderSpace, the object can adjust its request and try the call again until the container accepts it. If an obstinate container refuses to grant an object space for its tools, it's not the end of the world. The object can always display those tools in a floating pop-up window because popups don't require permission from the container. A flexible object would generally be able to display its tools in a popup or on a toolbar on any side of a window in such a way that it would be able to work well in any container. If it does so, it has to enable and disable these pop-up windows inside IOleInPlaceActiveObject::EnableModeless. A container will use EnableModeless to simulate what Windows does automatically for a window hierarchy owned by a single application—when a modal window is displayed, all the others are disabled. With in-place activation, some of these windows are not owned by the container, so EnableModeless is used to communicate the necessary behavior for those windows.

Besides pop-up tools and toolbars in the frame and the document window, the object is also allowed to create object adornments, which are additional tools attached to the outer edges of the editing window. For example, table or spreadsheet objects might want to display row and column headers. A text-editing object might want to display style information to the left of the text. In these cases, the object simply makes its in-place window larger, always keeping the editing space the same size as the container site—that is, the same size as the object that is displayed in the container when the object is not active. The only restriction to these object adornments is that they cannot reach outside a clipping rectangle provided by the container under any circumstances. The object must obey out of courtesy—there are no police to stop you, but end users would most likely complain about the visual problems that disobedience would cause.

4 Chapter 25 will describe some current work to better integrate toolbars so that the container can keep some of its own tools available.