Advanced MFC Programming
Advanced MFC Programming Advanced MFC Programming
Chapter 5. Common Controls implement dragging. We can also create our own customized image list for dragging operation, the procedure of creating this type of image list is the same with creating a normal image list. 1) We can call function CImageList::SetDragCursorImage(…) to combine an image contained in the image list with the cursor to begin dragging. 1) We must lock the tree control window when a node is being dragged around to avoid any change happening to the tree structure (When a node is being dragged, the tree should not change). When we want to do a temporary update (For example, when the dragging image enters a node and we want to highlight that node to indicate that the source can be dropped there), we must first unlock the window, then implement the update. If we want the dragging to be continued, we must lock the window again. 1) Function CImageList::EnterDrag(…) can be called to enter dragging mode and lock the tree control window. Before we make any change to the tree control window (For example, before we highlight a node), we need to call function CImageList::LeaveDrag(…) to unlock the tree control window. After the updates, we need to call CImageList::EnterDrag(…) again to lock the window. This will prevent the tree control from being updated when a node is being dragged around. 1) We can show or hide the dragging image by calling function CImageList::DragShowNolock(…) without locking the tree control window. This function is usually called before CImageList::SetDragCursorImage(…) is called. 1) To begin dragging, we need to call CImageList::BeginDrag(…); to move the dragging image to a specified position, we can call CImageList::DragMove(…); to end dragging, we need to call CImageList::EndDrag(). 1) We can highlight a node by calling function CTreeCtrl::SelectDropTarget(…). The following is a list of prototypes of the above-mentioned functions: BOOL CImageList::DragShowNolock(BOOL bShow); Parameter bShow Meaning TRUE to show the dragging image, FALSE to hide it. This function does not lock the tree control window. BOOL CImageList::SetDragCursorImage(int nDrag, CPoint ptHotSpot); Parameter nDrag PtHotSpot Meaning Index of the image in the list that will be used as the dragging image. Position of the hot spot in the image, this position will be used to do hit test when the image is being dragged around. BOOL CImageList::BeginDrag(int nImage, CPoint ptHotSpot); Parameter nImage ptHotSpot Meaning Index of the image in the list that will be used as the dragging image. Initial position to start dragging. BOOL CImageList::DragMove(CPoint pt); Parameter pt Meaning New position where the dragging image can be put. BOOL CImageList::DragEnter(CWnd *pWndLock, CPoint point); Parameter pWndLock point Meaning Pointer to the window that should be locked during the dragging. Position where the dragging image can be displayed. BOOL CImageList::DragLeave(CWnd *pWndLock); 126
Chapter 5. Common Controls Parameter pWndLock Meaning The window that has been locked during the dragging. BOOL CTreeCtrl::SelectDropTarget(HTREEITEM hItem); Parameter hItem Meaning Handle of the node that is to be highlighted. When the mouse button is released, we need to check if the source node can be copied to the target node. In the sample, we disable copying under the following three conditions: 1) The source node is the same with the target node. 2) The target node is a descendent node of the source node. 3) The target node does not have any child node. By setting these restrictions, a node can only be copied to become the child of its parent node (direct or indirect). We can use function CTreeCtrl::GetParentItem(…) to decide if one node is the descendent of another node: HTREEITEM CTreeCtrl::GetParentItem(HTREEITEM hItem); This function will return an HTREEITEM handle, which specifies the parent of node hItem. By repeatedly calling this function we will finally get a NULL return value (This indicates that the root node was encountered). Using this method, we can easily find out a list of all nodes that are parents of a specific node. New Member Variables and Functions To implement drag-n-drop, several new variables and functions are declared in class MCTreeCtrl: …… …… class MCTreeCtrl : public CTreeCtrl { public: void CopyItemTo(HTREEITEM, HTREEITEM); BOOL IsDescendent(HTREEITEM, HTREEITEM); //{{AFX_VIRTUAL(MCTreeCtrl) //}}AFX_VIRTUAL protected: BOOL m_bIsDragging; CImageList *m_pilDrag; HTREEITEM m_hTreeDragSrc; HTREEITEM m_hTreeDragTgt; }; Here, Boolean type variable m_bIsDragging is used to indicate if the drag-n-drop activity is undergoing. Pointer m_pilDrag will be used to store the dragging image. Variables m_hTreeDragSrc and m_hTreeDragTgt are used to store the handles of source and target nodes respectively. We can use them to implement copying right after the source node is dropped. Function MCTreeCtrl::IsDescendent(…) is used to judge if one node is the descendent node of another, and MCTreeCtrl::CopyItemTo(…) will copy one node (and all its descendent nodes) to another place. Node Copy When copying a node, we want to copy not only the node itself, but also all its descendent nodes. Since we do not know how many descendents a node have beforehand, we need to call function MCTreeCtrl::CopyItemTo(…) recursively until all the descendent nodes are copied. The following is the implementation of this function: void MCTreeCtrl::CopyItemTo(HTREEITEM hTreeDragTgt, HTREEITEM hTreeDragSrc) { 127
- Page 91 and 92: Chapter 4. Button Now we can remove
- Page 93 and 94: Chapter 4. Button } ( m_bBmpCheck ?
- Page 95 and 96: Chapter 4. Button using bit-wise AN
- Page 97 and 98: Chapter 4. Button Overriding Functi
- Page 99 and 100: Chapter 4. Button …… First pBit
- Page 101 and 102: Chapter 4. Button Using Class MCBit
- Page 103 and 104: Chapter 4. Button The button’s ID
- Page 105 and 106: Chapter 4. Button However, since me
- Page 107 and 108: Chapter 4. Button Here, we use subc
- Page 109 and 110: Chapter 5. Common Controls command
- Page 111 and 112: Chapter 5. Common Controls ((CSpinB
- Page 113 and 114: Chapter 5. Common Controls } The in
- Page 115 and 116: Chapter 5. Common Controls …… B
- Page 117 and 118: Chapter 5. Common Controls The “S
- Page 119 and 120: Chapter 5. Common Controls button
- Page 121 and 122: Chapter 5. Common Controls In this
- Page 123 and 124: Chapter 5. Common Controls (CBN_CLO
- Page 125 and 126: Chapter 5. Common Controls compare
- Page 127 and 128: Chapter 5. Common Controls } ptrEdi
- Page 129 and 130: Chapter 5. Common Controls ……
- Page 131 and 132: Chapter 5. Common Controls void CWn
- Page 133 and 134: Chapter 5. Common Controls Five loc
- Page 135 and 136: Chapter 5. Common Controls This fun
- Page 137 and 138: Chapter 5. Common Controls After cr
- Page 139 and 140: Chapter 5. Common Controls typedef
- Page 141: Chapter 5. Common Controls Using th
- Page 145 and 146: Chapter 5. Common Controls void MCT
- Page 147 and 148: Chapter 5. Common Controls modifica
- Page 149 and 150: Chapter 5. Common Controls In funct
- Page 151 and 152: Chapter 5. Common Controls Changing
- Page 153 and 154: Chapter 5. Common Controls m_tabCtr
- Page 155 and 156: Chapter 5. Common Controls Custom R
- Page 157 and 158: Chapter 6. Dialog Box Chapter 6 Dia
- Page 159 and 160: Chapter 6. Dialog Box void CMLDialo
- Page 161 and 162: Chapter 6. Dialog Box } Function CP
- Page 163 and 164: Chapter 6. Dialog Box Everything is
- Page 165 and 166: Chapter 6. Dialog Box } MINMAXINFO;
- Page 167 and 168: Chapter 6. Dialog Box Sample Sampel
- Page 169 and 170: Chapter 6. Dialog Box } brush=(HBRU
- Page 171 and 172: Chapter 6. Dialog Box wndA.GetWindo
- Page 173 and 174: Chapter 6. Dialog Box rectStaticGrp
- Page 175 and 176: Chapter 6. Dialog Box } TOOLTIPTEXT
- Page 177 and 178: Chapter 6. Dialog Box ) { } if ( )
- Page 179 and 180: Chapter 6. Dialog Box pWndCtrl=GetW
- Page 181 and 182: Chapter 6. Dialog Box Sample 6.8-2\
- Page 183 and 184: Chapter 6. Dialog Box } // handle t
- Page 185 and 186: Chapter 6. Dialog Box 1) Tracking s
- Page 187 and 188: Chapter 7. Common Dialog Boxes DWOR
- Page 189 and 190: Chapter 7. Common Dialog Boxes } {
- Page 191 and 192: Chapter 7. Common Dialog Boxes } }
Chapter 5. Common Controls<br />
Parameter<br />
pWndLock<br />
Meaning<br />
The window that has been locked during the dragging.<br />
BOOL CTreeCtrl::SelectDropTarget(HTREEITEM hItem);<br />
Parameter<br />
hItem<br />
Meaning<br />
Handle of the node that is to be highlighted.<br />
When the mouse button is released, we need to check if the source node can be copied to the target<br />
node. In the sample, we disable copying under the following three conditions: 1) The source node is the<br />
same with the target node. 2) The target node is a descendent node of the source node. 3) The target node<br />
does not have any child node. By setting these restrictions, a node can only be copied to become the child<br />
of its parent node (direct or indirect).<br />
We can use function CTreeCtrl::GetParentItem(…) to decide if one node is the descendent of<br />
another node:<br />
HTREEITEM CTreeCtrl::GetParentItem(HTREEITEM hItem);<br />
This function will return an HTREEITEM handle, which specifies the parent of node hItem. By<br />
repeatedly calling this function we will finally get a NULL return value (This indicates that the root node<br />
was encountered). Using this method, we can easily find out a list of all nodes that are parents of a specific<br />
node.<br />
New Member Variables and Functions<br />
To implement drag-n-drop, several new variables and functions are declared in class MCTreeCtrl:<br />
……<br />
……<br />
class MCTreeCtrl : public CTreeCtrl<br />
{<br />
public:<br />
void CopyItemTo(HTREEITEM, HTREEITEM);<br />
BOOL IsDescendent(HTREEITEM, HTREEITEM);<br />
//{{AFX_VIRTUAL(MCTreeCtrl)<br />
//}}AFX_VIRTUAL<br />
protected:<br />
BOOL m_bIsDragging;<br />
CImageList *m_pilDrag;<br />
HTREEITEM m_hTreeDragSrc;<br />
HTREEITEM m_hTreeDragTgt;<br />
};<br />
Here, Boolean type variable m_bIsDragging is used to indicate if the drag-n-drop activity is<br />
undergoing. Pointer m_pilDrag will be used to store the dragging image. Variables m_hTreeDragSrc and<br />
m_hTreeDragTgt are used to store the handles of source and target nodes respectively. We can use them to<br />
implement copying right after the source node is dropped. Function MCTreeCtrl::IsDescendent(…) is<br />
used to judge if one node is the descendent node of another, and MCTreeCtrl::CopyItemTo(…) will copy<br />
one node (and all its descendent nodes) to another place.<br />
Node Copy<br />
When copying a node, we want to copy not only the node itself, but also all its descendent nodes. Since<br />
we do not know how many descendents a node have beforehand, we need to call function<br />
MCTreeCtrl::CopyItemTo(…) recursively until all the descendent nodes are copied. The following is the<br />
implementation of this function:<br />
void MCTreeCtrl::CopyItemTo(HTREEITEM hTreeDragTgt, HTREEITEM hTreeDragSrc)<br />
{<br />
127