In-place activation has two notable effects on the elements of an object's user interface:
Many of the issues that I raise here are similar to the concerns for containers that we looked at in Chapter 22. You might find it beneficial to read the section "Prepare the Container" on page 1035 if you have not already done so.
When you activate in place, you need to share the menu with the container. The menus you typically display for an object in a server will not all be available, nor will the keyboard accelerators assigned to them. This means that you'll need to use a different accelerator table while in place and move critical commands to menus in your Edit, Object, and Help menu groups. A typical problem is how to deal with a File Import command, which is a good command to have when editing. Consider how you might move this item to your Edit menu as a command such as Import From File. (I didn't do this with Cosmo.) You'll need to take steps such as these for similar menus.
Your object will still receive messages for the menus you place in the shared menu set, including WM_INITMENUPOPUP. Typically, you will still use this message to enable or disable certain items, such as Edit Paste. Oftentimes an application will use the absolute position of a menu item for enabling and disabling. But because the absolute position of each popup you might process will most likely change in the shared menu, you can no longer compare the index of the pop-up menu in this message with a constant. For example, the Edit menu is usually at index 1, so many applications have code that says, "If the pop-up menu is in position 1, enable or disable the Paste command." You have two ways to deal with this. The first is to keep an array of integers that holds the current position for each menu you have showing. The second technique is to depend solely on the menu handles that are passed with messages such as WM_INITMENUPOPUP. I will demonstrate this approach later in this chapter by creating an array of HMENU messages on startup and comparing the hMenu in the message with those in this array.
The other big impact on an object is that you are going to place a number of windows in the container's user interface as children of container windows. But because you have no control over those parent windows, you should ask yourself a few questions. Do the windows you intend to use send any messages to the parent window? Many of the standard Windows controls do exactly this—but you don't want them sending unexpected messages to the container's windows! Do your windows make assumptions about what other windows exist? Do your windows use WS_CLIPSIBLINGS? They should because you are going to share space with unknown sibling windows, and you do not want to overlap them visually. Can your windows be independently resized outside a WM_SIZE message in another window? At some point, the container application might ask your application to take just such an action in your IOleInPlaceActiveObject implementation, so be prepared. How will your editing window react if it cannot be shown completely? Can it handle the clipping rectangle that the container will specify?
The biggest problem is the first one mentioned here: windows that send messages to their parent. In this case, you need to redirect those messages by either rewriting the code for those windows or wrapping those windows with code that can forward the messages to another window altogether.