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:
Call
HitTestItems
to find theCContainerItem
at the point where the mouse was clicked.Set the selection to be this
CContainerItem
. Note that if noCContainerItem
is located at the point where the mouse was clicked, nothing (NULL) is selected.If something is selected, set up a tracker rectangle (CRectTracker) around the selected object. A CRectTracker object is short lived. It exists only during the time a mouse event is being handled, or as you will see later, during the time a window is being repainted. In the case of a single click, the CRectTracker paints a rectangle with resize handles around the object.
If the item is clicked, CRectTracker::Track captures the mouse, enabling the user to drag the tracker rectangle around on the screen and to:
Resize the item if the click was on a handle.
Drag the item if the click was inside the rectangle.
When the user releases the mouse button, CRectTracker updates its public member variable, m_rect, which represents the new size of the object.
If the user has resized the object (indicated by a value of TRUE being returned from CRectTracker::Track), update the
m_rect
of theCContainerItem
object.
To implement the OnLButtonDown mouse handler
Using WizardBar, select CContainerView from the Class list.
Click the action arrow located on the right end of WizardBar.
Click Add Windows Message Handler.
The New Windows Message and Event Handlers dialog box appears.
From the New Windows messages/events list box, select WM_LBUTTONDOWN.
Click Add and Edit.
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
In ClassView, right-click the class
CContainerView
.From the pop-up menu, click Add Member Function.
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.
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
Using WizardBar, select CContainerView from the Class list.
Click the action arrow located on the right end of WizardBar.
Click Add Windows Message Handler.
The New Windows Message and Event Handlers dialog box appears.
From the New Windows messages/events list box, select WM_LBUTTONDBLCLK.
Click Add and Edit.
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.