/////////////////////////////////////////////////////////////////////////////// // // Implementation file // /////////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include "WAW_Main.hpp" #include "WAW_User.hpp" #include "WAW_Strg.hpp" #include "WAW_Data.hpp" #include "ErO.h" //*** Global Variables for Watch Dialog WAW_MainDialog * WAW_g_pclWatchWindow = NULL; CList WAW_g_clListOfUser; BOOL WAW_g_bAcceptMessage = TRUE; CImageList * WAW_g_pclImageList = NULL; #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define WAW_M_bCheckInfo(_hInfo) (WAW_g_clListOfUser.Find((_hInfo)) != NULL) //****************************** // Create the Main Dialog Window //****************************** void WAW_fn_vInitWatchWindow() { ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Create the Watch Window Main Dialog", "WAW_fn_vInitWatchWindow", E_ERROR_GRAVITY_INSTABLE, "The Main Dialog is not allocated" ); if( WAW_g_pclWatchWindow == NULL ) WAW_g_pclWatchWindow = new WAW_MainDialog( AfxGetMainWnd() ); ERROR_ASSERT( WAW_g_pclWatchWindow != NULL ); if( WAW_g_pclImageList == NULL ) { ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Create the Watch Window Image List", "WAW_fn_vInitWatchWindow", E_ERROR_GRAVITY_INSTABLE, "The Image List is not allocated" ); WAW_g_pclImageList = new CImageList; ERROR_ASSERT( WAW_g_pclImageList != NULL ); if( WAW_g_pclImageList == NULL ) return; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Create the Watch Window Image List", "WAW_fn_vInitWatchWindow", E_ERROR_GRAVITY_INSTABLE, "The Image List is not created" ); BOOL bResult = WAW_g_pclImageList->Create( 16, 16, ILC_COLOR16, 10, 5 ); ERROR_ASSERT( bResult != NULL ); if( bResult == FALSE ) return; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Create the Watch Window Image List", "WAW_fn_vInitWatchWindow", E_ERROR_GRAVITY_INSTABLE, "The pointer to CTreeCtrl is NULL" ); CTreeCtrl * pclTreeCtrl = WAW_g_pclWatchWindow->m_pub_fn_pclGetTreeCtrl(); ERROR_ASSERT( pclTreeCtrl != NULL ); if( pclTreeCtrl == NULL ) return; pclTreeCtrl->SetImageList( WAW_g_pclImageList, TVSIL_NORMAL ); } } void WAW_fn_vRefreshWatchWindow() { if( WAW_g_bAcceptMessage ) WAW_fn_vSendMessage( WAW_eUpdateData, NULL ); } void WAW_fn_vSendMessage( WAW_tdeMessage _eMessage, void* _pvData ) { // if the dialog window is not created, there is no message if( WAW_g_pclWatchWindow == NULL ) return; POSITION pos = WAW_g_clListOfUser.GetHeadPosition(); while( pos != NULL ) { WAW_hUserInfo hInfo = WAW_g_clListOfUser.GetNext( pos ); if( hInfo->m_pfnCallBack != NULL ) hInfo->m_pfnCallBack( _eMessage, _pvData ); } } CWnd * WAW_fn_pclGetWatchWindowDialog() { return (CWnd*)WAW_g_pclWatchWindow; } CWnd * WAW_fn_pclGetWatchWindowTree() { if( WAW_g_pclWatchWindow != NULL ) return (CWnd*)WAW_g_pclWatchWindow->m_pub_fn_pclGetTreeCtrl(); else return NULL; } //******************************* // Display the Watch Window //******************************* void WAW_fn_vDisplayWatchWindow() { WAW_fn_vSendMessage( WAW_eShowWindow, NULL ); WAW_g_pclWatchWindow->ShowWindow( TRUE ); } void WAW_fn_vHideWatchWindow() { WAW_fn_vSendMessage( WAW_eHideWindow, NULL ); WAW_g_pclWatchWindow->ShowWindow( FALSE ); } void WAW_fn_vSetWatchWindowTopMost( BOOL _bTopMost ) { if( _bTopMost ) WAW_g_pclWatchWindow->SetWindowPos( &CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); else WAW_g_pclWatchWindow->SetWindowPos( &CWnd::wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); } WAW_hUserInfo WAW_fn_hFindInfo( CString _csUserModuleName ) { BOOL bExist = FALSE; WAW_hUserInfo hUserInfo = NULL; POSITION pos = WAW_g_clListOfUser.GetHeadPosition(); while( (pos != NULL) && (!bExist) ) { hUserInfo = WAW_g_clListOfUser.GetNext( pos ); bExist = ( hUserInfo->m_csUserModuleName == _csUserModuleName ); } if( bExist ) return hUserInfo; else return NULL; } //*************************************************************************************** // Register module using the Watch Window // // Input : _csUserModuleName, a name to identify the module // _pfnCallBack, the CallBack used by the Watch Window to communicate // // Output : Handle of User Information, usefull to identify Module when it will add Data //*************************************************************************************** WAW_hUserInfo WAW_fn_hUserRegister( CString _csUserModuleName, WAW_CallBack _pfnCallBack) { WAW_hUserInfo hUserInfo = WAW_fn_hFindInfo( _csUserModuleName ); if( hUserInfo != NULL ) return hUserInfo; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Register new user for Watch Window", "WAW_fn_vUserRegister", E_ERROR_GRAVITY_INSTABLE, "The new User is not allocated" ); WAW_tdstUserInfo * pstInfo = new WAW_tdstUserInfo; ERROR_ASSERT( pstInfo != NULL ); pstInfo->m_csUserModuleName = _csUserModuleName; pstInfo->m_pfnCallBack = _pfnCallBack; WAW_g_clListOfUser.AddTail( pstInfo ); return pstInfo; } //************************************************************************************************* // Add a Data in the Watch Window // // Input : _hInfo, the handle of user info given when the user registered // _pclParentData, the parent of the data to add // _csDataName, the name of the added data // _csDataValue, a string representing the value of the added data // _pvUserData, a pointer to a possibly usefull data for the user // // Outpout : a pointer to the WAW_Data added or NULL if a problem is encounted //************************************************************************************************* WAW_Data * WAW_fn_pclAddData( CString _csUserModuleName, WAW_Data * _pclParentData, CString _csDataName, CString _csDataValue, void *_pvUserData ) { WAW_hUserInfo hInfo = WAW_fn_hFindInfo( _csUserModuleName ); if( hInfo != NULL ) return WAW_fn_pclAddData( hInfo, _pclParentData, _csDataName, _csDataValue, _pvUserData ); else return NULL; } WAW_Data * WAW_fn_pclAddData( WAW_hUserInfo _hInfo, WAW_Data * _pclParentData, CString _csDataName, CString _csDataValue, void *_pvUserData ) { ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Add Data in Watch Window", "WAW_fn_pclAddData", E_ERROR_GRAVITY_INSTABLE, "The WAW_hUserInfo is invalid" ); ERROR_ASSERT( WAW_M_bCheckInfo( _hInfo ) ); if( !WAW_M_bCheckInfo( _hInfo ) ) return NULL; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Add Data in Watch Window", "WAW_fn_pclAddData", E_ERROR_GRAVITY_INSTABLE, "The new Data is not allocated" ); WAW_Data *pclData = new WAW_Data( _csDataName, _csDataValue, _hInfo, _pvUserData ); ERROR_ASSERT( pclData != NULL ); if( pclData == NULL ) return NULL; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Add Data in Watch Window", "WAW_fn_pclAddData", E_ERROR_GRAVITY_INSTABLE, "The pointer to CTreeCtrl is NULL" ); CTreeCtrl * pclTreeCtrl = WAW_g_pclWatchWindow->m_pub_fn_pclGetTreeCtrl(); ERROR_ASSERT( pclTreeCtrl != NULL ); if( pclTreeCtrl == NULL ) return NULL; HTREEITEM hParentItem = ( _pclParentData == NULL ? NULL : _pclParentData->m_pri_hTreeItem ); HTREEITEM hChildItem = pclTreeCtrl->GetChildItem( hParentItem ); while( hChildItem != NULL ) { if( ((WAW_Data*)pclTreeCtrl->GetItemData( hChildItem ))->m_pub_fn_csGetDataName() == _csDataName ) return (WAW_Data*)pclTreeCtrl->GetItemData( hChildItem ); hChildItem = pclTreeCtrl->GetNextItem( hChildItem, TVGN_NEXT ); } if( hParentItem == NULL ) hParentItem = TVI_ROOT; TV_INSERTSTRUCT stItem; stItem.hParent = hParentItem; stItem.hInsertAfter = TVI_LAST; stItem.item.mask = TVIF_TEXT | TVIF_STATE; CString csDataString = _csDataName + " : " + _csDataValue; stItem.item.pszText = (char*)LPCTSTR( csDataString ); stItem.item.state = TVIS_EXPANDED; stItem.item.stateMask = TVIS_EXPANDED; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Add Data in Watch Window", "WAW_fn_pclAddData", E_ERROR_GRAVITY_INSTABLE, "The new subitem is not added in CTree" ); HTREEITEM hItem = pclTreeCtrl->InsertItem( &stItem ); ERROR_ASSERT( hItem != NULL ); if( hItem == NULL ) return NULL; pclData->m_pri_hTreeItem = hItem; pclTreeCtrl->SetItemData( hItem, (DWORD)pclData ); return pclData; } //************************************************************************************************* // Add a Node in the Watch Window // // Input : _hInfo, the handle of user info given when the user registered // _pclParentData, the parent of the node to add // _csDataName, the name of the added node // _pvUserData, a pointer to a possibly usefull data for the user // // Outpout : a pointer to the WAW_Data added or NULL if a problem is encounted // //************************************************************************************************* WAW_Data * WAW_fn_pclAddNode( CString _csUserModuleName, WAW_Data * _pclParentData, CString _csNodeName, void *_pvUserData ) { WAW_hUserInfo hInfo = WAW_fn_hFindInfo( _csUserModuleName ); if( hInfo != NULL ) return WAW_fn_pclAddNode( hInfo, _pclParentData, _csNodeName, _pvUserData ); else return NULL; } WAW_Data * WAW_fn_pclAddNode( WAW_hUserInfo _hInfo, WAW_Data * _pclParentData, CString _csNodeName, void *_pvUserData ) { ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Add Node in Watch Window", "WAW_fn_pclAddNode", E_ERROR_GRAVITY_INSTABLE, "The WAW_hUserInfo is invalid" ); ERROR_ASSERT( WAW_M_bCheckInfo( _hInfo ) ); if( !WAW_M_bCheckInfo( _hInfo ) ) return NULL; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Add Node in Watch Window", "WAW_fn_pclAddNode", E_ERROR_GRAVITY_INSTABLE, "The new Node is not allocated" ); WAW_Data *pclData = new WAW_Data( _csNodeName, "", _hInfo, _pvUserData ); ERROR_ASSERT( pclData != NULL ); if( pclData == NULL ) return NULL; pclData->m_pri_bIsData = FALSE; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Add Node in Watch Window", "WAW_fn_pclAddNode", E_ERROR_GRAVITY_INSTABLE, "The pointer to CTreeCtrl is NULL" ); CTreeCtrl * pclTreeCtrl = WAW_g_pclWatchWindow->m_pub_fn_pclGetTreeCtrl(); ERROR_ASSERT( pclTreeCtrl != NULL ); if( pclTreeCtrl == NULL ) return NULL; HTREEITEM hParentItem = ( _pclParentData == NULL ? NULL : _pclParentData->m_pri_hTreeItem ); HTREEITEM hChildItem = pclTreeCtrl->GetChildItem( hParentItem ); while( hChildItem != NULL ) { if( ((WAW_Data*)pclTreeCtrl->GetItemData( hChildItem ))->m_pub_fn_csGetDataName() == _csNodeName ) return (WAW_Data*)pclTreeCtrl->GetItemData( hChildItem ); hChildItem = pclTreeCtrl->GetNextItem( hChildItem, TVGN_NEXT ); } if( hParentItem == NULL ) hParentItem = TVI_ROOT; TV_INSERTSTRUCT stItem; stItem.hParent = hParentItem; stItem.hInsertAfter = TVI_LAST; stItem.item.mask = TVIF_TEXT | TVIF_STATE; stItem.item.pszText = (char*)LPCTSTR( _csNodeName ); stItem.item.state = TVIS_EXPANDED; stItem.item.stateMask = TVIS_EXPANDED; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Add Node in Watch Window", "WAW_fn_pclAddNode", E_ERROR_GRAVITY_INSTABLE, "The new subitem is not added in CTree" ); HTREEITEM hItem = pclTreeCtrl->InsertItem( &stItem ); ERROR_ASSERT( hItem != NULL ); if( hItem == NULL ) return NULL; pclData->m_pri_hTreeItem = hItem; pclTreeCtrl->SetItemData( hItem, (DWORD)pclData ); return pclData; } //***************************************************************************** // Update the value of a Data placed in the Watch Window // // Input : _pclData, a pointer to the Data to update // _csDataValue, a string representing the new value of the Data // // Output : TRUE if succesfull, otherwise FALSE //***************************************************************************** BOOL WAW_fn_bUpdateData( WAW_Data * _pclData, CString _csDataValue ) { ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Update Data in Watch Window", "WAW_fn_bUpdateData", E_ERROR_GRAVITY_WARNING, "The Data to update is NULL : operation aborted" ); ERROR_ASSERT( _pclData != NULL ); if( _pclData == NULL ) return FALSE; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Update Data in Watch Window", "WAW_fn_pclUpdateData", E_ERROR_GRAVITY_INSTABLE, "The pointer to CTreeCtrl is NULL" ); CTreeCtrl * pclTreeCtrl = WAW_g_pclWatchWindow->m_pub_fn_pclGetTreeCtrl(); ERROR_ASSERT( pclTreeCtrl != NULL ); if( pclTreeCtrl == NULL ) return NULL; if( _pclData->m_pri_csDataValue != _csDataValue ) { CString csDataString = _pclData->m_pub_fn_csGetDataName() + " : " + _csDataValue; BOOL bOk = pclTreeCtrl->SetItemText( _pclData->m_pri_hTreeItem, (char*)LPCTSTR( csDataString ) ); if( bOk ) _pclData->m_pri_csDataValue = _csDataValue; return bOk; } return TRUE; } //********************************************************* // Delete a specific Data from the Watch Window // // Input : _pclData, the pointer to the Data to delete // // Output : TRUE if successfull, otherwise FALSE //********************************************************* BOOL WAW_fn_bDeleteData( WAW_Data *_pclData ) { WAW_g_bAcceptMessage = FALSE; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Remove a Data from the Watch Window", "WAW_fn_bRemoveData", E_ERROR_GRAVITY_WARNING, "The Data to remove is NULL : operation aborted" ); ERROR_ASSERT( _pclData != NULL ); if( _pclData == NULL ) return FALSE; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Remove a Data from the Watch Window", "WAW_fn_bRemoveData", E_ERROR_GRAVITY_INSTABLE, "The pointer to CTreeCtrl is NULL" ); CTreeCtrl * pclTreeCtrl = WAW_g_pclWatchWindow->m_pub_fn_pclGetTreeCtrl(); ERROR_ASSERT( pclTreeCtrl != NULL ); if( pclTreeCtrl == NULL ) return FALSE; HTREEITEM hParentItem = pclTreeCtrl->GetParentItem( _pclData->m_pri_hTreeItem ); ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Remove a Data from the Watch Window", "WAW_fn_bRemoveData", E_ERROR_GRAVITY_WARNING, "The Data to remove is not deleted in CTreeCtrl" ); BOOL bOk = pclTreeCtrl->DeleteItem( _pclData->m_pri_hTreeItem ); ERROR_ASSERT( bOk ); delete _pclData; WAW_g_bAcceptMessage = TRUE; if( hParentItem != NULL ) return WAW_fn_bCheckForEmptyNode( hParentItem ); else return bOk; } BOOL WAW_fn_bCheckForEmptyNode( HTREEITEM _hItem ) { ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Check if the parent of a deleted data must be deleted", "WAW_fn_bCheckForEmptyNode", E_ERROR_GRAVITY_INSTABLE, "The pointer to CTreeCtrl is NULL" ); CTreeCtrl * pclTreeCtrl = WAW_g_pclWatchWindow->m_pub_fn_pclGetTreeCtrl(); ERROR_ASSERT( pclTreeCtrl != NULL ); if( pclTreeCtrl == NULL ) return FALSE; WAW_Data * pclData = (WAW_Data*)pclTreeCtrl->GetItemData( _hItem ); if( pclData->m_pri_bIsData || pclTreeCtrl->ItemHasChildren( _hItem ) ) return TRUE; else return WAW_fn_bDeleteData( pclData ); } BOOL WAW_fn_bSetDataIcon( WAW_Data * _pclData, HICON _hIcon, HICON _hSelectedIcon ) { ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Associate an icon to a data", "WAW_fn_bSetDataIcon", E_ERROR_GRAVITY_WARNING, "The Data is NULL : operation aborted" ); ERROR_ASSERT( _pclData != NULL ); if( _pclData == NULL ) return FALSE; ERROR_PREPARE_M( WAW_g_C_csModuleNameForError, "Associate an icon to a data", "WAW_fn_bSetDataIcon", E_ERROR_GRAVITY_INSTABLE, "The pointer to CTreeCtrl is NULL" ); CTreeCtrl * pclTreeCtrl = WAW_g_pclWatchWindow->m_pub_fn_pclGetTreeCtrl(); ERROR_ASSERT( pclTreeCtrl != NULL ); if( pclTreeCtrl == NULL ) return NULL; int iIndex = WAW_g_pclImageList->Add( _hIcon ); if( iIndex == -1 ) return FALSE; int iSelectedIndex = (_hSelectedIcon != NULL ? WAW_g_pclImageList->Add( _hSelectedIcon ) : iIndex ); if( iSelectedIndex == -1 ) return FALSE; return pclTreeCtrl->SetItemImage( _pclData->m_pri_hTreeItem, iIndex, iSelectedIndex ); }