Implementing Activation by Using a Mouse Click

Container has a standard user interface for selecting and activating embedded objects. A single click selects an object; a double-click activates it. If the object is selected, the user can move or resize it, or in general, manipulate the object as a whole. If the object is activated in place, the user can edit it.

Implementing the OnLButtonDown handler so that a single click selects the embedded object follows this scheme:

To implement the OnLButtonDown mouse handler

  1. Using WizardBar, select CContainerView from the Class list.

  2. Click the action arrow located on the right end of WizardBar.

  3. Click Add Windows Message Handler.

    The New Windows Message and Event Handlers dialog box appears.

  4. From the New Windows messages/events list box, select WM_LBUTTONDOWN.

  5. Click Add and Edit.

  6. Implement CContainerView::OnLButtonDown in ContainerView.cpp by replacing the //TODO comments with the following code.
    CContainerItem* pItemHit = HitTestItems(point);
    SetSelection(pItemHit);
    
    if (pItemHit != NULL)
    {
    CRectTracker tracker;
    SetupTracker(pItemHit, &tracker);
    
    UpdateWindow();
    if (tracker.Track(this, point))
    {   
    Invalidate();        
    pItemHit->m_rect = tracker.m_rect;
    GetDocument()->SetModifiedFlag();
    }
    }    
    

    Note   Your code should come before, but not replace, the call to the base class (CView) that WizardBar adds to the starter handler.

    For now, the entire client area of the view is invalidated. Smarter invalidation is implemented in Step 2.

The helper function SetupTracker sets up the styles of the tracker rectangle according to the state of the CContainerItem object, such as whether it has been selected.

To implement the helper function CContainerView::SetupTracker

  1. In ClassView, right-click the class CContainerView.

  2. From the pop-up menu, click Add Member Function.

  3. Fill in the Add Member Function dialog box as follows:
    • In the Function Type box, type void.

    • In the Function Declaration box, type:
    SetupTracker(CContainerItem* pItem, CRectTracker* pTracker)
    
    • In the Access area, select Public, and click OK.
  4. Implement the helper function with the following code:
    pTracker->m_rect = pItem->m_rect;
    
    if (pItem == m_pSelection)
    pTracker->m_nStyle |= CRectTracker::resizeInside;
    
    if (pItem->GetType() == OT_LINK)
    pTracker->m_nStyle |= CRectTracker::dottedLine;
    else
    pTracker->m_nStyle |= CRectTracker::solidLine;
    
    if (pItem->GetItemState() == COleClientItem::openState ||
    pItem->GetItemState() == COleClientItem::activeUIState)
    {    
    pTracker->m_nStyle |= CRectTracker::hatchInside;
    }
    

The OnLButtonDblClick handler needs to be implemented so that if the user double-clicks, the object is opened (OLEIVERB_OPEN). How the object is opened depends on whether the server supports in-place editing. If the user presses CTRL while double-clicking, the Open verb of the object should be called. Otherwise, call the primary verb, the meaning of which is determined by the server.

To implement the OnLButtonDblClick mouse handler

  1. Using WizardBar, select CContainerView from the Class list.

  2. Click the action arrow located on the right end of WizardBar.

  3. Click Add Windows Message Handler.

    The New Windows Message and Event Handlers dialog box appears.

  4. From the New Windows messages/events list box, select WM_LBUTTONDBLCLK.

  5. Click Add and Edit.

  6. Implement CContainerView::OnLButtonDblClk in ContainerView.cpp by replacing the //TODO comment inside the starter handler code that WizardBar generates with the following code:
    OnLButtonDown(nFlags, point);
    
    if (m_pSelection != NULL)
    {
    m_pSelection->DoVerb(GetKeyState(VK_CONTROL) < 0 ? 
    OLEIVERB_OPEN : OLEIVERB_PRIMARY, this);
    }
    

    Note   Your code should come before, but not replace, the call to the base class (CView) that WizardBar adds to the starter handler.