529 lines
13 KiB
C++
529 lines
13 KiB
C++
#include "stdafx.h"
|
|
#include "KUIDefine.h"
|
|
#include "KUIParser.h"
|
|
#include "KUIFactory.h"
|
|
//#include "KUIUtil.h"
|
|
|
|
#pragma warning(disable:4267)
|
|
#pragma warning(disable:4312)
|
|
|
|
namespace KTOKEN_HANDLER
|
|
{
|
|
const int KTOKEN_BEGIN = 40;
|
|
const int KTOKEN_END = 41;
|
|
|
|
const int KTOKEN_ID = 42;
|
|
const int KTOKEN_ANI = 43;
|
|
const int KTOKEN_SPR = 44;
|
|
const int KTOKEN_FRAME = 45;
|
|
|
|
const int KTOKEN_RECT = 46;
|
|
const int KTOKEN_POS = 47;
|
|
|
|
const int KTOKEN_CAPTION = 48;
|
|
const int KTOKEN_TOOLTIP = 49;
|
|
|
|
const int KTOKEN_STYLE = 50;
|
|
const int KTOKEN_FLAG = 51;
|
|
const int KTOKEN_ANCHOR = 52;
|
|
|
|
const int KTOKEN_ADD_BUTTON = 53;
|
|
|
|
const int KTOKEN_GENWND = 54;
|
|
}
|
|
|
|
BEGIN_KTOKEN_MAP(KUIParser)
|
|
ON_KTOKEN("begin",KTOKEN_BEGIN,&KUIParser::_OnBeginToken)
|
|
ON_KTOKEN("end",KTOKEN_END,&KUIParser::_OnEndToken)
|
|
|
|
ON_KTOKEN("id",KTOKEN_ID, &KUIParser::_OnPropetyToken)
|
|
ON_KTOKEN("ani",KTOKEN_ANI, &KUIParser::_OnPropetyToken)
|
|
ON_KTOKEN("spr",KTOKEN_SPR, &KUIParser::_OnPropetyToken)
|
|
ON_KTOKEN("frame",KTOKEN_FRAME, &KUIParser::_OnPropetyToken)
|
|
|
|
ON_KTOKEN("rect",KTOKEN_RECT, &KUIParser::_OnPropetyToken)
|
|
ON_KTOKEN("pos",KTOKEN_POS, &KUIParser::_OnPropetyToken)
|
|
|
|
ON_KTOKEN("caption", KTOKEN_CAPTION, &KUIParser::_OnPropetyToken)
|
|
//ON_KTOKEN("tooltip",KTOKEN_TOOLTIP,&KUIParser::_OnPropetyToken)
|
|
ON_KTOKEN("info",KTOKEN_TOOLTIP,&KUIParser::_OnPropetyToken)
|
|
|
|
ON_KTOKEN("style", KTOKEN_STYLE, &KUIParser::_OnPropetyToken)
|
|
ON_KTOKEN("flag",KTOKEN_FLAG,&KUIParser::_OnPropetyToken)
|
|
ON_KTOKEN("anchor",KTOKEN_ANCHOR,&KUIParser::_OnPropetyToken)
|
|
|
|
ON_KTOKEN("add_button",KTOKEN_ADD_BUTTON,&KUIParser::_OnPropetyToken)
|
|
|
|
ON_KTOKEN("genwnd", KTOKEN_GENWND, &KUIParser::_OnGenWndCreate )
|
|
END_KTOKEN_MAP()
|
|
|
|
|
|
namespace
|
|
{
|
|
std::map<std::string, DWORD> MAP_STYLE;
|
|
std::map<std::string, DWORD> MAP_FLAG;
|
|
std::map<std::string, DWORD> MAP_ANCHOR;
|
|
|
|
struct MAPPING_INFO
|
|
{
|
|
DWORD dwFlag;
|
|
std::string sName;
|
|
};
|
|
|
|
void registerMappingInfo(std::map<std::string, DWORD>& mapInfo, MAPPING_INFO* pInfoArray, int nCount)
|
|
{
|
|
|
|
for(int i = 0; i < nCount; ++i)
|
|
mapInfo.insert( std::make_pair( pInfoArray[i].sName, pInfoArray[i].dwFlag) );
|
|
}
|
|
|
|
bool initMapInfo()
|
|
{
|
|
|
|
MAPPING_INFO STYLE_ARRAY[] =
|
|
{
|
|
// GenWnd
|
|
{ KSTYLE_NOCLOSE, "KSTYLE_NOCLOSE" },
|
|
{ KSTYLE_NOMINIMIZE, "KSTYLE_NOMINIMIZE" },
|
|
{ KSTYLE_NORESIZE, "KSTYLE_NORESIZE" },
|
|
{ KSTYLE_NOTITLE, "KSTYLE_NOTITLE" },
|
|
{ KSTYLE_NOSTATUSBAR, "KSTYLE_NOSTATUSBAR" },
|
|
{ KSTYLE_VSCROLL, "KSTYLE_VSCROLL"},
|
|
{ KSTYLE_HSCROLL, "KSTYLE_HSCROLL"},
|
|
|
|
{ KSTYLE_NOFRAME, "KSTYLE_NOFRAME"},
|
|
{ KSTYLE_NOTOPFRAME, "KSTYLE_NOTOPFRAME"},
|
|
{ KSTYLE_NOBACKGROUND, "KSTYLE_NOBACKGROUND"},
|
|
{ KSTYLE_RESIZE_LEFT, "KSTYLE_RESIZE_LEFT"},
|
|
{ KSTYLE_RESIZE_TOP, "KSTYLE_RESIZE_TOP"},
|
|
|
|
{ KSTYLE_MOVE_BY_TITLEBAR, "KSTYLE_MOVE_BY_TITLEBAR"},
|
|
{ KSTYLE_MOVE_BY_TOPFRAME, "KSTYLE_MOVE_BY_TOPFRAME"},
|
|
{ KSTYLE_MOVE_BY_ALL, "KSTYLE_MOVE_BY_ALL"},
|
|
{ KSTYLE_MOVE_BY_CUSTOM, "KSTYLE_MOVE_BY_CUSTOM"},
|
|
|
|
{ KSTYLE_NO_CLIPPING, "KSTYLE_NO_CLIPPING"},
|
|
|
|
{ KSTYLE_VERTICAL_REPEAT, "KSTYLE_VERTICAL_REPEAT"},
|
|
{ KSTYLE_HORIZONTAL_REPEAT, "KSTYLE_HORIZONTAL_REPEAT"},
|
|
|
|
{ KSTYLE_SPR_CAPTION, "KSTYLE_SPR_CAPTION"},
|
|
{ KSTYLE_ALPHA_SHOW, "KSTYLE_ALPHA_SHOW" },
|
|
|
|
// button
|
|
{ KSTYLE_BUTTON_LEFTSIDE, "KSTYLE_BUTTON_LEFTSIDE"},
|
|
{ KSTYLE_BUTTON_RIGHTSIDE, "KSTYLE_BUTTON_RIGHTSIDE"},
|
|
{ KSTYLE_BUTTON_CANDRAG, "KSTYLE_BUTTON_CANDRAG"},
|
|
{ KSTYLE_BUTTON_VERTICAL, "KSTYLE_BUTTON_VERTICAL"},
|
|
|
|
{ KSTYLE_CHECK_CAPTION_RIGHT, "KSTYLE_CHECK_CAPTION_RIGHT"},
|
|
|
|
|
|
// status bar
|
|
{ KSTYLE_SB_NOLEFTSIDE, "KSTYLE_SB_NOLEFTSIDE"},
|
|
{ KSTYLE_SB_NORIGHTSIDE, "KSTYLE_SB_NORIGHTSIDE"},
|
|
|
|
// Tab Control
|
|
{ KSTYLE_TAB_VERTICAL, "KSTYLE_TAB_VERTICAL"},
|
|
|
|
// Number Control
|
|
{ KSTYLE_NUMBER_LEFT, "KSTYLE_NUMBER_LEFT"},
|
|
{ KSTYLE_NUMBER_CENTER, "KSTYLE_NUMBER_CENTER"},
|
|
{ KSTYLE_NUMBER_RIGHT, "KSTYLE_NUMBER_RIGHT"},
|
|
|
|
// Gauge Control
|
|
{ KSTYLE_GAUGE_WITH_GRADUATION, "KSTYLE_GAUGE_WITH_GRADUATION" },
|
|
|
|
// Msg Control
|
|
{ KSTYLE_MSG_VERTICAL_REPEAT, "KSTYLE_MSG_VERTICAL_REPEAT"},
|
|
{ KSTYLE_MSG_HORIZONTAL_REPEAT, "KSTYLE_MSG_HORIZONTAL_REPEAT"},
|
|
|
|
};
|
|
|
|
registerMappingInfo( MAP_STYLE, STYLE_ARRAY, _countof(STYLE_ARRAY) );
|
|
|
|
MAPPING_INFO FLAG_ARRAY[] =
|
|
{
|
|
// GenWnd
|
|
{ KFLAG_NO_GET_MESSAGE, "KFLAG_NO_GET_MESSAGE" },
|
|
{ KFLAG_GET_PASS_MESSAGE, "KFLAG_GET_PASS_MESSAGE" },
|
|
{ KFLAG_CAN_DRAG, "KFLAG_CAN_DRAG" },
|
|
{ KFLAG_SINGLE_LINE, "KFLAG_SINGLE_LINE" },
|
|
{ KFLAG_NO_GET_FOCUS, "KFLAG_NO_GET_FOCUS" },
|
|
};
|
|
registerMappingInfo(MAP_FLAG ,FLAG_ARRAY, _countof(FLAG_ARRAY));
|
|
|
|
MAPPING_INFO ANCHOR_ARRAY[] =
|
|
{
|
|
// GenWnd
|
|
{ KANCHOR_LEFT, "KANCHOR_LEFT" },
|
|
{ KANCHOR_RIGHT, "KANCHOR_RIGHT" },
|
|
{ KANCHOR_TOP, "KANCHOR_TOP" },
|
|
{ KANCHOR_BOTTOM, "KANCHOR_BOTTOM" },
|
|
};
|
|
registerMappingInfo(MAP_ANCHOR, ANCHOR_ARRAY, _countof(ANCHOR_ARRAY));
|
|
return true;
|
|
}
|
|
|
|
DWORD getStringToDWORD(LPCSTR lpszName, std::map<std::string, DWORD>& mapInfo)
|
|
{
|
|
std::map<std::string, DWORD>::iterator it = mapInfo.find( std::string ( lpszName ) );
|
|
|
|
if( it == mapInfo.end() )
|
|
return 0;
|
|
|
|
return it->second;
|
|
}
|
|
|
|
bool bInitMapInfo = initMapInfo();
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KUIParser Implement
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
KUIParser::KUIParser()
|
|
{
|
|
static char Whitespacechr[] = {'\n', '\r', ' ', '\t', '|'};
|
|
static char Tokendata[] =
|
|
{
|
|
KTOKEN_HANDLER::KTOKEN_COMMA, ',' ,
|
|
KTOKEN_HANDLER::KTOKEN_ASSIGN, '=' ,
|
|
KTOKEN_HANDLER::KTOKEN_SEMI_COLON, ';' ,
|
|
};
|
|
|
|
m_TokenParser.SetWhiteSpaceChar(Whitespacechr, _countof(Whitespacechr) );
|
|
m_TokenParser.SetTokenChar(Tokendata, _countof(Tokendata) );
|
|
|
|
_InitializeTokenMap();
|
|
Clear();
|
|
}
|
|
|
|
KUIParser::~KUIParser()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void KUIParser::Clear()
|
|
{
|
|
m_bErrorFound = false;
|
|
m_nStage = KSTAGE_CONTROL_START; m_nSubStage = 0;
|
|
m_pParentObj = NULL;
|
|
SAFE_DELETE_VECTOR( m_vtParseObj );
|
|
|
|
}
|
|
|
|
bool KUIParser::DoParsing(KStream& stream)
|
|
{
|
|
Clear();
|
|
m_TokenParser.LoadStream(stream);
|
|
return !m_bErrorFound;
|
|
}
|
|
|
|
DWORD KUIParser::GetParseObjCount()
|
|
{
|
|
return m_vtParseObj.size();
|
|
}
|
|
KUIWndParseObject* KUIParser::GetParseObject(DWORD dwIndex)
|
|
{
|
|
if( dwIndex >= m_vtParseObj.size() )
|
|
{
|
|
assert(false && "Invalid Index");
|
|
return NULL;
|
|
}
|
|
|
|
return m_vtParseObj[dwIndex];
|
|
}
|
|
|
|
|
|
K_TOKEN_CALL void KUIParser::_OnNoTokenFound(DWORD dwStringPointer, DWORD dwLineCount,DWORD dwReserve1)
|
|
{
|
|
|
|
LPCSTR lpszToken = reinterpret_cast<LPCSTR>(dwStringPointer);
|
|
|
|
// Create 상태다
|
|
|
|
switch( m_nStage)
|
|
{
|
|
case KSTAGE_CONTROL_CREATE:
|
|
|
|
// 찾을수 없는 control
|
|
if( false == KUIFactory::GetInstance()->IsRegister( lpszToken) )
|
|
{
|
|
// 무조건 Error
|
|
_ErrMsgBox("파싱 에러 %d Line. 등록되지 않은 Control 입니다", dwLineCount);
|
|
return;
|
|
}
|
|
|
|
m_CurrentArg.lpszClassName = lpszToken;
|
|
m_nStage = KSTAGE_CONTROL_PROPERTY;
|
|
break;
|
|
|
|
case KSTAGE_CONTROL_ASSIGN:
|
|
_DoAssign( lpszToken, dwLineCount);
|
|
break;
|
|
|
|
default:
|
|
_ErrMsgBox("파싱 에러 %d Line. 알수 없는 Token ( %s ) 입니다", dwLineCount, lpszToken);
|
|
assert( 0 && "NUI 파싱 에러" );
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
K_TOKEN_CALL void KUIParser::_OnCharTokenFound(DWORD dwCharType, DWORD dwLineCount, DWORD dwReserve1)
|
|
{
|
|
switch( dwCharType )
|
|
{
|
|
case KTOKEN_HANDLER::KTOKEN_SEMI_COLON:
|
|
{
|
|
_CheckStageError(KSTAGE_CONTROL_ASSIGN, dwLineCount);
|
|
m_nStage = KSTAGE_CONTROL_PROPERTY;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
K_TOKEN_CALL void KUIParser::_OnTokenEnd()
|
|
{
|
|
if( m_nStage != KSTAGE_CONTROL_START)
|
|
_ErrMsgBox(" end 를 빼먹었습니다");
|
|
}
|
|
|
|
K_TOKEN_CALL void KUIParser::_OnBeginToken(DWORD dwTokenID, DWORD dwLineCount,DWORD dwReserve2)
|
|
{
|
|
_CheckStageError(KSTAGE_CONTROL_START, dwLineCount);
|
|
m_nStage = KSTAGE_CONTROL_CREATE;
|
|
|
|
// Argument 초기화
|
|
m_CurrentArg = KUIWND_CREATE_ARG();
|
|
}
|
|
K_TOKEN_CALL void KUIParser::_OnEndToken(DWORD dwTokenID, DWORD dwLineCount,DWORD dwReserve2)
|
|
{
|
|
_CheckStageError(KSTAGE_CONTROL_PROPERTY,dwLineCount);
|
|
m_nStage = KSTAGE_CONTROL_START;
|
|
|
|
if( NULL == m_pParentObj)
|
|
return;
|
|
|
|
if (m_CurrentArg.lpszClassName != "genwnd" )
|
|
m_pParentObj->AddChildObj( m_CurrentArg );
|
|
else
|
|
m_pParentObj->SetCreateArg( m_CurrentArg );
|
|
|
|
}
|
|
K_TOKEN_CALL void KUIParser::_OnPropetyToken(DWORD dwTokenID, DWORD dwLineCount,DWORD dwReserve1)
|
|
{
|
|
_CheckStageError(KSTAGE_CONTROL_PROPERTY,dwLineCount);
|
|
m_nStage = KSTAGE_CONTROL_ASSIGN;
|
|
m_nSubStage = dwTokenID;
|
|
}
|
|
|
|
K_TOKEN_CALL void KUIParser::_OnGenWndCreate(DWORD dwTokenID, DWORD dwLineCount,DWORD dwReserve1)
|
|
{
|
|
_CheckStageError(KSTAGE_CONTROL_CREATE,dwLineCount);
|
|
m_nStage = KSTAGE_CONTROL_PROPERTY;
|
|
|
|
m_pParentObj = new KUIWndParseObject;
|
|
m_CurrentArg.lpszClassName = "genwnd";
|
|
m_vtParseObj.push_back( m_pParentObj) ;
|
|
}
|
|
|
|
void KUIParser::_DoAssign(LPCSTR lpszToken, DWORD dwLineCount)
|
|
{
|
|
_CheckStageError(KSTAGE_CONTROL_ASSIGN, dwLineCount);
|
|
|
|
int IntValue = ::atoi( lpszToken);
|
|
using namespace KTOKEN_HANDLER;
|
|
switch ( m_nSubStage)
|
|
{
|
|
case KTOKEN_ID:
|
|
m_CurrentArg.lpszID = lpszToken;
|
|
break;
|
|
case KTOKEN_ANI:
|
|
m_CurrentArg.lpszAniName = lpszToken;
|
|
break;
|
|
case KTOKEN_SPR:
|
|
m_CurrentArg.lpszSprName = lpszToken;
|
|
break;
|
|
case KTOKEN_FRAME:
|
|
m_CurrentArg.nFrameIndex = IntValue;
|
|
break;
|
|
case KTOKEN_RECT:
|
|
{
|
|
static int nRectCount = 0;
|
|
static int nRectArray[4];
|
|
|
|
nRectArray[nRectCount] = IntValue;
|
|
nRectCount++;
|
|
|
|
if(nRectCount == 4)
|
|
{
|
|
m_CurrentArg.rcRect = KRect(nRectArray[0], nRectArray[1], nRectArray[2], nRectArray[3]);
|
|
nRectCount = 0;
|
|
}
|
|
}
|
|
break;
|
|
case KTOKEN_POS:
|
|
{
|
|
static int nPosCount = 0;
|
|
static int nPosArray[2];
|
|
|
|
nPosArray[nPosCount] = IntValue;
|
|
nPosCount++;
|
|
|
|
if(nPosCount == 2)
|
|
{
|
|
m_CurrentArg.rcRect = KRect(nPosArray[0], nPosArray[1], -1, -1);
|
|
nPosCount = 0;
|
|
}
|
|
}
|
|
break;
|
|
case KTOKEN_CAPTION:
|
|
m_CurrentArg.lpszCaption = lpszToken;
|
|
break;
|
|
|
|
case KTOKEN_TOOLTIP:
|
|
m_CurrentArg.lpszToolTip = lpszToken;
|
|
break;
|
|
|
|
case KTOKEN_STYLE:
|
|
{
|
|
DWORD dwStyle = getStringToDWORD( lpszToken, MAP_STYLE);
|
|
if( dwStyle == 0)
|
|
_ErrMsgBox( "파싱 에러 %d. 잘못된 Style (%s) 입니다.", dwLineCount, lpszToken);
|
|
|
|
m_CurrentArg.dwStyle |= dwStyle;
|
|
}
|
|
break;
|
|
case KTOKEN_FLAG:
|
|
{
|
|
DWORD dwFlag = getStringToDWORD( lpszToken, MAP_FLAG);
|
|
|
|
if( dwFlag == 0)
|
|
_ErrMsgBox( "파싱 에러 %d. 잘못된 Flag (%s) 입니다.", dwLineCount, lpszToken);
|
|
|
|
m_CurrentArg.dwFlag |= dwFlag;
|
|
}
|
|
break;
|
|
case KTOKEN_ANCHOR:
|
|
{
|
|
DWORD dwAnchor = getStringToDWORD( lpszToken, MAP_ANCHOR);
|
|
|
|
if( dwAnchor == 0)
|
|
_ErrMsgBox( "파싱 에러 %d. 잘못된 Anchor (%s) 입니다.", dwAnchor, lpszToken);
|
|
|
|
m_CurrentArg.dwAnchor |= dwAnchor;
|
|
}
|
|
break;
|
|
case KTOKEN_ADD_BUTTON:
|
|
break;
|
|
default:
|
|
_CheckStageError( -1, dwLineCount);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
void KUIParser::_CheckStageError(int nStage, DWORD dwLineNumber)
|
|
{
|
|
if(m_nStage != nStage)
|
|
{
|
|
char buff[512];
|
|
switch( nStage)
|
|
{
|
|
case KSTAGE_CONTROL_START:
|
|
sprintf(buff, "begin의 시작전에 잘 못된 값이 존재합니다");
|
|
break;
|
|
case KSTAGE_CONTROL_CREATE:
|
|
sprintf(buff, "begin Keyword가 필요합니다");
|
|
break;
|
|
case KSTAGE_CONTROL_PROPERTY:
|
|
sprintf(buff, " ; (semi colon)을 빼먹거나 Control을 생성하지 않았습니다");
|
|
break;
|
|
case KSTAGE_CONTROL_ASSIGN:
|
|
sprintf(buff, "Control의 속성을 지정하는 Keyword 이후에 사용해야 합니다");
|
|
break;
|
|
default:
|
|
sprintf(buff, "알수 없는 오류입니다");
|
|
break;
|
|
}
|
|
|
|
_ErrMsgBox( "파싱 에러 %d Line. %s", dwLineNumber, buff);
|
|
}
|
|
}
|
|
|
|
void KUIParser::_ErrMsgBox(LPCSTR lpszString, ...)
|
|
{
|
|
#ifndef NDEBUG
|
|
#ifndef _RELEASE
|
|
char szBuf[1024];
|
|
|
|
va_list va;
|
|
va_start( va, lpszString );
|
|
_vsnprintf( szBuf, _countof(szBuf), lpszString, va );
|
|
va_end( va );
|
|
|
|
MessageBox( NULL, szBuf, "Error", MB_OK);
|
|
#endif
|
|
#endif
|
|
|
|
m_bErrorFound = true;
|
|
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// KUIWndParseObject Implement
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
KUIWndParseObject::KUIWndParseObject()
|
|
{
|
|
}
|
|
|
|
KUIWndParseObject::~KUIWndParseObject()
|
|
{
|
|
SAFE_DELETE_VECTOR( m_vtChildParseObj );
|
|
}
|
|
|
|
DWORD KUIWndParseObject::GetChildCount()
|
|
{
|
|
return m_vtChildParseObj.size();
|
|
}
|
|
KUIWndParseObject* KUIWndParseObject::GetChildParseObj(DWORD dwIndex)
|
|
{
|
|
if( dwIndex >= m_vtChildParseObj.size() )
|
|
{
|
|
assert(false && "Invalid Index");
|
|
return NULL;
|
|
}
|
|
|
|
return m_vtChildParseObj[dwIndex];
|
|
}
|
|
|
|
KUIWndParseObject* KUIWndParseObject::AddChildObj(const KUIWND_CREATE_ARG& arg)
|
|
{
|
|
KUIWndParseObject* pObj = new KUIWndParseObject;
|
|
pObj->SetCreateArg( arg );
|
|
|
|
m_vtChildParseObj.push_back( pObj );
|
|
return m_vtChildParseObj.back();
|
|
}
|
|
|
|
const KUIWND_CREATE_ARG& KUIWndParseObject::GetCreateArg() const
|
|
{
|
|
return m_CreateArg;
|
|
}
|
|
KUIWND_CREATE_ARG& KUIWndParseObject::GetCreateArg()
|
|
{
|
|
return m_CreateArg;
|
|
}
|
|
|
|
void KUIWndParseObject::SetCreateArg(const KUIWND_CREATE_ARG& arg)
|
|
{
|
|
m_CreateArg = arg;
|
|
} |