851 lines
27 KiB
C++
851 lines
27 KiB
C++
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<iNbSel ; i++)
|
|
{
|
|
SendMessage (p_stWndDefinition -> 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<iNbSel ; i++)
|
|
{
|
|
SendMessage (p_stWndDefinition -> 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<HMENU,HMENU> 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;
|
|
}
|
|
|
|
|