GME
13
|
00001 //############################################################################################################################################### 00002 // 00003 // Object Constraint Language Generic Manager 00004 // GMEConstraintTreeCtrl.cpp 00005 // 00006 //############################################################################################################################################### 00007 00008 #include "StdAfx.h" 00009 #include "GMEConstraintTreeCtrl.h" 00010 00011 #ifdef _DEBUG 00012 #define new DEBUG_NEW 00013 #undef THIS_FILE 00014 static char THIS_FILE[] = __FILE__; 00015 #endif 00016 00017 int static CALLBACK SpecialCompare( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ) 00018 { 00019 CConstraintTreeCtrl* pTree = (CConstraintTreeCtrl*) lParamSort; 00020 int iImNum1, iImNum2; 00021 pTree->GetItemImage( ( HTREEITEM ) lParam1, iImNum1, iImNum1 ); 00022 pTree->GetItemImage( ( HTREEITEM ) lParam2, iImNum2, iImNum2 ); 00023 00024 CString strCaption1 = pTree->GetItemText( ( HTREEITEM ) lParam1 ); 00025 CString strCaption2 = pTree->GetItemText( ( HTREEITEM ) lParam2 ); 00026 00027 if ( iImNum1 < iImNum2 ) 00028 return -1; 00029 if ( iImNum1 > iImNum2 ) 00030 return 1; 00031 return _tcscmp( strCaption1, strCaption2 ); 00032 } 00033 00034 //############################################################################################################################################## 00035 // 00036 // C L A S S : CConstraintTreeCtrl <<< + CTreeCtrlEx 00037 // 00038 //############################################################################################################################################## 00039 00040 IMPLEMENT_DYNAMIC(CConstraintTreeCtrl, CTreeCtrlEx) 00041 00042 CConstraintTreeCtrl::CConstraintTreeCtrl() 00043 : CTreeCtrlEx(), m_eKind( CConstraintTreeCtrl::TK_UNKNOWN ) 00044 { 00045 } 00046 00047 CConstraintTreeCtrl::~CConstraintTreeCtrl() 00048 { 00049 } 00050 00051 BEGIN_MESSAGE_MAP(CConstraintTreeCtrl, CTreeCtrlEx) 00052 //{{AFX_MSG_MAP(CConstraintTreeCtrl) 00053 ON_WM_LBUTTONDOWN() 00054 ON_WM_RBUTTONDOWN() 00055 ON_WM_KEYUP() 00056 ON_WM_LBUTTONDBLCLK() 00057 //}}AFX_MSG_MAP 00058 END_MESSAGE_MAP() 00059 00060 //============================================================================================================================== 00061 // PUBLIC METHOD -> SelectAllItems 00062 // 00063 // DESCRIPTION: 00064 // Selects or deselects the part of the tree specified by the root item 00065 // ARGUMENTS: 00066 // hRoot: 00067 // handle of a tree item which is the begining of the selection 00068 // bSelect: 00069 // trivial 00070 // NOTE: 00071 // As the base class seems to be a little buggy, we have to select explicitly the first visible item 00072 00073 void CConstraintTreeCtrl::SelectAllItems( HTREEITEM hRoot, bool bSelect /* = TRUE */ ) 00074 { 00075 for ( HTREEITEM hItem = hRoot ; hItem != NULL ; hItem = GetNextSiblingItem( hItem ) ) { 00076 for ( HTREEITEM hItem2 = GetChildItem( hItem ) ; hItem2 != NULL ; hItem2 = GetNextSiblingItem( hItem2 ) ) 00077 SelectAllItems( hItem2, bSelect ); 00078 SetItemState( hItem, ( bSelect ) ? TVIS_SELECTED : 0, TVIS_SELECTED ); 00079 } 00080 HTREEITEM hItem = GetFirstVisibleItem(); 00081 if ( hItem ) 00082 SelectItemEx( hItem, bSelect ); 00083 } 00084 00085 void CConstraintTreeCtrl::SetKind( CConstraintTreeCtrl::Kind eKind ) 00086 { 00087 m_eKind = eKind; 00088 } 00089 00090 CConstraintTreeCtrl::Kind CConstraintTreeCtrl::GetKind() const 00091 { 00092 return m_eKind; 00093 } 00094 00095 void CConstraintTreeCtrl::SortItemChildren( HTREEITEM hItem ) 00096 { 00097 TVSORTCB tvs; 00098 tvs.hParent = hItem; 00099 tvs.lpfnCompare = SpecialCompare; 00100 tvs.lParam = (LPARAM) this; 00101 00102 SortChildrenCB( &tvs ); 00103 } 00104 00105 //============================================================================================================================== 00106 // PROTECTED METHOD -> SendTreeNotification 00107 // 00108 // DESCRIPTION: 00109 // Simple helper method in order not to write too much. Sends the specified Tree Notification 00110 // ARGUMENTS: 00111 // uiMessage: 00112 // id of the message 00113 // hItem: 00114 // handle of the appropriate treeitem 00115 00116 void CConstraintTreeCtrl::SendTreeNotification( UINT uiMessage, HTREEITEM hItem ) 00117 { 00118 CWnd* pWnd = GetParent(); 00119 if ( pWnd ) { 00120 NM_TREEVIEW tv; 00121 00122 tv.hdr.hwndFrom = GetSafeHwnd(); 00123 tv.hdr.idFrom = GetWindowLong( GetSafeHwnd(), GWL_ID ); 00124 tv.hdr.code = uiMessage; 00125 00126 tv.itemNew.hItem = hItem; 00127 tv.itemNew.state = GetItemState( hItem, 0xFFFFFFFF ); 00128 tv.itemNew.lParam = GetItemData( hItem ); 00129 00130 pWnd->SendMessage( WM_NOTIFY, tv.hdr.idFrom, (LPARAM) &tv ); 00131 } 00132 } 00133 00134 //================================================================================================================================ 00135 // PROTECTED METHOD -> OnLButtonDown <OVERRIDE, VIRTUAL> 00136 // 00137 // DESCRIPTION: 00138 // It catches the click if it was performed on the ItemStateIcon, otherwise call the base class. 00139 // ARGUMENT: 00140 // See MSDN. 00141 // TODO: 00142 // After catching we should send a NM_CLICK Notification :) 00143 00144 void CConstraintTreeCtrl::OnLButtonDown( UINT nFlags, CPoint point ) 00145 { 00146 UINT flags = 0; 00147 HTREEITEM hItem = HitTest( point, &flags ); 00148 if ( hItem && ( flags & TVHT_ONITEMSTATEICON ) ) { 00149 int iOldState = GETSTATE( hItem ); 00150 if ( iOldState > 2 && iOldState < 8 ) 00151 SendTreeNotification( CTVN_CHECKCHANGED, hItem ); 00152 } 00153 CTreeCtrlEx::OnLButtonDown( nFlags, point ); 00154 } 00155 00156 void CConstraintTreeCtrl::OnRButtonDown( UINT nFlags, CPoint point ) 00157 { 00158 UINT flags = 0; 00159 HTREEITEM hItem = HitTest( point, &flags ); 00160 if ( hItem && ( flags & TVHT_ONITEMSTATEICON ) ) { 00161 int iOldState = GETSTATE( hItem ); 00162 if ( iOldState > 2 && iOldState < 8 ) 00163 SendTreeNotification( CTVN_CHECKCHANGEDREC, hItem ); 00164 } 00165 CTreeCtrlEx::OnRButtonDown( nFlags, point ); 00166 } 00167 00168 //================================================================================================================================ 00169 // PROTECTED METHOD -> OnKeyUp <OVERRIDE, VIRTUAL> 00170 // 00171 // DESCRIPTION: 00172 // It catches the space key, otherwise call the base class. 00173 // ARGUMENT: 00174 // See MSDN. 00175 // TODO: 00176 // After catching we should send a NM_KEY Notification :) 00177 00178 void CConstraintTreeCtrl::OnKeyUp( UINT nChar, UINT nRepCnt, UINT nFlags ) 00179 { 00180 if ( nChar == VK_SPACE ) { 00181 HTREEITEM hItem = GetSelectedItem(); 00182 if ( hItem ) { 00183 int iOldState = GETSTATE( hItem ); 00184 if ( iOldState > 2 && iOldState < 8 ) 00185 SendTreeNotification( CTVN_CHECKCHANGED, hItem ); 00186 } 00187 return; 00188 } 00189 CTreeCtrlEx::OnKeyUp( nChar, nRepCnt, nFlags ); 00190 } 00191 00192 //================================================================================================================================ 00193 // PROTECTED METHOD -> OnLButtonDblClk <OVERRIDE, VIRTUAL> 00194 // 00195 // DESCRIPTION: 00196 // It catches the double click. If it is on TreeButton the delegate the call to the base class. If it is on either the icon or the label CTVN_SHOWITEM notifcation is sent. In any other case it eats the message. 00197 // ARGUMENT: 00198 // See MSDN. 00199 // TODO: 00200 // After catching we should send a NM_DBLCLK Notification :) 00201 00202 void CConstraintTreeCtrl::OnLButtonDblClk(UINT nFlags, CPoint point) 00203 { 00204 UINT flags = 0; 00205 HTREEITEM hItem = HitTest( point, &flags ); 00206 if ( hItem ) 00207 if ( flags & TVHT_ONITEMBUTTON ) 00208 CTreeCtrlEx::OnLButtonDblClk(nFlags, point); 00209 else 00210 if ( flags & ( TVHT_ONITEMICON | TVHT_ONITEMLABEL ) ) 00211 SendTreeNotification( CTVN_SHOWITEM, hItem ); 00212 }