const CString TUT_gs_csPause = ";"; // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void TUT_CTutorialManager::m_fn_vStartRecord (HMODULE _hModule, DWORD _dThreadID) { m_oListOfCommands . RemoveAll (); m_fn_bStartStopHook (_hModule , _dThreadID , TRUE); m_xLastCommandTime = clock (); m_bInPause = TRUE; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void TUT_CTutorialManager::m_fn_vStopRecord (HMODULE _hModule, DWORD _dThreadID, LPCTSTR _szFileName) { m_fn_bStartStopHook (_hModule , _dThreadID , FALSE); m_fn_vDeleteLastCommand (); if (_szFileName) { FILE *pFile = fopen (_szFileName , "wt"); if (pFile) { while (m_oListOfCommands . GetCount ()) { CString csCommand = m_oListOfCommands . RemoveHead (); /*if (csCommand != TUT_gs_csPause)*/ fprintf (pFile , "%s\n" , csCommand); } fclose (pFile); } } // remove list while (m_oListOfCommands . GetCount ()) m_oListOfCommands . RemoveHead (); } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ #define TUT_M_vSetHookProc(hFunc,iHookType,szHookFuncName,hModule,hThreadID)\ if (!hFunc)\ {\ if (!(hFunc = SetWindowsHookEx(iHookType,(HOOKPROC)GetProcAddress(hModule, szHookFuncName), hModule, hThreadID)))\ {\ return FALSE;\ }\ } #define TUT_M_vUnsetHookProc(hFunc)\ if (hFunc)\ {\ UnhookWindowsHookEx(hFunc);\ hFunc = NULL;\ } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ BOOL TUT_CTutorialManager::m_fn_bStartStopHook (HMODULE _hModule, DWORD _dThreadID, BOOL _bStart) { static HHOOK hhkGetMessage = NULL; static HHOOK hhkCallWndProc = NULL; static HHOOK hhkCallWndProcRet = NULL; if (_bStart) { TUT_M_vSetHookProc(hhkGetMessage, WH_GETMESSAGE, "SpyGetMsgProc", _hModule,_dThreadID); TUT_M_vSetHookProc(hhkCallWndProc, WH_CALLWNDPROC, "SpyGetWndProc", _hModule,_dThreadID); TUT_M_vSetHookProc(hhkCallWndProcRet, WH_CALLWNDPROCRET, "SpyGetWndProcRet", _hModule,_dThreadID); } else { TUT_M_vUnsetHookProc(hhkGetMessage); TUT_M_vUnsetHookProc(hhkCallWndProc); TUT_M_vUnsetHookProc(hhkCallWndProcRet); } return TRUE; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ #define TUT_M_HandleMsg(iType,uiMess,Func) case uiMess: return Func(iType, hwnd , uiMessage , wParam , lParam); // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ BOOL TUT_CTutorialManager::m_fn_bHookMsgProc (HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) { m_fn_vHandlePause (); switch (uiMessage) { TUT_M_HandleMsg(WH_GETMESSAGE, WM_RBUTTONDOWN, m_fn_bRButtonMsgProc) TUT_M_HandleMsg(WH_GETMESSAGE, WM_LBUTTONUP, m_fn_bLButtonMsgProc) TUT_M_HandleMsg(WH_GETMESSAGE, WM_LBUTTONDOWN, m_fn_bLButtonMsgProc) TUT_M_HandleMsg(WH_GETMESSAGE, WM_LBUTTONDBLCLK, m_fn_bLButtonMsgProc) TUT_M_HandleMsg(WH_GETMESSAGE, WM_MOUSEMOVE, m_fn_bMouseMsgProc) default : break; } return FALSE; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ BOOL TUT_CTutorialManager::m_fn_bHookWndProc (HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) { m_fn_vHandlePause (); switch (uiMessage) { TUT_M_HandleMsg(WH_CALLWNDPROC, WM_COMMAND, m_fn_bCommandMsgProc) TUT_M_HandleMsg(WH_CALLWNDPROC, WM_KILLFOCUS, m_fn_bFocusMsgProc) TUT_M_HandleMsg(WH_CALLWNDPROC, WM_NOTIFY, m_fn_bNotifyMsgProc) TUT_M_HandleMsg(WH_CALLWNDPROC, WM_INITMENU, m_fn_bMenuMsgProc) TUT_M_HandleMsg(WH_CALLWNDPROC, WM_INITMENUPOPUP, m_fn_bMenuMsgProc) TUT_M_HandleMsg(WH_CALLWNDPROC, WM_MENUSELECT, m_fn_bMenuMsgProc) TUT_M_HandleMsg(WH_CALLWNDPROC, WM_EXITMENULOOP, m_fn_bMenuMsgProc) TUT_M_HandleMsg(WH_CALLWNDPROC, WM_MOUSEMOVE, m_fn_bMouseMsgProc) default : break; } return FALSE; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ BOOL TUT_CTutorialManager::m_fn_bHookWndProcRet (HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) { m_fn_vHandlePause (); switch (uiMessage) { default : break; } return FALSE; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void TUT_CTutorialManager::m_fn_vHandlePause () { clock_t xDuration = clock () - m_xLastCommandTime; if (!m_bInPause && xDuration > TUT_C_xPauseIntervall) { xDuration = TUT_C_xPauseIntervall; m_fn_vAddPause (); } } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void TUT_CTutorialManager::m_fn_vAddCommand (CString csCommand) { m_oListOfCommands . AddTail (csCommand); m_bInPause = FALSE; m_xLastCommandTime = clock (); } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void TUT_CTutorialManager::m_fn_vInsertAfterPause (CString csCommand) { POSITION xPos; xPos = m_oListOfCommands . GetTailPosition (); while (xPos && m_oListOfCommands . GetAt (xPos) != TUT_gs_csPause) { m_oListOfCommands . GetPrev (xPos); } if (xPos) { m_oListOfCommands . InsertBefore (xPos , csCommand); } else { m_oListOfCommands . AddTail (csCommand); } m_bInPause = FALSE; m_xLastCommandTime = clock (); } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void TUT_CTutorialManager::m_fn_vAddPause (void) { m_oListOfCommands . AddTail (TUT_gs_csPause); m_bInPause = TRUE; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void TUT_CTutorialManager::m_fn_vRemoveToPause (void) { while (!m_oListOfCommands . IsEmpty () && m_oListOfCommands . GetTail () != TUT_gs_csPause) { m_oListOfCommands . RemoveTail (); } m_bInPause = TRUE; m_xLastCommandTime = clock (); } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ BOOL TUT_CTutorialManager::m_fn_bHaveSomethingAfterPause (void) { return (m_oListOfCommands . GetCount () && m_oListOfCommands . GetTail () != TUT_gs_csPause); } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void TUT_CTutorialManager::m_fn_vDeleteLastCommand (void) { // delete last Pause commands while (!m_oListOfCommands . IsEmpty () && m_oListOfCommands . GetTail () == TUT_gs_csPause) { m_oListOfCommands . RemoveTail (); } // delete last command m_fn_vRemoveToPause (); } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ #define TUT_M_bWND_VALID_AND_USABLE(p_stWndDefinition)\ ( (p_stWndDefinition) && (p_stWndDefinition) -> hWnd && IsWindowVisible((p_stWndDefinition) -> hWnd) ) #define TUT_M_ASSERT_WND_VALID_AND_USABLE(p_stWndDefinition)\ if (!TUT_M_bWND_VALID_AND_USABLE(p_stWndDefinition)) return FALSE; #define TUT_M_ASSERT_CURSOR_UNDER_CONTROL(hwnd)\ {\ RECT stRect;\ POINT xPoint;\ GetWindowRect (hwnd , &stRect);\ GetCursorPos (&xPoint);\ if (!PtInRect (&stRect , xPoint)) return FALSE;\ } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ BOOL TUT_CTutorialManager::m_fn_bCommandMsgProc (int /*iHookType*/, HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) { TUT_tdstWndDefinition *p_stWndDefinition = lParam ? m_fnp_stFindWndDefinition ((HWND)lParam) : NULL; UINT uiNotification = HIWORD(wParam); CString csText; TUT_M_ASSERT_WND_VALID_AND_USABLE(p_stWndDefinition); switch (p_stWndDefinition -> eType) { case TUT_eButton: { if (uiNotification == BN_CLICKED) { csText . Format ("%s(\"%s\")" , TUT_C_szClic , p_stWndDefinition -> csName); m_fn_vAddCommand (csText); return TRUE; } } break; case TUT_eListBox: { switch (uiNotification) { case LBN_SELCHANGE: { long lType = GetWindowLong (p_stWndDefinition -> hWnd, GWL_STYLE); if (! (lType & LBS_MULTIPLESEL) ) { int iCurSel = SendMessage (p_stWndDefinition -> hWnd, LB_GETCURSEL, 0, 0); if (iCurSel != LB_ERR) { char szText[255]; SendMessage (p_stWndDefinition -> hWnd, LB_GETTEXT, iCurSel, (DWORD)szText); csText . Format ("%s(\"%s\" , \"%s\")" , TUT_C_szSelect , p_stWndDefinition -> csName , szText); m_fn_vAddCommand (csText); return TRUE; } } } break; case LBN_DBLCLK: { if (m_oListOfCommands . GetCount () > 0) { csText . Format ("%s()" , TUT_C_szDoubleClic); m_fn_vInsertAfterPause (csText); return TRUE; } } break; } // switch (uiNotification) } break; case TUT_eComboBox: { switch (uiNotification) { case CBN_SELCHANGE: { int iCurSel = SendMessage (p_stWndDefinition -> hWnd, CB_GETCURSEL, 0, 0); if (iCurSel != CB_ERR) { char szText[255]; SendMessage (p_stWndDefinition -> hWnd, CB_GETLBTEXT, iCurSel, (DWORD)szText); csText . Format ("%s(\"%s\" , \"%s\")" , TUT_C_szSelect , p_stWndDefinition -> csName , szText); m_fn_vAddCommand (csText); return TRUE; } } break; case CBN_DBLCLK: { if (m_oListOfCommands . GetCount () > 0) { csText . Format ("%s()" , TUT_C_szDoubleClic); m_fn_vInsertAfterPause (csText); return TRUE; } } break; } // switch (uiNotification) } break; } // switch (p_stWndDefinition -> eType) return FALSE; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ CString gs_fn_csHandleQuoteInString (char *_szSourceText) { CString csResult; char *p_cBegin = _szSourceText; csResult . Empty (); while (*p_cBegin) { if (*p_cBegin == '\"') { csResult += "''"; } else { csResult += *p_cBegin; } p_cBegin ++; } return csResult; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ BOOL TUT_CTutorialManager::m_fn_bFocusMsgProc (int /*iHookType*/, HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) { if (uiMessage == WM_KILLFOCUS) { TUT_tdstWndDefinition *p_stWndDefinition = hwnd ? m_fnp_stFindWndDefinition (hwnd) : NULL; CString csText; TUT_M_ASSERT_WND_VALID_AND_USABLE(p_stWndDefinition); switch (p_stWndDefinition -> eType) { case TUT_eListBox: { long lType = GetWindowLong (p_stWndDefinition -> hWnd , GWL_STYLE); if (lType & LBS_MULTIPLESEL) { int iNbSel = SendMessage (p_stWndDefinition -> hWnd , LB_GETSELCOUNT , 0 , 0); if (iNbSel != LB_ERR) { int *a_iSelItems = (int*) alloca (iNbSel * sizeof (int)); if (SendMessage (p_stWndDefinition -> hWnd , LB_GETSELITEMS , iNbSel , (DWORD)a_iSelItems)) { char szText[255]; SendMessage (p_stWndDefinition -> hWnd , LB_GETTEXT , a_iSelItems [0] , (DWORD)szText); csText . Format ("%s(\"%s\" , \"%s\")" , TUT_C_szSelect , p_stWndDefinition -> csName , szText); m_fn_vAddCommand (csText); for (int i=1 ; i hWnd , LB_GETTEXT , a_iSelItems [i] , (DWORD)szText); csText . Format ("%s(\"%s\" , \"%s\")" , TUT_C_szAddSelect , p_stWndDefinition -> csName , szText); m_fn_vAddCommand (csText); } return TRUE; } } } } break; case TUT_eTextEdit: { long lType = GetWindowLong (p_stWndDefinition -> hWnd , GWL_STYLE); if (lType & ES_MULTILINE) { int iSize = GetWindowTextLength (p_stWndDefinition -> hWnd); char *szText = (char *) alloca (iSize+1); char szEndOfLine [3] = { 13 , 10 , 0 }; char *p_cBegin , *p_cEnd; int iLineNumber; // clear control csText . Format ("%s(0,0,0,0)" , TUT_C_szSelectText); m_fn_vAddCommand (csText); GetWindowText (p_stWndDefinition -> hWnd , szText , iSize + 1); p_cBegin = szText; iLineNumber = 0; p_cEnd = strstr (p_cBegin , szEndOfLine); while (p_cEnd) { *p_cEnd = 0; if (p_cEnd != p_cBegin) { csText . Format ("%s(\"%s\" , \"%s\" , %d)" , TUT_C_szSetEditText , p_stWndDefinition -> csName , gs_fn_csHandleQuoteInString (p_cBegin) , iLineNumber); m_fn_vAddCommand (csText); } // p_cBegin = p_cEnd + 2; iLineNumber ++; p_cEnd = strstr (p_cBegin , szEndOfLine); } if (*p_cBegin) { csText . Format ("%s(\"%s\" , \"%s\" , %d)" , TUT_C_szSetEditText , p_stWndDefinition -> csName , gs_fn_csHandleQuoteInString (p_cBegin) , iLineNumber); m_fn_vAddCommand (csText); } return TRUE; } else { int iSize = GetWindowTextLength (p_stWndDefinition -> hWnd); char *szText = (char *) alloca (iSize+1); if (GetWindowText (p_stWndDefinition -> hWnd , szText , iSize+1)) { csText . Format ("%s(\"%s\" , \"%s\")" , TUT_C_szSetEditText , p_stWndDefinition -> csName , gs_fn_csHandleQuoteInString (szText)); m_fn_vAddCommand (csText); return TRUE; } } } break; } // switch (p_stWndDefinition -> eType) } return FALSE; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ BOOL TUT_CTutorialManager::m_fn_bNotifyMsgProc (int iHookType, HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) { LPNMHDR pnmh = (LPNMHDR) lParam; TUT_tdstWndDefinition *p_stWndDefinition = (pnmh && pnmh -> hwndFrom) ? m_fnp_stFindWndDefinition (pnmh -> hwndFrom) : NULL; CString csText; TUT_M_ASSERT_WND_VALID_AND_USABLE(p_stWndDefinition); TUT_M_ASSERT_CURSOR_UNDER_CONTROL(p_stWndDefinition -> hWnd); switch (p_stWndDefinition -> eType) { case TUT_eListBox: { uiMessage = uiMessage; } break; case TUT_eListCtrl: { NM_LISTVIEW *pnmv = (NM_LISTVIEW *) lParam; if (pnmv -> hdr . code == LVN_ITEMCHANGED) { if (pnmv -> iItem && pnmv -> uNewState == (LVIS_SELECTED|LVIS_FOCUSED)) { char szText[255]; ListView_GetItemText (p_stWndDefinition -> hWnd , pnmv -> iItem , 0 , szText , 255); csText . Format ("%s(\"%s\" , \"%s\")" , TUT_C_szSelect , p_stWndDefinition -> csName , szText); m_fn_vAddCommand (csText); return TRUE; } } } break; case TUT_eTreeCtrl: { NM_TREEVIEW *pnmtv = (NM_TREEVIEW *) lParam; switch (pnmtv -> hdr . code) { case TVN_SELCHANGED: { if (pnmtv -> itemNew . mask & TVIF_STATE && pnmtv -> itemNew . state & TVIS_SELECTED) { char szText[255]; pnmtv -> itemNew . pszText = szText; pnmtv -> itemNew . cchTextMax = 255; pnmtv -> itemNew . mask = TVIF_TEXT; if (TreeView_GetItem (p_stWndDefinition -> hWnd , & pnmtv -> itemNew)) { csText . Format ("%s(\"%s\" , \"%s\")" , TUT_C_szSelect , p_stWndDefinition -> csName , szText); m_fn_vAddCommand (csText); return TRUE; } } } break; case TVN_ITEMEXPANDED: { if (pnmtv -> itemNew . mask & TVIF_STATE) { BOOL bExpanded = (pnmtv -> itemNew . state & TVIS_EXPANDED) ? TRUE : FALSE; char szText[255]; pnmtv -> itemNew . pszText = szText; pnmtv -> itemNew . cchTextMax = 255; pnmtv -> itemNew . mask = TVIF_TEXT; if (TreeView_GetItem (p_stWndDefinition -> hWnd , & pnmtv -> itemNew)) { csText . Format ("%s(\"%s\" , \"%s\")" , bExpanded ? TUT_C_szExpand : TUT_C_szCollapse , p_stWndDefinition -> csName , szText); m_fn_vAddCommand (csText); return TRUE; } } } break; } // switch (pnmtv -> hdr . code) } break; } // switch (p_stWndDefinition -> eType) return FALSE; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ BOOL TUT_CTutorialManager::m_fn_bLButtonMsgProc (int iHookType, HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) { switch (iHookType) { case WH_CALLWNDPROCRET: case WH_GETMESSAGE: { switch (uiMessage) { case WM_LBUTTONDOWN: { TUT_tdstWndDefinition *p_stWndDefinition = hwnd ? m_fnp_stFindWndDefinition (hwnd) : NULL; if (p_stWndDefinition == NULL && m_fn_bIsModelView (hwnd)) { return m_fn_bLButtonDownModelViewProc (iHookType, hwnd, uiMessage, wParam, lParam); } TUT_M_ASSERT_WND_VALID_AND_USABLE(p_stWndDefinition); m_csDragDropElement . Empty (); m_lDragDrop = 0; switch (p_stWndDefinition -> eType) { case TUT_e3DView: { return m_fn_bLButtonDown3DViewProc (iHookType, hwnd, uiMessage, wParam, lParam); } break; } } break; case WM_LBUTTONUP: { TUT_tdstWndDefinition *p_stWndDefinition = hwnd ? m_fnp_stFindWndDefinition (hwnd) : NULL; if (p_stWndDefinition == NULL && m_fn_bIsModelView (hwnd)) { return m_fn_bLButtonUpModelViewProc (iHookType, hwnd, uiMessage, wParam, lParam); } TUT_M_ASSERT_WND_VALID_AND_USABLE(p_stWndDefinition); switch (p_stWndDefinition -> eType) { case TUT_e3DView: { return m_fn_bLButtonUp3DViewProc (iHookType, hwnd, uiMessage, wParam, lParam); } break; } m_csDragDropElement . Empty (); m_lDragDrop = 0; } break; case WM_LBUTTONDBLCLK: { if (m_fn_bHaveSomethingAfterPause ()) { CString csText; csText . Format ("%s()" , TUT_C_szDoubleClic); m_fn_vInsertAfterPause (csText); return TRUE; } } break; } // switch (uiMessage) } break; } // switch (iHookType) return FALSE; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ BOOL TUT_CTutorialManager::m_fn_bMouseMsgProc (int iHookType, HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) { switch (uiMessage) { case WM_MOUSEMOVE: { if (m_lDragDrop > 0) m_lDragDrop++; } break; } return FALSE; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ BOOL TUT_CTutorialManager::m_fn_bRButtonMsgProc (int iHookType, HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) { switch (uiMessage) { case WM_RBUTTONDOWN: { TUT_tdstWndDefinition *p_stWndDefinition = hwnd ? m_fnp_stFindWndDefinition (hwnd) : NULL; CString csText; TUT_M_ASSERT_WND_VALID_AND_USABLE(p_stWndDefinition); switch (p_stWndDefinition -> eType) { case TUT_e3DView: { csText . Format ("%s()" , TUT_C_szRightButton); m_fn_vAddCommand (csText); return TRUE; } break; case TUT_eListBox: { long lType = GetWindowLong (p_stWndDefinition -> hWnd , GWL_STYLE); if (lType & LBS_MULTIPLESEL) { int iNbSel = SendMessage (p_stWndDefinition -> hWnd , LB_GETSELCOUNT , 0 , 0); if (iNbSel != LB_ERR) { int *a_iSelItems = (int*) alloca (iNbSel * sizeof (int)); if (SendMessage (p_stWndDefinition -> hWnd , LB_GETSELITEMS , iNbSel , (DWORD)a_iSelItems)) { char szText[255]; SendMessage (p_stWndDefinition -> hWnd , LB_GETTEXT , a_iSelItems [0] , (DWORD)szText); csText . Format ("%s(\"%s\" , \"%s\")" , TUT_C_szSelect , p_stWndDefinition -> csName , szText); m_fn_vAddCommand (csText); for (int i=1 ; i hWnd , LB_GETTEXT , a_iSelItems [i] , (DWORD)szText); csText . Format ("%s(\"%s\" , \"%s\")" , TUT_C_szAddSelect , p_stWndDefinition -> csName , szText); m_fn_vAddCommand (csText); } } } } } // no break here default: { csText . Format ("%s()" , TUT_C_szRightButton); m_fn_vAddCommand (csText); csText . Format ("%s(\"%s\")" , TUT_C_szClic , p_stWndDefinition -> csName); m_fn_vAddCommand (csText); } break; } // switch (p_stWndDefinition -> eType) // } break; } // switch (uiMessage) return FALSE; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void gs_fn_vCleanMenuName(char *_szName) { char *p_cSource = _szName; char *p_cTarget = _szName; while (*p_cSource) { if (*p_cSource == '\t') break; if (*p_cSource != '&') { *p_cTarget++ = *p_cSource; } p_cSource++; } *p_cTarget = 0; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ BOOL TUT_CTutorialManager::m_fn_bMenuMsgProc (int /*iHookType*/, HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) { static CStringList s_oListOfMenuNames; static CList s_oListOfMenuHandles; static char s_oCurrentMenuName[255]; static HMENU hCurrentMenu; static HMENU hNextMenu; static BOOL bLastIsAnEntry; CString csText; switch (uiMessage) { case WM_INITMENU: { s_oListOfMenuNames . RemoveAll (); s_oListOfMenuHandles . RemoveAll (); *s_oCurrentMenuName = 0; hCurrentMenu = (HMENU)wParam; hNextMenu = NULL; bLastIsAnEntry = FALSE; } break; case WM_INITMENUPOPUP: { hNextMenu = (HMENU) wParam; } break; case WM_MENUSELECT: { UINT uItem = (UINT) LOWORD(wParam); // menu item or submenu index UINT fuFlags = (UINT) HIWORD(wParam); // menu flags HMENU hmenu = (HMENU) lParam; // handle of menu clicked UINT uiFlag = (fuFlags & MF_POPUP) ? MF_BYPOSITION : MF_BYCOMMAND; csText = "WM_MENUSELECT : "; if (fuFlags == 0xFFFF) { if (!bLastIsAnEntry) { while (s_oListOfMenuNames . GetCount()) s_oListOfMenuNames . RemoveHead (); while (s_oListOfMenuHandles . GetCount()) s_oListOfMenuHandles . RemoveHead (); *s_oCurrentMenuName = 0; csText += "Clear all"; } else { s_oListOfMenuNames . AddTail (s_oCurrentMenuName); csText += "End"; } } else if (hmenu == hCurrentMenu) { GetMenuString (hmenu , uItem , s_oCurrentMenuName , 255 , uiFlag); gs_fn_vCleanMenuName (s_oCurrentMenuName); bLastIsAnEntry = (fuFlags & MF_POPUP) ? FALSE : TRUE; csText += "Current => " + CString(s_oCurrentMenuName); } else if (hmenu == hNextMenu) { s_oListOfMenuHandles . AddTail (hCurrentMenu); s_oListOfMenuNames . AddTail (s_oCurrentMenuName); GetMenuString (hmenu , uItem , s_oCurrentMenuName , 255 , uiFlag); gs_fn_vCleanMenuName (s_oCurrentMenuName); hCurrentMenu = hNextMenu; hNextMenu = NULL; bLastIsAnEntry = (fuFlags & MF_POPUP) ? FALSE : TRUE; csText += "Next => " + CString(s_oCurrentMenuName); } else { if (s_oListOfMenuNames . GetCount()) s_oListOfMenuNames . RemoveTail (); while (s_oListOfMenuHandles . GetCount() && (s_oListOfMenuHandles . GetTail () != hmenu)) { s_oListOfMenuHandles . RemoveTail (); if (s_oListOfMenuNames . GetCount()) s_oListOfMenuNames . RemoveTail (); } if (s_oListOfMenuHandles . GetCount()) s_oListOfMenuHandles . RemoveTail (); hCurrentMenu = hmenu; hNextMenu = NULL; GetMenuString (hmenu , uItem , s_oCurrentMenuName , 255 , uiFlag); gs_fn_vCleanMenuName (s_oCurrentMenuName); bLastIsAnEntry = (fuFlags & MF_POPUP) ? FALSE : TRUE; csText += "Back => " + CString(s_oCurrentMenuName); } } break; case WM_EXITMENULOOP: { while (s_oListOfMenuHandles . GetCount()) s_oListOfMenuHandles . RemoveHead (); if (s_oListOfMenuNames . GetCount()) { ASSERT(bLastIsAnEntry); csText . Format ("%s(\"%s\"" , wParam ? TUT_C_szPopupMenu : TUT_C_szMenu , s_oListOfMenuNames . RemoveHead ()); while (s_oListOfMenuNames . GetCount()) { csText = csText + " , \"" + s_oListOfMenuNames . RemoveHead () + "\""; } csText += ")"; m_fn_vAddCommand (csText); return TRUE; } } break; } return FALSE; }