1617 lines
70 KiB
PHP
1617 lines
70 KiB
PHP
|
||
/******************************************************************************
|
||
* *
|
||
* Tut_Mngr.cpp : definition of the low level functions of the *
|
||
* TUT_CTutorialManager class *
|
||
* *
|
||
* This class can take the control of all windows of the application *
|
||
* to create a tutorial or an automatic test *
|
||
* *
|
||
* Author : Alexis Vaisse *
|
||
* *
|
||
******************************************************************************/
|
||
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_csGetTreeCtrlItemText
|
||
// Get the text of one item of a tree ctrl
|
||
//-----------------------------------------------------------------------------
|
||
CString TUT_CTutorialManager::m_fn_csGetTreeCtrlItemText (HWND _hTreeCtrl , HTREEITEM _hItem)
|
||
{
|
||
char szBuffer [256];
|
||
* szBuffer = 0;
|
||
TV_ITEM Item;
|
||
Item . mask = TVIF_TEXT;
|
||
Item . hItem = _hItem;
|
||
Item . pszText = szBuffer;
|
||
Item . cchTextMax = 255;
|
||
TreeView_GetItem (_hTreeCtrl , & Item);
|
||
return szBuffer;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_uiGetTreeCtrlState
|
||
// Get the state of one item of a tree ctrl
|
||
//-----------------------------------------------------------------------------
|
||
UINT TUT_CTutorialManager::m_fn_uiGetTreeCtrlState (HWND _hTreeCtrl , HTREEITEM _hItem , UINT _uiFlag)
|
||
{
|
||
TV_ITEM Item;
|
||
Item . mask = TVIF_STATE;
|
||
Item . hItem = _hItem;
|
||
Item . stateMask = _uiFlag;
|
||
TreeView_GetItem (_hTreeCtrl , & Item);
|
||
return Item . state;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_hFindStringInTree
|
||
// Recursiv function to find a string into a tree
|
||
//-----------------------------------------------------------------------------
|
||
HTREEITEM TUT_CTutorialManager::m_fn_hFindStringInTree (HWND _hTreeCtrl , HTREEITEM _hItem , CString _csText)
|
||
{
|
||
while (_hItem)
|
||
{
|
||
// Is it the good item ?
|
||
if (m_fn_csGetTreeCtrlItemText (_hTreeCtrl , _hItem) == _csText) return _hItem;
|
||
|
||
// Get the first child and recursiv call
|
||
HTREEITEM _hChildItem = TreeView_GetChild (_hTreeCtrl , _hItem);
|
||
if (_hChildItem)
|
||
{
|
||
HTREEITEM hResultItem = m_fn_hFindStringInTree (_hTreeCtrl , _hChildItem , _csText);
|
||
if (hResultItem) return hResultItem;
|
||
}
|
||
|
||
// Get the next brother
|
||
_hItem = TreeView_GetNextItem (_hTreeCtrl , _hItem , TVGN_NEXT);
|
||
}
|
||
|
||
return NULL; // Not found
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_bIsItemVIsibleInTree
|
||
// Return TRUE if an item is visible in a tree
|
||
//-----------------------------------------------------------------------------
|
||
BOOL TUT_CTutorialManager::m_fn_bIsItemVisibleInTree (HWND _hTreeCtrl , HTREEITEM _hItemToFind)
|
||
{
|
||
HTREEITEM hItem = TreeView_GetFirstVisible (_hTreeCtrl);
|
||
|
||
while (hItem)
|
||
{
|
||
if (hItem == _hItemToFind) return TRUE;
|
||
hItem = TreeView_GetNextVisible (_hTreeCtrl , hItem);
|
||
}
|
||
|
||
return FALSE; // Not found
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_bSearchWndDefinition
|
||
// Search a window name into the list
|
||
//-----------------------------------------------------------------------------
|
||
BOOL TUT_CTutorialManager::m_fn_bSearchWndDefinition (const CString _csName , int *_p_iIndex /* = NULL */)
|
||
{
|
||
int iMin = -1;
|
||
int iMax = m_oArrayOfWnd . GetSize ();
|
||
int iMiddle = (iMin + iMax) >> 1;
|
||
int iComp;
|
||
BOOL bFound = FALSE;
|
||
TUT_tdstWndDefinition * p_stWndDefinition;
|
||
|
||
while (iMax != iMin + 1)
|
||
{
|
||
p_stWndDefinition = m_oArrayOfWnd [iMiddle];
|
||
iComp = p_stWndDefinition -> csName . CompareNoCase (_csName);
|
||
|
||
if (iComp == 0) // Found
|
||
{
|
||
if (_p_iIndex) * _p_iIndex = iMiddle;
|
||
return TRUE;
|
||
}
|
||
else
|
||
if (iComp == -1)
|
||
{
|
||
iMin = iMiddle;
|
||
iMiddle = (iMin + iMax) >> 1;
|
||
}
|
||
else
|
||
{
|
||
iMax = iMiddle;
|
||
iMiddle = (iMin + iMax) >> 1;
|
||
}
|
||
}
|
||
|
||
// Not found : we set the position where to insert the new window
|
||
if (_p_iIndex) * _p_iIndex = iMin;
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_bSearchWndDefinition
|
||
// Search a window name into the list
|
||
//-----------------------------------------------------------------------------
|
||
BOOL TUT_CTutorialManager::m_fn_bSearchWndDefinition (HWND _hWnd , int * _p_iIndex /*=NULL*/ )
|
||
{
|
||
int iMin = 0;
|
||
int iMax = m_oArrayOfWnd . GetSize ();
|
||
int iIndex;
|
||
TUT_tdstWndDefinition * p_stWndDefinition;
|
||
|
||
for (iIndex = iMin ; iIndex < iMax ; iIndex ++)
|
||
{
|
||
p_stWndDefinition = m_oArrayOfWnd [iIndex];
|
||
if (p_stWndDefinition -> hWnd == _hWnd) // Found
|
||
{
|
||
if (_p_iIndex) * _p_iIndex = iIndex;
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
// Not found : we set the position where to insert the new window
|
||
if (_p_iIndex) * _p_iIndex = -1;
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fnp_stFindWndDefinition
|
||
// Search a window name into the list
|
||
//-----------------------------------------------------------------------------
|
||
TUT_tdstWndDefinition * TUT_CTutorialManager::m_fnp_stFindWndDefinition (const CString _csName)
|
||
{
|
||
int iIndex;
|
||
return m_fn_bSearchWndDefinition (_csName , & iIndex) ? m_oArrayOfWnd [iIndex] : NULL;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fnp_stFindWndDefinition
|
||
// Search a window handle into the list
|
||
//-----------------------------------------------------------------------------
|
||
TUT_tdstWndDefinition * TUT_CTutorialManager::m_fnp_stFindWndDefinition (HWND _hWnd)
|
||
{
|
||
int iIndex;
|
||
return m_fn_bSearchWndDefinition (_hWnd , & iIndex) ? m_oArrayOfWnd [iIndex] : NULL;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fnp_stFindLabel
|
||
// Search a label name into the list
|
||
//-----------------------------------------------------------------------------
|
||
TUT_tdstLabelDefinition * TUT_CTutorialManager::m_fnp_stFindLabel (char * _szName)
|
||
{
|
||
int iCurrentContextNumber = m_oListOfContext . GetCount ();
|
||
POSITION Pos = m_oListOfLabel . GetHeadPosition ();
|
||
while (Pos)
|
||
{
|
||
TUT_tdstLabelDefinition * p_stLabelDef = m_oListOfLabel . GetNext (Pos);
|
||
if (p_stLabelDef -> csName . CompareNoCase (_szName) == 0 && p_stLabelDef -> iContextNumber == iCurrentContextNumber)
|
||
return p_stLabelDef;
|
||
}
|
||
|
||
return NULL; // Not found
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fnp_stFindVariable
|
||
// Search a variable name into the list
|
||
//-----------------------------------------------------------------------------
|
||
TUT_tdstVariableDefinition * TUT_CTutorialManager::m_fnp_stFindVariable (char * _szName)
|
||
{
|
||
BOOL bDeclareVariable;
|
||
if (* _szName == TUT_C_cDeclarationOfVariable)
|
||
{
|
||
bDeclareVariable = TRUE;
|
||
_szName ++;
|
||
}
|
||
else bDeclareVariable = FALSE;
|
||
|
||
int iCurrentContextNumber = m_oListOfContext . GetCount ();
|
||
POSITION Pos = m_oListOfVariable . GetHeadPosition ();
|
||
|
||
TUT_tdstVariableDefinition * p_stGlobalVariableDef = NULL;
|
||
|
||
while (Pos)
|
||
{
|
||
TUT_tdstVariableDefinition * p_stVariableDef = m_oListOfVariable . GetNext (Pos);
|
||
if (p_stVariableDef -> csName . CompareNoCase (_szName) == 0) // We have found a variable
|
||
{
|
||
if (p_stVariableDef -> iContextNumber == iCurrentContextNumber) // Is this variable a local variable ?
|
||
{
|
||
if (bDeclareVariable) return NULL; // Declaration of a already existing variable -> error
|
||
else return p_stVariableDef; // Ok
|
||
}
|
||
else
|
||
if (p_stVariableDef -> iContextNumber == 0) // Is this variable a global variable ?
|
||
{
|
||
p_stGlobalVariableDef = p_stVariableDef;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Here, we have not found a local variable
|
||
|
||
if (bDeclareVariable)
|
||
{
|
||
TUT_tdstVariableDefinition * p_stVariableDef = new TUT_tdstVariableDefinition;
|
||
m_oListOfVariable . AddTail (p_stVariableDef);
|
||
p_stVariableDef -> csName = _szName;
|
||
p_stVariableDef -> csValue = "";
|
||
p_stVariableDef -> iContextNumber = iCurrentContextNumber;
|
||
return p_stVariableDef;
|
||
}
|
||
else
|
||
{
|
||
if (p_stGlobalVariableDef) return p_stGlobalVariableDef;
|
||
else return NULL; // Not found
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fnp_stFindOrCreateVariable
|
||
// Search a variable name into the list. If it does not exist, create it
|
||
//-----------------------------------------------------------------------------
|
||
TUT_tdstVariableDefinition * TUT_CTutorialManager::m_fnp_stFindOrCreateVariable (char * _szName)
|
||
{
|
||
TUT_tdstVariableDefinition * p_stVariableDef = m_fnp_stFindVariable (_szName);
|
||
if (p_stVariableDef == NULL)
|
||
{
|
||
p_stVariableDef = new TUT_tdstVariableDefinition;
|
||
m_oListOfVariable . AddTail (p_stVariableDef);
|
||
p_stVariableDef -> csName = _szName;
|
||
p_stVariableDef -> csValue = "";
|
||
p_stVariableDef -> iContextNumber = m_oListOfContext . GetCount ();
|
||
}
|
||
|
||
return p_stVariableDef;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vSetValueToVariable
|
||
// Set a value to a variable
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vSetValueToVariable (TUT_tdstVariableDefinition * _p_stVariableDef , long _lValue)
|
||
{
|
||
_p_stVariableDef -> csValue . Format ("%d" , _lValue);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vSetGetLastError
|
||
// Put an error number into the GetLastError' global variable
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vSetGetLastError (long _lErrorNumber)
|
||
{
|
||
// Fill the GetLastError variable
|
||
TUT_tdstVariableDefinition * p_stVariableDef = m_fnp_stFindOrCreateVariable (TUT_C_szGetLastError);
|
||
m_fn_vSetValueToVariable (p_stVariableDef , _lErrorNumber);
|
||
|
||
// Fill the GetLastErrorMessage variable
|
||
char * szMessage;
|
||
switch (_lErrorNumber)
|
||
{
|
||
case TUT_C_iNoError : szMessage = "No error"; break;
|
||
case TUT_C_iError_ListBoxItemNotFound : szMessage = "Item not found in list box"; break;
|
||
case TUT_C_iError_ComboBoxItemNotFound : szMessage = "Item not found in combo box"; break;
|
||
case TUT_C_iError_ListCtrlItemNotFound : szMessage = "Item not found in list control"; break;
|
||
case TUT_C_iError_ListBoxInvalidLine : szMessage = "Invalid line number in list box"; break;
|
||
case TUT_C_iError_ComboBoxInvalidLine : szMessage = "Invalid line number in combo box"; break;
|
||
case TUT_C_iError_ListCtrlInvalidLine : szMessage = "Invalid line number in list control"; break;
|
||
case TUT_C_iError_TreeCtrlItemNotFound : szMessage = "Item not found in tree control"; break;
|
||
case TUT_C_iError_SoundError : szMessage = "Wav file not found or sound error"; break;
|
||
case TUT_C_iError_UnregisteredWindow : szMessage = "Unregistered window"; break;
|
||
default : szMessage = NULL; break;
|
||
}
|
||
|
||
p_stVariableDef = m_fnp_stFindOrCreateVariable (TUT_C_szGetLastErrorMessage);
|
||
if (szMessage) p_stVariableDef -> csValue = szMessage;
|
||
else p_stVariableDef -> csValue . Format ("Unknown error code (%d)" , _lErrorNumber);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_iConvertToInt
|
||
// Convert a string into an integer. Return TUT_C_iErrorNotANumber if error
|
||
//-----------------------------------------------------------------------------
|
||
int TUT_CTutorialManager::m_fn_iConvertToInt (char * _szString)
|
||
{
|
||
char * szEndOfNumber;
|
||
long lValue = strtol (_szString , & szEndOfNumber , 10);
|
||
if (* szEndOfNumber != 0) return TUT_C_iErrorNotANumber;
|
||
|
||
return (int) lValue;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_iConvertToDouble
|
||
// Convert a string into a double. Return TUT_C_dErrorNotANumber if error
|
||
//-----------------------------------------------------------------------------
|
||
double TUT_CTutorialManager::m_fn_dConvertToDouble (char * _szString)
|
||
{
|
||
char * szEndOfNumber;
|
||
double dValue = strtod (_szString , & szEndOfNumber);
|
||
if (* szEndOfNumber != 0) return TUT_C_dErrorNotANumber;
|
||
|
||
return dValue;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_bAreParametersEqual
|
||
// Return TRUE if the two parameters are equal (can be integer, float or string)
|
||
//-----------------------------------------------------------------------------
|
||
BOOL TUT_CTutorialManager::m_fn_bAreParametersEqual (char * _szParameter1 , char * _szParameter2)
|
||
{
|
||
double dParameter1 = m_fn_dConvertToDouble (_szParameter1);
|
||
BOOL bIsDouble1 = dParameter1 != TUT_C_dErrorNotANumber;
|
||
|
||
double dParameter2 = m_fn_dConvertToDouble (_szParameter2);
|
||
BOOL bIsDouble2 = dParameter2 != TUT_C_dErrorNotANumber;
|
||
|
||
if (bIsDouble1 && bIsDouble2) return dParameter1 == dParameter2;
|
||
else return stricmp (_szParameter1 , _szParameter2) == 0;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_bIsParameter1LessThanParameter2
|
||
// Return TRUE if the first parameter is less than the seoncd parameter (can be integer, float or string)
|
||
//-----------------------------------------------------------------------------
|
||
BOOL TUT_CTutorialManager::m_fn_bIsParameter1LessThanParameter2 (char * _szParameter1 , char * _szParameter2)
|
||
{
|
||
double dParameter1 = m_fn_dConvertToDouble (_szParameter1);
|
||
BOOL bIsDouble1 = dParameter1 != TUT_C_dErrorNotANumber;
|
||
|
||
double dParameter2 = m_fn_dConvertToDouble (_szParameter2);
|
||
BOOL bIsDouble2 = dParameter2 != TUT_C_dErrorNotANumber;
|
||
|
||
if (bIsDouble1 && bIsDouble2) return dParameter1 < dParameter2;
|
||
else return stricmp (_szParameter1 , _szParameter2) < 0;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_bIsParameterTrue
|
||
// Return if a parameter is TRUE or FALSE
|
||
//-----------------------------------------------------------------------------
|
||
BOOL TUT_CTutorialManager::m_fn_bIsParameterTrue (char * _szParameter , int * _p_iReturnValue)
|
||
{
|
||
* _p_iReturnValue = TUT_C_iNoError;
|
||
|
||
if (stricmp (_szParameter , TUT_C_szTrue ) == 0) return TRUE;
|
||
if (stricmp (_szParameter , TUT_C_szFalse) == 0) return FALSE;
|
||
|
||
* _p_iReturnValue = TUT_C_iError_BooleanValueRequired;
|
||
return FALSE;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_bIsTestVerified
|
||
// Execute a test and return the result of this test
|
||
//-----------------------------------------------------------------------------
|
||
BOOL TUT_CTutorialManager::m_fn_bIsTestVerified (char * _szTestOperator , char * _szParameter1 ,
|
||
char * _szParameter2 , int * _p_iReturnValue)
|
||
{
|
||
BOOL bTestVerified;
|
||
* _p_iReturnValue = TUT_C_iNoError;
|
||
|
||
if (stricmp (_szTestOperator , "=") == 0 || stricmp (_szTestOperator , "==") == 0)
|
||
bTestVerified = m_fn_bAreParametersEqual (_szParameter1 , _szParameter2);
|
||
else
|
||
if (stricmp (_szTestOperator , "<>") == 0 || stricmp (_szTestOperator , "!=") == 0)
|
||
bTestVerified = ! m_fn_bAreParametersEqual (_szParameter1 , _szParameter2);
|
||
else
|
||
if (stricmp (_szTestOperator , "<") == 0)
|
||
bTestVerified = m_fn_bIsParameter1LessThanParameter2 (_szParameter1 , _szParameter2);
|
||
else
|
||
if (stricmp (_szTestOperator , "<=") == 0)
|
||
bTestVerified = ! m_fn_bIsParameter1LessThanParameter2 (_szParameter2 , _szParameter1);
|
||
else
|
||
if (stricmp (_szTestOperator , ">") == 0)
|
||
bTestVerified = m_fn_bIsParameter1LessThanParameter2 (_szParameter2 , _szParameter1);
|
||
else
|
||
if (stricmp (_szTestOperator , ">=") == 0)
|
||
bTestVerified = ! m_fn_bIsParameter1LessThanParameter2 (_szParameter1 , _szParameter2);
|
||
else
|
||
{
|
||
bTestVerified = FALSE;
|
||
* _p_iReturnValue = TUT_C_iError_TestOperatorRequired;
|
||
}
|
||
|
||
return bTestVerified;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_bMustActionBeExecuted
|
||
// Return if the current action must be executed
|
||
//-----------------------------------------------------------------------------
|
||
BOOL TUT_CTutorialManager::m_fn_bMustActionBeExecuted ()
|
||
{
|
||
// Not inside a test -> no problem
|
||
if (m_oListOfTest . GetCount () == 0) return TRUE;
|
||
|
||
TUT_tdstTestDefinition * p_stTestDef = m_oListOfTest . GetHead ();
|
||
|
||
// Return TRUE if test verified XOR we are in the else block
|
||
return p_stTestDef -> bTestVerified ^ p_stTestDef -> ePositionInTest == TUT_eAfterElse;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vAddAnActionForTheTest
|
||
// Called each time an action is executed
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vAddAnActionForTheTest ()
|
||
{
|
||
// Not inside a test -> nothing to do
|
||
if (m_oListOfTest . GetCount () == 0) return;
|
||
|
||
TUT_tdstTestDefinition * p_stTestDef = m_oListOfTest . GetHead ();
|
||
if (p_stTestDef -> ePositionInTest == TUT_eAfterIf) p_stTestDef -> ePositionInTest = TUT_eBeforeElse;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vATestRightButtonDoubleClicAndPosition
|
||
// These five flags must be set to FALSE after one action
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vTestRightButtonDoubleClicAndPosition ()
|
||
{
|
||
static BOOL sbPreviousValueUseRightButton = FALSE;
|
||
static BOOL sbPreviousValueUseDoubleClic = FALSE;
|
||
static BOOL sbPreviousValueUsePosition = FALSE;
|
||
static BOOL sbPreviousValueUseDrag = FALSE;
|
||
static BOOL sbPreviousValueUseDrop = FALSE;
|
||
|
||
if (sbPreviousValueUseRightButton) m_bUseRightButton = FALSE;
|
||
if (sbPreviousValueUseDoubleClic ) m_bUseDoubleClic = FALSE;
|
||
if (sbPreviousValueUsePosition ) m_bUsePosition = FALSE;
|
||
if (sbPreviousValueUseDrag ) m_bUseDrag = FALSE;
|
||
if (sbPreviousValueUseDrop ) m_bUseDrop = FALSE;
|
||
|
||
sbPreviousValueUseRightButton = m_bUseRightButton;
|
||
sbPreviousValueUseDoubleClic = m_bUseDoubleClic;
|
||
sbPreviousValueUsePosition = m_bUsePosition;
|
||
sbPreviousValueUseDrag = m_bUseDrag;
|
||
sbPreviousValueUseDrop = m_bUseDrop;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vClearAllList
|
||
// Clear the list used by the class
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vClearAllList (BOOL _bUnregisterControl)
|
||
{
|
||
if (_bUnregisterControl)
|
||
{
|
||
for (int iIndex = m_oArrayOfWnd . GetSize() - 1 ; iIndex >= 0 ; iIndex --)
|
||
delete m_oArrayOfWnd [iIndex];
|
||
m_oArrayOfWnd . RemoveAll ();
|
||
}
|
||
|
||
int iNumber;
|
||
|
||
iNumber = 0;
|
||
while (m_oListOfVariable . GetCount ())
|
||
{
|
||
TUT_tdstVariableDefinition *p_stVarDef = m_oListOfVariable . RemoveHead ();
|
||
delete p_stVarDef;
|
||
iNumber ++;
|
||
}
|
||
|
||
iNumber = 0;
|
||
while (m_oListOfLoop . GetCount ())
|
||
{
|
||
TUT_tdstLoopDefinition *p_stLoopDef = m_oListOfLoop . RemoveHead ();
|
||
delete p_stLoopDef;
|
||
iNumber ++;
|
||
}
|
||
|
||
iNumber = 0;
|
||
while (m_oListOfTest . GetCount ())
|
||
{
|
||
TUT_tdstTestDefinition *p_stTestDef = m_oListOfTest . RemoveHead ();
|
||
iNumber ++;
|
||
delete p_stTestDef;
|
||
}
|
||
|
||
iNumber = 0;
|
||
while (m_oListOfLabel . GetCount ())
|
||
{
|
||
TUT_tdstLabelDefinition *p_stLabelDef = m_oListOfLabel . RemoveHead ();
|
||
delete p_stLabelDef;
|
||
iNumber ++;
|
||
}
|
||
|
||
// Reset the variables
|
||
m_iNumberOfParameter = 0;
|
||
m_iNumberOfResult = 0;
|
||
m_bInsideAGoto = FALSE;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vPreprocessString
|
||
// Remove spaces, tab and quotes at the beginning and the end of the string
|
||
// Remplace variable name by its value. Return FALSE if error
|
||
//-----------------------------------------------------------------------------
|
||
BOOL TUT_CTutorialManager::m_fn_vPreprocessString (char * & _szString)
|
||
{
|
||
if (_szString == NULL || * _szString == 0) return TRUE;;
|
||
|
||
// Remove spaces and tab at the beginning of the string
|
||
while (* _szString == ' ' || * _szString == '\t') _szString ++;
|
||
|
||
// Remove spaces and tab at the end of the string
|
||
char * p = _szString + strlen (_szString) - 1; // Points to the last character of the string
|
||
while (* _szString != 0 && (* p == ' ' || * p == '\t')) * (p--) = 0;
|
||
|
||
// Check if it is a variable name
|
||
int iNbVariable = 0;
|
||
while (* _szString == TUT_C_cBeginningOfVariable)
|
||
{
|
||
_szString ++;
|
||
iNbVariable ++;
|
||
}
|
||
|
||
if (iNbVariable)
|
||
{
|
||
while (iNbVariable --)
|
||
{
|
||
TUT_tdstVariableDefinition * p_stVariableDef = m_fnp_stFindVariable (_szString);
|
||
if (p_stVariableDef) _szString = (char *) (LPCTSTR) p_stVariableDef -> csValue;
|
||
else return FALSE; // Use of an unknown variable -> error
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
// Remove quote at the beginning of the string
|
||
if (* _szString == '"') _szString ++;
|
||
|
||
// Remove quote at the end of the string
|
||
if (* _szString != 0 && * p == '"') * p = 0;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_szStrtok
|
||
// same as strtok but don't stop at delimiter inside quote
|
||
//-----------------------------------------------------------------------------
|
||
char * TUT_CTutorialManager::m_fn_szStrtok (char * _szString , char _cDelimiter)
|
||
{
|
||
static char * p = NULL;
|
||
|
||
if (_szString != NULL) p = _szString; // in both cases,
|
||
else
|
||
{
|
||
if (p == NULL) return NULL;
|
||
else p ++; // p points to the first character
|
||
}
|
||
|
||
char * szReturnValue = p;
|
||
if (* szReturnValue == 0) return NULL; // end of the string -> return NULL
|
||
|
||
BOOL bInsideQuote = FALSE;
|
||
while (* p != 0 && (* p != _cDelimiter || bInsideQuote)) // Find delimiter or end of string
|
||
{
|
||
if (* p == '\"') bInsideQuote = ! bInsideQuote;
|
||
p ++;
|
||
}
|
||
|
||
if (* p != 0) * p = 0; // Put 0 instead of a delimiter
|
||
else p = NULL; // Eof of the string
|
||
|
||
|
||
return szReturnValue;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_iGetParameters
|
||
// Split a string into a variable number of parameters. Return 0 if no error
|
||
//-----------------------------------------------------------------------------
|
||
int TUT_CTutorialManager::m_fn_iGetParameters (char * _szString , int _iMinNumberOfParameter , int _iMaxNumberOfParameter ,
|
||
int * _p_iNumberOfParameter , ...)
|
||
{
|
||
va_list Marker;
|
||
va_start (Marker, _p_iNumberOfParameter); // Initialize variable arguments
|
||
* _p_iNumberOfParameter = 0;
|
||
|
||
char * szParameter = m_fn_szStrtok (_szString , ',');
|
||
while (szParameter != NULL)
|
||
{
|
||
(* _p_iNumberOfParameter) ++;
|
||
if (* _p_iNumberOfParameter > _iMaxNumberOfParameter) return TUT_C_iError_TooManyParameters;
|
||
|
||
char * * p_szParameter = va_arg (Marker , char * *); // Get the next argument
|
||
if (! m_fn_vPreprocessString (szParameter)) return TUT_C_iError_UnknownVariable;
|
||
* p_szParameter = m_fn_szHandleQuote (szParameter);
|
||
|
||
szParameter = m_fn_szStrtok (NULL , ',');
|
||
}
|
||
|
||
va_end (Marker);
|
||
|
||
if (* _p_iNumberOfParameter < _iMinNumberOfParameter) return TUT_C_iError_ParameterRequired;
|
||
|
||
return TUT_C_iNoError;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vPumpMessage
|
||
// Dispatch messages
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vPumpMessage ()
|
||
{
|
||
MSG Msg;
|
||
while (PeekMessage (& Msg , NULL , 0 , 0 , PM_REMOVE))
|
||
DispatchMessage (& Msg);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vSleep
|
||
// Wait for the given duration (in millisecond)
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vSleep (int _iDuration)
|
||
{
|
||
BOOL bLeftKeyPressed = (GetAsyncKeyState (VK_LSHIFT) & 0x8000) && (GetAsyncKeyState (VK_LCONTROL) & 0x8000);
|
||
|
||
m_fn_vPumpMessage ();
|
||
|
||
while (_iDuration > 0)
|
||
{
|
||
int iDelta = min (50 , _iDuration);
|
||
_iDuration -= iDelta;
|
||
|
||
// Are the control and shift keys pressed ?
|
||
if ((GetAsyncKeyState (VK_RCONTROL) & 0x8000) && (GetAsyncKeyState (VK_RSHIFT) & 0x8000)) return;
|
||
|
||
// Is the 'Escape' key pressed ?
|
||
if ((GetAsyncKeyState (VK_ESCAPE) & 0x8000)) return;
|
||
|
||
if (bLeftKeyPressed)
|
||
{
|
||
if ((GetAsyncKeyState (VK_LSHIFT) & 0x8000) == 0 && (GetAsyncKeyState (VK_LCONTROL) & 0x8000) == 0)
|
||
bLeftKeyPressed = FALSE;
|
||
}
|
||
else
|
||
{
|
||
if ((GetAsyncKeyState (VK_LSHIFT) & 0x8000) && (GetAsyncKeyState (VK_LCONTROL) & 0x8000)) return;
|
||
}
|
||
|
||
Sleep (iDelta);
|
||
|
||
m_fn_vPumpMessage ();
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vActivateWindow
|
||
// Activate a window and its parent (recursiv call)
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vActivateWindow (HWND _hWnd)
|
||
{
|
||
SetForegroundWindow (_hWnd);
|
||
UpdateWindow (_hWnd);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_hOpenUserWindow
|
||
// Open one user window (a rich edit control inside a frame) and return its handle
|
||
//-----------------------------------------------------------------------------
|
||
HWND TUT_CTutorialManager::m_fn_hOpenUserWindow (char * _szWindowName , int _iLeft , int _iTop ,
|
||
int _iRight , int _iBottom)
|
||
{
|
||
// Compute the size of the frame to create
|
||
CRect ScreenPos;
|
||
GetWindowRect (GetDesktopWindow () , & ScreenPos);
|
||
CRect WindowPos;
|
||
WindowPos . left = ScreenPos . right * _iLeft / 100;
|
||
WindowPos . right = ScreenPos . right * _iRight / 100;
|
||
WindowPos . top = ScreenPos . bottom * _iTop / 100;
|
||
WindowPos . bottom = ScreenPos . bottom * _iBottom / 100;
|
||
|
||
// Create a new class for the frame
|
||
LPCTSTR lpszSmartClass = AfxRegisterWndClass (CS_HREDRAW | CS_VREDRAW , LoadCursor (NULL, IDC_ARROW) , (HBRUSH) (COLOR_WINDOW + 1));
|
||
|
||
// Create the frame window
|
||
HWND hWnd = CreateWindowEx (WS_EX_TOPMOST | WS_EX_TOOLWINDOW , lpszSmartClass , _szWindowName ,
|
||
WS_POPUP | WS_BORDER | WS_CAPTION | WS_VISIBLE ,
|
||
WindowPos . left , WindowPos . top , WindowPos . Width () , WindowPos . Height () ,
|
||
NULL /* No parent to avoid problem */ , NULL , AfxGetInstanceHandle () , NULL);
|
||
if (hWnd == NULL)
|
||
{
|
||
DWORD dwError = GetLastError ();
|
||
ASSERT (0);
|
||
}
|
||
|
||
// Create a text view
|
||
CRect ClientRect;
|
||
GetClientRect (hWnd , & ClientRect);
|
||
|
||
HWND hEditView = CreateWindowEx (WS_EX_LEFT , "RichEdit" , "" , WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE ,
|
||
ClientRect . left , ClientRect . top , ClientRect . Width () , ClientRect . Height () ,
|
||
hWnd , NULL , AfxGetInstanceHandle () , NULL);
|
||
if (hEditView == NULL)
|
||
{
|
||
DWORD dwError = GetLastError ();
|
||
ASSERT (0);
|
||
}
|
||
SendMessage (hEditView , EM_SETREADONLY , TRUE , 0);
|
||
|
||
return hEditView;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vCloseUserWindow
|
||
// Close one user window
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vCloseUserWindow (int _iIndex)
|
||
{
|
||
TUT_tdstWndDefinition * p_stWndDefinition = m_oArrayOfWnd [_iIndex];
|
||
HWND hWindow = p_stWndDefinition -> hWnd;
|
||
HWND hParent = GetParent (hWindow);
|
||
ASSERT (hParent);
|
||
|
||
DestroyWindow (hWindow);
|
||
DestroyWindow (hParent);
|
||
|
||
m_oArrayOfWnd . RemoveAt (_iIndex);
|
||
|
||
delete p_stWndDefinition;
|
||
|
||
if (m_p_stCurrentUserWindow == p_stWndDefinition) m_p_stCurrentUserWindow = NULL;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vCloseAllUserWindow
|
||
// Close all open user windows
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vCloseAllUserWindow ()
|
||
{
|
||
for (int iIndex = m_oArrayOfWnd . GetSize () - 1 ; iIndex >= 0 ; iIndex --)
|
||
{
|
||
TUT_tdstWndDefinition * p_stWndDefinition = m_oArrayOfWnd [iIndex];
|
||
if (p_stWndDefinition -> eType == TUT_eUserWindow) m_fn_vCloseUserWindow (iIndex);
|
||
}
|
||
|
||
if (m_hDebugWnd)
|
||
{
|
||
DestroyWindow (m_hDebugWnd);
|
||
m_hDebugWnd = NULL;
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vDeleteLocalLabelAndVariable
|
||
// Delete all local labels and variables
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vDeleteLocalLabelAndVariable ()
|
||
{
|
||
int iCurrentContextNumber = m_oListOfContext . GetCount ();
|
||
|
||
POSITION Pos = m_oListOfVariable . GetHeadPosition ();
|
||
while (Pos)
|
||
{
|
||
POSITION SavePos = Pos;
|
||
TUT_tdstVariableDefinition * p_stVariableDef = m_oListOfVariable . GetNext (Pos);
|
||
|
||
if (p_stVariableDef -> iContextNumber == iCurrentContextNumber)
|
||
{
|
||
m_oListOfVariable . RemoveAt (SavePos);
|
||
delete p_stVariableDef;
|
||
}
|
||
}
|
||
|
||
Pos = m_oListOfLabel . GetHeadPosition ();
|
||
while (Pos)
|
||
{
|
||
POSITION SavePos = Pos;
|
||
TUT_tdstLabelDefinition * p_stLabelDef = m_oListOfLabel . GetNext (Pos);
|
||
|
||
if (p_stLabelDef -> iContextNumber == iCurrentContextNumber)
|
||
{
|
||
m_oListOfLabel . RemoveAt (SavePos);
|
||
delete p_stLabelDef;
|
||
}
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vCloseLogFile
|
||
// Close the given log file if it is open
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vCloseLogFile (TUT_tdstLogFileDefinition * _p_stLogFile)
|
||
{
|
||
if (_p_stLogFile -> bOpen)
|
||
{
|
||
fclose (_p_stLogFile -> pFile);
|
||
_p_stLogFile -> bOpen = FALSE;
|
||
_p_stLogFile -> csName = "";
|
||
_p_stLogFile -> pFile = NULL;
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vCloseAllLogFiles
|
||
// Close the given log file if it is open
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vCloseAllLogFiles ()
|
||
{
|
||
m_fn_vCloseLogFile (& m_stLogFile);
|
||
m_fn_vCloseLogFile (& m_stDebugLogFile);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_bFindColor
|
||
// Find RGB code of the given color name. Return FALSE if not found
|
||
//-----------------------------------------------------------------------------
|
||
BOOL TUT_CTutorialManager::m_fn_bFindColor (char * _szColorName , COLORREF * _p_xColor)
|
||
{
|
||
const TUT_tdstColorDefinition * p = g_a_stColorDefinition;
|
||
|
||
while (p -> szColorName)
|
||
{
|
||
if (stricmp (p -> szColorName , _szColorName) == 0)
|
||
{
|
||
* _p_xColor = p -> xColor;
|
||
return TRUE;
|
||
}
|
||
|
||
p ++;
|
||
}
|
||
|
||
return FALSE; // Not found
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_iFindVirtualKeyCode
|
||
// Find a virtual key code with the given name. Return 0 if not found
|
||
//-----------------------------------------------------------------------------
|
||
int TUT_CTutorialManager::m_fn_iFindVirtualKeyCode (char * _szVirtualKeyCode)
|
||
{
|
||
if (strlen (_szVirtualKeyCode) == 1)
|
||
{
|
||
char cChar = (char) toupper (* _szVirtualKeyCode);
|
||
if (cChar >= 'A' && cChar <= 'Z') return cChar;
|
||
}
|
||
|
||
int i = -1;
|
||
char * szKeyName;
|
||
do
|
||
{
|
||
szKeyName = TUT_cgs_a_stKeyConversionTable [++ i] . szKeyName;
|
||
if (szKeyName == NULL) return 0; // End of the list : not found -> return 0;
|
||
} while (stricmp (szKeyName , _szVirtualKeyCode) != 0);
|
||
|
||
return TUT_cgs_a_stKeyConversionTable [i] . iVirtualKeyCode;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_iFindIdForMessageMox
|
||
// Find RGB code of the given color name. Return FALSE if not found
|
||
//-----------------------------------------------------------------------------
|
||
int TUT_CTutorialManager::m_fn_iFindIdForMessageBox (char * _szControlName)
|
||
{
|
||
if (stricmp (_szControlName , TUT_C_szOk ) == 0) return IDOK;
|
||
if (stricmp (_szControlName , TUT_C_szCancel) == 0) return IDCANCEL;
|
||
if (stricmp (_szControlName , TUT_C_szAbort ) == 0) return IDABORT;
|
||
if (stricmp (_szControlName , TUT_C_szRetry ) == 0) return IDRETRY;
|
||
if (stricmp (_szControlName , TUT_C_szIgnore) == 0) return IDIGNORE;
|
||
if (stricmp (_szControlName , TUT_C_szYes ) == 0) return IDYES;
|
||
if (stricmp (_szControlName , TUT_C_szNo ) == 0) return IDNO;
|
||
|
||
return 0; // Not found
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_szGetWndNameType
|
||
// Return the name of the given window type
|
||
//-----------------------------------------------------------------------------
|
||
char * TUT_CTutorialManager::m_fn_szGetWndNameType (TUT_tdeWndType _eType)
|
||
{
|
||
switch (_eType)
|
||
{
|
||
case TUT_eWindow : return "Window";
|
||
case TUT_eMdiWindow : return "Mdi window";
|
||
case TUT_eButton : return "Button";
|
||
case TUT_eTextEdit : return "Text edit";
|
||
case TUT_eListBox : return "List box";
|
||
case TUT_eComboBox : return "Combo box";
|
||
case TUT_eTreeCtrl : return "Tree control";
|
||
case TUT_eListCtrl : return "List control";
|
||
case TUT_eSpin : return "Spin";
|
||
case TUT_eSlider : return "Slider";
|
||
case TUT_eScrollBar : return "Scrollbar";
|
||
case TUT_eUserWindow : return "User window";
|
||
case TUT_e3DView : return "3DView";
|
||
default : ASSERT (0);
|
||
return NULL;
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vShowError
|
||
// Open a message box with a message associated to the given error code
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vShowError (int _iErrorCode , const CString _csFileName , int _iLineNumber , char * _szLine)
|
||
{
|
||
CString csMessage;
|
||
|
||
if (_iErrorCode == TUT_C_iError_FileNotFound) csMessage . Format ("File not found : %s" , _csFileName);
|
||
else
|
||
{
|
||
CString csText;
|
||
|
||
switch (_iErrorCode)
|
||
{
|
||
case TUT_C_iError_UnknownCommand : csText = "Unknown command"; break;
|
||
case TUT_C_iError_TooManyParameters : csText = "Too many parameters"; break;
|
||
case TUT_C_iError_ParameterRequired : csText = "More parameters are required"; break;
|
||
case TUT_C_iError_UnknownButton : csText = "Unknown button name"; break;
|
||
case TUT_C_iError_ButtonRequired : csText = "The control is not a button"; break;
|
||
case TUT_C_iError_InvalidCoordinates : csText = "Coordinates are not valid"; break;
|
||
case TUT_C_iError_NoWindowToWriteText : csText = "No open window to write text"; break;
|
||
case TUT_C_iError_InvalidNumber : csText = "Invalid number"; break;
|
||
case TUT_C_iError_UnknownTextEdit : csText = "Unknown text edit name"; break;
|
||
case TUT_C_iError_TextEditRequired : csText = "The control is not a text edit"; break;
|
||
case TUT_C_iError_UnknownWindow : csText = "Unknown window name"; break;
|
||
case TUT_C_iError_UnknownComboBox : csText = "Unknown combo box name"; break;
|
||
case TUT_C_iError_ListOrComboRequired : csText = "The control must be a combo box, a list box or a list control"; break;
|
||
case TUT_C_iError_UnknownMdiWindow : csText = "Unknown mdi window name"; break;
|
||
case TUT_C_iError_MdiWindowRequired : csText = "The control is not a mdi window"; break;
|
||
case TUT_C_iError_UnknownColor : csText = "Unknown color name"; break;
|
||
case TUT_C_iError_UnknownControl : csText = "Unknown control name"; break;
|
||
case TUT_C_iError_SelectCtrlRequired : csText = "The control is not a control with selection"; break;
|
||
case TUT_C_iError_InvalidTextAlignment : csText = "Invalid text alignment"; break;
|
||
case TUT_C_iError_UnknownTreeBox : csText = "Unknown tree box name"; break;
|
||
case TUT_C_iError_TreeBoxRequired : csText = "The control is not a tree box"; break;
|
||
case TUT_C_iError_FunctionNotCompiled : csText = "Not compiled function"; break;
|
||
case TUT_C_iError_Unknown3dObject : csText = "Unknown 3d object"; break;
|
||
case TUT_C_iError_NoMenuAvailable : csText = "No menu available"; break;
|
||
case TUT_C_iError_UnknownMenuName : csText = "Unknown menu name"; break;
|
||
case TUT_C_iError_NotASubMenu : csText = "Not a sub menu"; break;
|
||
case TUT_C_iError_EndLoopWithoutLoop : csText = "'EndLoop' without a 'Loop'"; break;
|
||
case TUT_C_iError_TestOperatorRequired : csText = "A test operator is required"; break;
|
||
case TUT_C_iError_OrIfWithoutAnIf : csText = "'OrIf' without an 'If'"; break;
|
||
case TUT_C_iError_ElseWithoutAnIf : csText = "'Else' without an 'If'"; break;
|
||
case TUT_C_iError_ElseInTheWrongPlace : csText = "Incorrect 'Else'"; break;
|
||
case TUT_C_iError_EndIfWithoutAnIf : csText = "'EndIf' without an 'If'"; break;
|
||
case TUT_C_iError_DebugWndAlreadyOpen : csText = "The debug window is already open"; break;
|
||
case TUT_C_iError_DebugWndNotOpen : csText = "The debug window is not open"; break;
|
||
case TUT_C_iError_InvalidMdiHandle : csText = "Invalid handle to a MDI window"; break;
|
||
case TUT_C_iError_InvalidParentMdiHandle : csText = "Invalid handle to a parent of a MDI window"; break;
|
||
case TUT_C_iError_InvalidListBoxHandle : csText = "Invalid handle to a list box"; break;
|
||
case TUT_C_iError_InvalidComboBoxHandle : csText = "Invalid handle to a combo box"; break;
|
||
case TUT_C_iError_InvalidTreeBoxHandle : csText = "Invalid handle to a tree box"; break;
|
||
case TUT_C_iError_InvalidMenuHandle : csText = "Invalid menu handle"; break;
|
||
case TUT_C_iError_InvalidMenuWndHandle : csText = "Invalid handle to a menu owner"; break;
|
||
case TUT_C_iError_InvalidButtonHandle : csText = "Invalid handle to a button"; break;
|
||
case TUT_C_iError_InvalidTextEditHandle : csText = "Invalid handle to a text edit"; break;
|
||
case TUT_C_iError_WindowOrMdiRequired : csText = "The control is not a window or a MDI window"; break;
|
||
case TUT_C_iError_InvalidWndOrMdiHandle : csText = "Invalid handle to a window or a MDI window"; break;
|
||
case TUT_C_iError_CtrlWithTextRequired : csText = "This type of control has no text"; break;
|
||
case TUT_C_iError_InvalidHandle : csText = "Invalid handle"; break;
|
||
case TUT_C_iError_BooleanValueRequired : csText = "A boolean value is required"; break;
|
||
case TUT_C_iError_ItemNotFoundInTree : csText = "The item was not found in the tree"; break;
|
||
case TUT_C_iError_ItemHasNoChild : csText = "The item has no child"; break;
|
||
case TUT_C_iError_InvalidChildNumber : csText = "Invalid child number"; break;
|
||
case TUT_C_iError_NotANumericVariable : csText = "A numeric variable is required"; break;
|
||
case TUT_C_iError_DivisionByZero : csText = "Division by zero"; break;
|
||
case TUT_C_iError_EmptyVariable : csText = "A not-empty variable is required"; break;
|
||
case TUT_C_iError_LogFileAlreadyOpen : csText = "A log file is already open"; break;
|
||
case TUT_C_iError_UnableToOpenLogFile : csText = "Unable to open the log file"; break;
|
||
case TUT_C_iError_LogFileNotOpen : csText = "The log file is not open"; break;
|
||
case TUT_C_iError_InvalidXBorder : csText = "'Left' or 'Right' is required"; break;
|
||
case TUT_C_iError_InvalidYBorder : csText = "'Top' or 'Bottom' is required"; break;
|
||
case TUT_C_iError_InvalidNumberOrPercent : csText = "Invalid number or percentage"; break;
|
||
case TUT_C_iError_InvalidListCtrlHandle : csText = "Invalid handle to a list control"; break;
|
||
case TUT_C_iError_LabelsWithSameName : csText = "This name is already used by another label"; break;
|
||
case TUT_C_iError_LabelNotFound : csText = "Label not found"; break;
|
||
case TUT_C_iError_ModelNotFound : csText = "Model not found"; break;
|
||
case TUT_C_iError_DragAtTheWrongPlace : csText = "'Drag' at the wrong place"; break;
|
||
case TUT_C_iError_DropAtTheWrongPlace : csText = "'Drop' at the wrong place"; break;
|
||
case TUT_C_iError_InvisibleControl : csText = "Use of an invisible control"; break;
|
||
case TUT_C_iError_DisabledControl : csText = "Use of a disabled control"; break;
|
||
case TUT_C_iError_NoMultipleSelection : csText = "The list is not a multiple selection list"; break;
|
||
case TUT_C_iError_UnknownListBox : csText = "Unknown list box name"; break;
|
||
case TUT_C_iError_ListBoxRequired : csText = "The control is not a list box"; break;
|
||
case TUT_C_iError_UnknownObject : csText = "Unknown object name"; break;
|
||
case TUT_C_iError_UnknownVariable : csText = "Unknown variable name or variable already declared";break;
|
||
case TUT_C_iError_CountCtrlRequired : csText = "A list box, list control or combo box is required"; break;
|
||
case TUT_C_iError_UnknownMessageBoxCtrl : csText = "Unknown message box control name"; break;
|
||
case TUT_C_iError_MessageBoxCtrlNotFound : csText = "Message box control not found"; break;
|
||
case TUT_C_iError_NoReturnValue : csText = "There is no return value"; break;
|
||
case TUT_C_iError_UnknownKey : csText = "Unknown key name"; break;
|
||
case TUT_C_iError_MultiLineRequired : csText = "The text edit is not multi-line"; break;
|
||
case TUT_C_iError_InvalidLineNumber : csText = "Invalid line number"; break;
|
||
case TUT_C_iError_LocalVariableExist : csText = "A local variable with the same name already exists";break;
|
||
case TUT_C_iError_GlobalVariableExist : csText = "A global variable with the same name already exists";break;
|
||
case TUT_C_iError_ListViewRequired : csText = "A List View control is required"; break;
|
||
case TUT_C_iError_UncoherentSelectionLimits : csText = "Limits of selection are incoherent"; break;
|
||
|
||
default : csText . Format ("Unknown error : code = %d" , _iErrorCode); break;
|
||
}
|
||
|
||
if (_iErrorCode == TUT_C_iError_LabelNotFound)
|
||
csMessage . Format ("Error n<> %d in file '%s' : %s (%s)" , _iErrorCode , _csFileName , csText , m_csLabelToFind);
|
||
else csMessage . Format ("Error n<> %d in file '%s' : %s (line %d : '%s')" , _iErrorCode , _csFileName , csText ,
|
||
_iLineNumber , _szLine);
|
||
}
|
||
|
||
// Give the focus to the tutorial thread
|
||
if (m_p_stCurrentUserWindow)
|
||
SetForegroundWindow (m_p_stCurrentUserWindow -> hWnd);
|
||
|
||
MessageBox (NULL , csMessage , "Tutorial manager" , MB_OK + MB_ICONSTOP + MB_TASKMODAL);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vMoveMouseCursor
|
||
// Move the mouse cursor to the destination point
|
||
// Duration is in millisecond, speed in pixel/second and acceleration in pixel/second<6E>
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vMoveMouseCursor (CPoint _stDestination, HWND _hWnd /*=NULL*/)
|
||
{
|
||
long lMaxDuration = m_lCurrentMaxDuration;
|
||
long lMinSpeed = m_lCurrentMinSpeed;
|
||
long lAcceleration = m_lCurrentAcceleration;
|
||
|
||
CPoint stCurrentMousePos;
|
||
GetCursorPos (& stCurrentMousePos);
|
||
CPoint stDelta = _stDestination - stCurrentMousePos;
|
||
|
||
long lCurrentDistance = (long) sqrt ((double) (stDelta . x * stDelta . x + stDelta . y * stDelta . y));
|
||
long lOptimumSpeed = lCurrentDistance * 1000 / lMaxDuration;
|
||
if (lOptimumSpeed < lMinSpeed) lOptimumSpeed = lMinSpeed;
|
||
|
||
long lCurrentSpeed = 0;
|
||
|
||
const long lDeltaT = m_bUseDrop ? 30 : 10; // one move every 10 milliseconds
|
||
|
||
long lTime = 0;
|
||
|
||
while (stCurrentMousePos != _stDestination && lTime < lMaxDuration)
|
||
{
|
||
long lDistanceToStop = lCurrentSpeed * lCurrentSpeed / 2 / lAcceleration;
|
||
long lCurrentAcceleration;
|
||
// breake ?
|
||
if (lCurrentDistance <= lDistanceToStop * 1100 / 1000) lCurrentAcceleration = - lAcceleration;
|
||
else
|
||
// accelerate ?
|
||
if (lCurrentSpeed < lOptimumSpeed * 1300 / 1000) lCurrentAcceleration = lAcceleration;
|
||
else lCurrentAcceleration = 0;
|
||
|
||
lCurrentSpeed += lCurrentAcceleration * lDeltaT / 1000;
|
||
POINT stTranslation;
|
||
stTranslation . x = lDeltaT * lCurrentSpeed * stDelta . x / lCurrentDistance / 1000;
|
||
stTranslation . y = lDeltaT * lCurrentSpeed * stDelta . y / lCurrentDistance / 1000;
|
||
if (stTranslation . x == 0)
|
||
{
|
||
if (stCurrentMousePos . x < _stDestination . x) stTranslation . x = 1; else
|
||
if (stCurrentMousePos . x > _stDestination . x) stTranslation . x = -1;
|
||
}
|
||
if (stTranslation . y == 0)
|
||
{
|
||
if (stCurrentMousePos . y < _stDestination . y) stTranslation . y = 1; else
|
||
if (stCurrentMousePos . y > _stDestination . y) stTranslation . y = -1;
|
||
}
|
||
stCurrentMousePos . x += stTranslation . x;
|
||
stCurrentMousePos . y += stTranslation . y;
|
||
|
||
SetCursorPos (stCurrentMousePos .x , stCurrentMousePos . y);
|
||
if (_hWnd)
|
||
{
|
||
CPoint stLocalMousePos = stCurrentMousePos;
|
||
|
||
ScreenToClient (_hWnd , & stLocalMousePos);
|
||
PostMessage (_hWnd , WM_MOUSEMOVE , 0 , MAKELPARAM (stLocalMousePos . x , stLocalMousePos . y) );
|
||
}
|
||
|
||
m_fn_vSleep (lDeltaT);
|
||
lTime += lDeltaT;
|
||
|
||
GetCursorPos (& stCurrentMousePos);
|
||
stDelta = _stDestination - stCurrentMousePos;
|
||
|
||
lCurrentDistance = (long) sqrt ((double) (stDelta . x * stDelta . x + stDelta . y * stDelta . y));
|
||
}
|
||
|
||
SetCursorPos (_stDestination . x , _stDestination . y);
|
||
if (_hWnd)
|
||
{
|
||
CPoint stLocalMousePos = _stDestination;
|
||
|
||
ScreenToClient (_hWnd , & stLocalMousePos);
|
||
PostMessage (_hWnd , WM_MOUSEMOVE , 0 , MAKELPARAM (stLocalMousePos . x , stLocalMousePos . y) );
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vMoveMouseCursor
|
||
// Move the mouse cursor to the center of the given window
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vMoveMouseCursor (HWND _hWnd)
|
||
{
|
||
CRect WindowPos;
|
||
GetWindowRect (_hWnd , & WindowPos);
|
||
|
||
m_fn_vMoveMouseCursor (WindowPos . CenterPoint ());
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vClickOnControl
|
||
// Simulate a click on a control
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vClickOnControl (HWND _hControl)
|
||
{
|
||
// Get the center of the control
|
||
CRect Rect;
|
||
GetClientRect (_hControl , & Rect);
|
||
LPARAM lParam = MAKELPARAM (Rect . CenterPoint () . x , Rect . CenterPoint () . y);
|
||
UINT uiMsgDown;
|
||
UINT uiMsgUp;
|
||
UINT uiMsgDblClk;
|
||
WPARAM wParam,wButton;
|
||
|
||
if (m_bUseRightButton)
|
||
{
|
||
uiMsgDown = WM_RBUTTONDOWN;
|
||
uiMsgUp = WM_RBUTTONUP;
|
||
uiMsgDblClk = WM_RBUTTONDBLCLK;
|
||
wButton = MK_RBUTTON;
|
||
}
|
||
else
|
||
{
|
||
uiMsgDown = WM_LBUTTONDOWN;
|
||
uiMsgUp = WM_LBUTTONUP;
|
||
uiMsgDblClk = WM_LBUTTONDBLCLK;
|
||
wButton = MK_LBUTTON;
|
||
}
|
||
wParam = (m_bUseShift ? MK_SHIFT : 0) + (m_bUseControl ? MK_CONTROL : 0);
|
||
|
||
m_fn_vSleep (60);
|
||
PostMessage (_hControl , uiMsgDown , wParam | wButton, lParam); // Clic on the button
|
||
m_fn_vSleep (60);
|
||
if (m_bUseDoubleClic)
|
||
{
|
||
PostMessage (_hControl , uiMsgUp , wParam , lParam);
|
||
m_fn_vSleep (60);
|
||
PostMessage (_hControl , uiMsgDblClk , wParam | wButton, lParam);
|
||
m_fn_vSleep (60);
|
||
}
|
||
PostMessage (_hControl , uiMsgUp , wParam , lParam); // Release the button
|
||
m_fn_vSleep (60);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vSetTextInEdit
|
||
// Simulate an edition of text,
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vSetTextInEdit (HWND _hTextEdit , const CString _csText)
|
||
{
|
||
HWND hParent = GetParent (_hTextEdit);
|
||
|
||
for (int i = 1 ; i <= _csText . GetLength () ; i ++)
|
||
{
|
||
SetWindowText (_hTextEdit , _csText . Left (i));
|
||
|
||
SendMessage (_hTextEdit , EM_SETSEL , i , i); // Put the caret at the end of the line
|
||
InvalidateRect (_hTextEdit , NULL , FALSE);
|
||
UpdateWindow (_hTextEdit);
|
||
|
||
SendMessage (_hTextEdit , EM_SETMODIFY , TRUE , 0);
|
||
|
||
if (_csText [i - 1] != ' ') m_fn_vSleep (m_iDurationBetweenKeys);
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vSelectLineInComboBox
|
||
// Simulate a selection into a combo box
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vSelectLineInComboBox (HWND _hComboBox , int _iLineNumber)
|
||
{
|
||
m_fn_vSetGetLastError (TUT_C_iNoError);
|
||
|
||
int iComboBoxGetCount = SendMessage (_hComboBox , CB_GETCOUNT , 0 , 0);
|
||
if (_iLineNumber < 1 || _iLineNumber > iComboBoxGetCount)
|
||
{
|
||
m_fn_vSetGetLastError (TUT_C_iError_ComboBoxInvalidLine);
|
||
return;
|
||
}
|
||
|
||
SendMessage (_hComboBox , CB_SHOWDROPDOWN , TRUE , 0);
|
||
|
||
// To be sure the line will be visible
|
||
CRect stListRect;
|
||
SendMessage (_hComboBox , CB_GETDROPPEDCONTROLRECT , 0 , (LPARAM) & stListRect);
|
||
|
||
int iTopIndex = SendMessage (_hComboBox , CB_GETTOPINDEX , 0 , 0);
|
||
int iItemRect = SendMessage (_hComboBox , CB_GETITEMHEIGHT , 0 , 0);
|
||
int iNumberOfVisibleItem = stListRect . Height () / iItemRect - 2;
|
||
|
||
if (_iLineNumber - 1 < iTopIndex)
|
||
SendMessage (_hComboBox , CB_SETTOPINDEX , _iLineNumber - 1 , 0);
|
||
else
|
||
if (_iLineNumber - 1 > iTopIndex + iNumberOfVisibleItem - 1)
|
||
SendMessage (_hComboBox , CB_SETTOPINDEX , _iLineNumber - iNumberOfVisibleItem , 0);
|
||
|
||
iTopIndex = SendMessage (_hComboBox , CB_GETTOPINDEX , 0 , 0);
|
||
|
||
// Compute the position of the selected line to move the mouse to
|
||
CRect ComboPos;
|
||
GetWindowRect (_hComboBox , & ComboPos);
|
||
CPoint Pos = ComboPos . CenterPoint ();
|
||
Pos . y += ComboPos . Height () / 2 + iItemRect / 2 + iItemRect * (_iLineNumber - 1 - iTopIndex);
|
||
m_fn_vMoveMouseCursor (Pos);
|
||
|
||
SendMessage (_hComboBox , CB_SHOWDROPDOWN , FALSE , 0);
|
||
|
||
if (m_bUseRightButton)
|
||
{
|
||
LPARAM lParam = MAKELPARAM (Pos . x , Pos . y);
|
||
WPARAM wParam = (m_bUseShift ? MK_SHIFT : 0) | (m_bUseControl ? MK_CONTROL : 0);;
|
||
|
||
ScreenToClient (_hComboBox , & Pos);
|
||
PostMessage (_hComboBox , WM_RBUTTONDOWN , wParam + MK_RBUTTON , lParam);
|
||
PostMessage (_hComboBox , WM_RBUTTONUP , wParam , lParam);
|
||
}
|
||
else
|
||
{
|
||
HWND hParentWnd = GetParent (_hComboBox);
|
||
SendMessage (_hComboBox , CB_SETCURSEL , _iLineNumber - 1 , 0);
|
||
PostMessage (hParentWnd , WM_COMMAND , (CBN_SELCHANGE << 16) + GetDlgCtrlID (_hComboBox) , (LPARAM) _hComboBox);
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vSelectLineInListBox
|
||
// Simulate a selection into a list box
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vSelectLineInListBox (HWND _hListBox , int _iLineNumber , BOOL _bAddToSelection /*=FALSE*/)
|
||
{
|
||
m_fn_vSetGetLastError (TUT_C_iNoError);
|
||
|
||
int iListBoxGetCount = SendMessage (_hListBox , LB_GETCOUNT , 0 , 0);
|
||
if (_iLineNumber < 1 || _iLineNumber > iListBoxGetCount)
|
||
{
|
||
m_fn_vSetGetLastError (TUT_C_iError_ListBoxInvalidLine);
|
||
return;
|
||
}
|
||
|
||
// To be sure the line will be visible
|
||
SendMessage(_hListBox , LVM_ENSUREVISIBLE , _iLineNumber - 1 , FALSE);
|
||
|
||
// Compute the position of the selected line to move the mouse to
|
||
CRect ListPos;
|
||
GetWindowRect (_hListBox , & ListPos);
|
||
CPoint Pos;
|
||
int iTopIndex = SendMessage (_hListBox , LB_GETTOPINDEX , 0 , 0);
|
||
int iItemHeight = SendMessage (_hListBox , LB_GETITEMHEIGHT , 0 , 0);
|
||
if (m_bUsePosition)
|
||
{
|
||
Pos . y = ListPos . top + iItemHeight * (_iLineNumber - 1 - iTopIndex);
|
||
|
||
if (m_bPercentForX)
|
||
if (m_bRightBorder ) Pos . x = ListPos . right - ListPos . Width () * m_iXPosition / 100;
|
||
else Pos . x = ListPos . left + ListPos . Width () * m_iXPosition / 100;
|
||
else
|
||
if (m_bRightBorder ) Pos . x = ListPos . right - m_iXPosition;
|
||
else Pos . x = ListPos . left + m_iXPosition;
|
||
|
||
if (m_bPercentForY)
|
||
if (m_bBottomBorder) Pos . y += iItemHeight - iItemHeight * m_iYPosition / 100;
|
||
else Pos . y += iItemHeight * m_iYPosition / 100;
|
||
else
|
||
if (m_bBottomBorder) Pos . y += iItemHeight - m_iYPosition;
|
||
else Pos . y += m_iYPosition;
|
||
}
|
||
else
|
||
{
|
||
Pos . x = min (ListPos . CenterPoint () . x , ListPos . left + 4 * iItemHeight);
|
||
Pos . y = ListPos . top + iItemHeight / 2 + iItemHeight * (_iLineNumber - 1 - iTopIndex);
|
||
}
|
||
m_fn_vMoveMouseCursor (Pos);
|
||
|
||
if (m_bUseRightButton)
|
||
{
|
||
ScreenToClient (_hListBox , & Pos);
|
||
LPARAM lParam = MAKELPARAM (Pos . x , Pos . y);
|
||
WPARAM wParam = (m_bUseShift ? MK_SHIFT : 0) | (m_bUseControl ? MK_CONTROL : 0);
|
||
|
||
PostMessage (_hListBox , WM_RBUTTONDOWN , wParam | MK_RBUTTON , lParam);
|
||
PostMessage (_hListBox , WM_RBUTTONUP , wParam , lParam);
|
||
}
|
||
else
|
||
if (m_bUseDoubleClic)
|
||
{
|
||
ScreenToClient (_hListBox , & Pos);
|
||
LPARAM lParam = MAKELPARAM (Pos . x , Pos . y);
|
||
WPARAM wParam = (m_bUseShift ? MK_SHIFT : 0) | (m_bUseControl ? MK_CONTROL : 0);
|
||
|
||
PostMessage (_hListBox , WM_LBUTTONDOWN , wParam | MK_LBUTTON , lParam);
|
||
PostMessage (_hListBox , WM_LBUTTONUP , wParam , lParam);
|
||
PostMessage (_hListBox , WM_LBUTTONDBLCLK , wParam | MK_LBUTTON , lParam);
|
||
PostMessage (_hListBox , WM_LBUTTONUP , wParam , lParam);
|
||
}
|
||
else
|
||
if (m_bUsePosition)
|
||
{
|
||
ScreenToClient (_hListBox , & Pos);
|
||
LPARAM lParam = MAKELPARAM (Pos . x , Pos . y);
|
||
WPARAM wParam = (m_bUseShift ? MK_SHIFT : 0) | (m_bUseControl ? MK_CONTROL : 0);
|
||
|
||
PostMessage (_hListBox , WM_LBUTTONDOWN , wParam | MK_LBUTTON , lParam);
|
||
PostMessage (_hListBox , WM_LBUTTONUP , wParam , lParam);
|
||
}
|
||
else
|
||
{
|
||
HWND hParentWnd = GetParent (_hListBox);
|
||
if (GetWindowLong (_hListBox , GWL_STYLE) & (LBS_EXTENDEDSEL | LBS_MULTIPLESEL))
|
||
{
|
||
// if not add, unselect all
|
||
if (! _bAddToSelection)
|
||
SendMessage (_hListBox , LB_SETSEL , FALSE , - 1);
|
||
SendMessage (_hListBox , LB_SETSEL , TRUE , _iLineNumber - 1);
|
||
}
|
||
else
|
||
SendMessage (_hListBox , LB_SETCURSEL , _iLineNumber - 1 , 0);
|
||
|
||
PostMessage (hParentWnd , WM_COMMAND , (LBN_SELCHANGE << 16) + GetDlgCtrlID (_hListBox) , (LPARAM) _hListBox);
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vSelectLineInListCtrl
|
||
// Simulate a selection into a list control
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vSelectLineInListCtrl (HWND _hListCtrl , int _iLineNumber)
|
||
{
|
||
m_fn_vSetGetLastError (TUT_C_iNoError);
|
||
|
||
int iListCtrlGetCount = ListView_GetItemCount (_hListCtrl);
|
||
if (_iLineNumber < 1 || _iLineNumber > iListCtrlGetCount)
|
||
{
|
||
m_fn_vSetGetLastError (TUT_C_iError_ListCtrlInvalidLine);
|
||
return;
|
||
}
|
||
|
||
// To be sure the line will be visible
|
||
ListView_EnsureVisible (_hListCtrl , _iLineNumber - 1 , FALSE);
|
||
|
||
// Compute the position of the selected line to move the mouse to
|
||
CRect stItemRect;
|
||
ListView_GetItemRect (_hListCtrl , _iLineNumber - 1 , & stItemRect , LVIR_BOUNDS);
|
||
POINT stPos;
|
||
stPos . x = min (stItemRect . CenterPoint () . x , stItemRect . left + 2 * stItemRect . Height ());
|
||
stPos . y = stItemRect . CenterPoint () . y;
|
||
LPARAM lParam = MAKELPARAM (stPos . x , stPos . y);
|
||
WPARAM wParam = (m_bUseShift ? MK_SHIFT : 0) | (m_bUseControl ? MK_CONTROL : 0);
|
||
|
||
if (m_bUseRightButton)
|
||
{
|
||
ClientToScreen (_hListCtrl , & stPos);
|
||
m_fn_vMoveMouseCursor (stPos);
|
||
PostMessage (_hListCtrl , WM_RBUTTONDOWN , wParam + MK_RBUTTON , lParam);
|
||
PostMessage (_hListCtrl , WM_RBUTTONUP , wParam , lParam);
|
||
}
|
||
else
|
||
if (m_bUseDoubleClic)
|
||
{
|
||
ClientToScreen (_hListCtrl , & stPos);
|
||
m_fn_vMoveMouseCursor (stPos);
|
||
|
||
PostMessage (_hListCtrl , WM_LBUTTONDOWN , wParam + MK_LBUTTON , lParam);
|
||
PostMessage (_hListCtrl , WM_LBUTTONUP , wParam , lParam);
|
||
PostMessage (_hListCtrl , WM_LBUTTONDBLCLK , wParam + MK_LBUTTON , lParam);
|
||
PostMessage (_hListCtrl , WM_LBUTTONUP , wParam , lParam);
|
||
}
|
||
else
|
||
{
|
||
if (m_bUsePosition)
|
||
{
|
||
if (m_bPercentForX)
|
||
if (m_bRightBorder ) stPos . x = stItemRect . right - stItemRect . Width () * m_iXPosition / 100;
|
||
else stPos . x = stItemRect . left + stItemRect . Width () * m_iXPosition / 100;
|
||
else
|
||
if (m_bRightBorder ) stPos . x = stItemRect . right - m_iXPosition;
|
||
else stPos . x = stItemRect . left + m_iXPosition;
|
||
|
||
if (m_bPercentForY)
|
||
if (m_bBottomBorder) stPos . y = stItemRect . bottom - stItemRect . Height () * m_iYPosition / 100;
|
||
else stPos . y = stItemRect . top + stItemRect . Height () * m_iYPosition / 100;
|
||
else
|
||
if (m_bBottomBorder) stPos . y = stItemRect . bottom - m_iYPosition;
|
||
else stPos . y = stItemRect . top + m_iYPosition;
|
||
|
||
lParam = MAKELPARAM (stPos . x , stPos . y);
|
||
}
|
||
|
||
ClientToScreen (_hListCtrl , & stPos);
|
||
m_fn_vMoveMouseCursor (stPos);
|
||
|
||
PostMessage (_hListCtrl , WM_LBUTTONDOWN , wParam + MK_LBUTTON , lParam);
|
||
PostMessage (_hListCtrl , WM_LBUTTONUP , wParam , lParam);
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vEnsureVisibleInTree
|
||
// Make sure the given item of a tree is visible or invisible
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vEnsureVisibleInTree (HWND _hTreeCtrl , HTREEITEM _hItem ,
|
||
BOOL _bEnsureVisible /* = TRUE */)
|
||
|
||
{
|
||
// Get the parent item. If there is no parent, we show the item and we return
|
||
HTREEITEM hParentItem = TreeView_GetParent (_hTreeCtrl , _hItem);
|
||
if (! hParentItem)
|
||
{
|
||
TreeView_EnsureVisible (_hTreeCtrl , _hItem);
|
||
return;
|
||
}
|
||
|
||
// If the parent is not visible, we make it visible (recursiv call)
|
||
if (! m_fn_bIsItemVisibleInTree (_hTreeCtrl , hParentItem))
|
||
m_fn_vEnsureVisibleInTree (_hTreeCtrl , hParentItem);
|
||
|
||
// Now that the parent is visible, we check if its children are visible
|
||
if (m_fn_uiGetTreeCtrlState (_hTreeCtrl , hParentItem , TVIS_EXPANDED) != TVIS_EXPANDED)
|
||
{
|
||
CRect Rect;
|
||
TreeView_GetItemRect (_hTreeCtrl , hParentItem , & Rect , FALSE);
|
||
POINT Pos;
|
||
Pos . x = Rect . left + Rect . Height () / 2;
|
||
Pos . y = Rect . CenterPoint () . y;
|
||
ClientToScreen (_hTreeCtrl , & Pos);
|
||
|
||
m_fn_vMoveMouseCursor (Pos);
|
||
TreeView_Expand (_hTreeCtrl , hParentItem , _bEnsureVisible ? TVE_EXPAND : TVE_COLLAPSE);
|
||
}
|
||
|
||
if (_bEnsureVisible) TreeView_EnsureVisible (_hTreeCtrl , _hItem);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_bSelectItemInTreeBox
|
||
// Simulate a selection in a tree box
|
||
// Return FALSE if there is no item with the given text
|
||
//-----------------------------------------------------------------------------
|
||
BOOL TUT_CTutorialManager::m_fn_bSelectItemInTreeBox (HWND _hTreeCtrl , CString _csTextToSelect)
|
||
{
|
||
HTREEITEM hRootItem = TreeView_GetRoot (_hTreeCtrl);
|
||
HTREEITEM hItemToSelect = m_fn_hFindStringInTree (_hTreeCtrl , hRootItem , _csTextToSelect);
|
||
if (! hItemToSelect) return FALSE; // Not found -> return FALSE
|
||
|
||
m_fn_vEnsureVisibleInTree (_hTreeCtrl , hItemToSelect , TRUE);
|
||
|
||
CRect Rect;
|
||
TreeView_GetItemRect (_hTreeCtrl , hItemToSelect , & Rect , FALSE);
|
||
POINT Pos;
|
||
Pos . x = Rect . left + Rect . Height () * 4;
|
||
Pos . y = Rect . CenterPoint () . y;
|
||
ClientToScreen (_hTreeCtrl , & Pos);
|
||
|
||
// Select the item
|
||
m_fn_vMoveMouseCursor (Pos);
|
||
TreeView_SelectItem (_hTreeCtrl , hItemToSelect);
|
||
|
||
// Send a second notification to the parent, because the first one sent by TreeView_SelectItem did not have action = TVC_BYMOUSE
|
||
NM_TREEVIEW stTreeView;
|
||
stTreeView . hdr . hwndFrom = _hTreeCtrl;
|
||
stTreeView . hdr . idFrom = GetDlgCtrlID (_hTreeCtrl);
|
||
stTreeView . hdr . code = TVN_SELCHANGED;
|
||
stTreeView . action = TVC_BYMOUSE;
|
||
SendMessage (GetParent (_hTreeCtrl) , WM_NOTIFY , GetDlgCtrlID (_hTreeCtrl) , (LPARAM) & stTreeView);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vWriteText
|
||
// Write a line of text into a tutorial window
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vWriteText (HWND _hEditView , CString _csText)
|
||
{
|
||
ASSERT (IsWindow (_hEditView)); // The edit view must be correct
|
||
|
||
HWND hPreviousWnd = GetForegroundWindow ();
|
||
|
||
// Put the caret at the end of the text
|
||
int iNumberOfChar = GetWindowTextLength (_hEditView);
|
||
SendMessage (_hEditView , EM_SETSEL , iNumberOfChar , iNumberOfChar);
|
||
|
||
// Change the format
|
||
CHARFORMAT stCharFormat;
|
||
stCharFormat . cbSize = sizeof (CHARFORMAT);
|
||
stCharFormat . dwMask = CFM_COLOR | CFM_SIZE | CFM_FACE;
|
||
stCharFormat . dwEffects &= ~ CFE_AUTOCOLOR; // Remove the flag "auto color"
|
||
stCharFormat . crTextColor = m_xCurrentColor;
|
||
stCharFormat . yHeight = m_lCurrentHeight * GetDeviceCaps (GetDC (_hEditView) , LOGPIXELSY) * 180 / 1000;
|
||
strcpy (stCharFormat . szFaceName , "Arial");
|
||
SendMessage (_hEditView , EM_SETCHARFORMAT , SCF_SELECTION , (LPARAM) & stCharFormat);
|
||
|
||
PARAFORMAT stParaFormat;
|
||
stParaFormat . cbSize = sizeof (PARAFORMAT);
|
||
stParaFormat . dwMask = PFM_ALIGNMENT;
|
||
stParaFormat . wAlignment = (unsigned short) m_lCurrentAlignment;
|
||
SendMessage (_hEditView ,EM_SETPARAFORMAT , 0 , (LPARAM) & stParaFormat);
|
||
|
||
// Insert the new text
|
||
if (_csText . Right (1) == "\\") _csText = _csText . Left (_csText . GetLength () - 1); // If the string ends with '\', no line feed
|
||
else
|
||
{
|
||
_csText += (char)13;
|
||
_csText += (char)10;
|
||
}
|
||
SendMessage (_hEditView , EM_REPLACESEL , FALSE /* No Undo */ , (LPARAM) (LPCTSTR) _csText);
|
||
|
||
// Check if scroll is necessary
|
||
RECT stEditViewRect;
|
||
GetClientRect (_hEditView , & stEditViewRect);
|
||
POINT stEndOfTextPos;
|
||
BOOL bOk;
|
||
int iCounter = 0;
|
||
do
|
||
{
|
||
SendMessage (_hEditView , EM_POSFROMCHAR , (WPARAM) & stEndOfTextPos , GetWindowTextLength (_hEditView));
|
||
bOk = stEndOfTextPos . y <= stEditViewRect . bottom;
|
||
if (! bOk) SendMessage (_hEditView , EM_LINESCROLL , 0 , 1);
|
||
} while (bOk == FALSE && ++iCounter < 10); // To prevent from infinite loop
|
||
|
||
InvalidateRect (_hEditView , NULL , FALSE);
|
||
UpdateWindow (_hEditView);
|
||
|
||
SetForegroundWindow (hPreviousWnd);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_vSendKey
|
||
// Send a key
|
||
//-----------------------------------------------------------------------------
|
||
void TUT_CTutorialManager::m_fn_vSendKey (int _iVirtualKeyCode , BOOL _bKeyPressed)
|
||
{
|
||
keybd_event (_iVirtualKeyCode , _iVirtualKeyCode , _bKeyPressed ? 0 : KEYEVENTF_KEYUP , 0);
|
||
Sleep (10);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// class TUT_CTutorialManager - m_fn_szHandleQuote
|
||
// replace two consecutive quotes by a double-quote
|
||
//-----------------------------------------------------------------------------
|
||
char *TUT_CTutorialManager::m_fn_szHandleQuote(char * _szString)
|
||
{
|
||
char *cBegin = _szString;
|
||
char *cTarget = _szString;
|
||
char *cSource = _szString;
|
||
BOOL bPreviousQuote = FALSE;
|
||
|
||
while (*cSource)
|
||
{
|
||
if (*cSource == '\'')
|
||
{
|
||
if (bPreviousQuote)
|
||
{
|
||
*cTarget++ = '\"';
|
||
bPreviousQuote = FALSE;
|
||
}
|
||
else
|
||
{
|
||
bPreviousQuote = TRUE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (bPreviousQuote)
|
||
{
|
||
*cTarget++ = '\'';
|
||
}
|
||
*cTarget++ = *cSource;
|
||
bPreviousQuote = FALSE;
|
||
}
|
||
cSource++;
|
||
}
|
||
if (bPreviousQuote)
|
||
{
|
||
*cTarget++ = '\'';
|
||
}
|
||
|
||
*cTarget = 0;
|
||
|
||
return _szString;
|
||
} |