void MkFileSystem::SetSystemSetting(const MkDataNode& node)
{
	// chunk size
	unsigned int chunkSizeInMB;
	if (node.GetData(L"ChunkSizeInMB", chunkSizeInMB, 0))
	{
		SetChunkSizeGuideline(chunkSizeInMB);
	}

	// comp limit
	unsigned int percentageForCompressing;
	if (node.GetData(L"PercentageForCompressing", percentageForCompressing, 0))
	{
		SetPercentageForCompressing(percentageForCompressing);
	}

	// name rule
	MkStr prefix, extension;
	if (node.GetData(L"Prefix", prefix, 0) && node.GetData(L"Extension", extension, 0))
	{
		SetChunkFileNamingRule(prefix, extension);
	}

	// filtering
	MkArray<MkStr> filterBuffer;
	MkArray<MkPathName> exceptionFilter;
	if (node.GetData(L"ExceptionFilter", filterBuffer))
	{
		exceptionFilter.Reserve(filterBuffer.GetSize());
		MK_INDEXING_LOOP(filterBuffer, i)
		{
			exceptionFilter.PushBack(filterBuffer[i]);
		}
void MkCheckBoxControlNode::Save(MkDataNode& node) const
{
	// caption, on icon 제외
	static MkArray<MkHashStr> exceptions(2);
	if (exceptions.Empty())
	{
		exceptions.PushBack(CaptionNodeName);
		exceptions.PushBack(CheckIconName);
	}
	_AddExceptionList(node, SystemKey_NodeExceptions, exceptions);

	// run
	MkWindowBaseNode::Save(node);
}
Beispiel #3
0
unsigned int MkLineShape::AddLine(const MkArray<MkFloat2>& vertices)
{
	unsigned int count = 0;
	unsigned int vSize = vertices.GetSize();

	if (vSize > 1) // 최소 두개는 존재해야 가능
	{
		unsigned int index = m_LocalVertices.GetSize();

		if (vertices[0] != vertices[1])
		{
			m_LocalVertices.PushBack(vertices[0]);
		}

		for (unsigned int i=1; i<vSize; ++i)
		{
			const MkFloat2& begin = vertices[i - 1];
			const MkFloat2& end = vertices[i];
			if (begin != end)
			{
				m_LocalVertices.PushBack(vertices[i]); // current

				m_Indices.PushBack(index); // last
				++index;
				m_Indices.PushBack(index); // current

				++count;
			}
		}
	}
	return count;
}
bool MkWindowFactory::_IsMsgBoxButton(const MkArray<MkHashStr>& callerPath, const MkHashStr& msgBoxName, const MkHashStr& buttonName)
{
	return ((callerPath.GetSize() == 3) && // title -> body -> button
		(callerPath[0] == msgBoxName) &&
		(callerPath[1] == BodyFrameName) &&
		(callerPath[2] == buttonName));
}
bool MkCheatMessage::ExcuteMsg(const MkStr& command, const MkArray<MkStr>& argument, MkStr& resultMsg) const
{
	MkStr cmd = command;
	cmd.ToLower();

	if ((cmd == L"q") && argument.Empty())
	{
		MK_DEV_PANEL.__QuitApplication();
		return true;
	}

	if ((cmd == L"cls") && argument.Empty())
	{
		MK_DEV_PANEL.ClearLogWindow();
		return true;
	}

	return false;
}
Beispiel #6
0
void MkWindowThemedNode::SendNodeCommandTypeEvent(ePA_SceneNodeEvent eventType, MkDataNode* argument)
{
	switch (eventType)
	{
	case ePA_SNE_ChangeTheme:
		{
			MkArray<MkHashStr> names;
			if (argument->GetDataEx(ArgKey_ChangeTheme, names) && (names.GetSize() == 2))
			{
				if (names[0].Empty() || (names[0] == m_ThemeName))
				{
					SetThemeName(names[1]);
				}
			}
		}
		break;
	}
	
	MkVisualPatternNode::SendNodeCommandTypeEvent(eventType, argument);
}
void MkCheckBoxControlNode::SendNodeReportTypeEvent(ePA_SceneNodeEvent eventType, MkArray<MkHashStr>& path, MkDataNode* argument)
{
	// left cursor click이고 해당 window가 자신이면 toggle
	if ((eventType == ePA_SNE_CursorLBtnReleased) && path.Empty())
	{
		_SetCheck(!GetCheck(), true);
	}
	else
	{
		MkWindowBaseNode::SendNodeReportTypeEvent(eventType, path, argument);
	}
}
void MkCheckBoxControlNode::LoadObject(const MkDataNode& node)
{
	MkWindowBaseNode::LoadObject(node);

	// caption
	MkArray<MkHashStr> textName;
	if (node.GetDataEx(ObjKey_CaptionTextName, textName) && (!textName.Empty()))
	{
		MkStr caption;
		node.GetData(ObjKey_CaptionString, caption, 0);

		_SetCaption(textName, caption);
	}

	// check
	bool onCheck;
	if (node.GetData(ObjKey_OnCheck, onCheck, 0))
	{
		SetCheck(onCheck);
	}
}
Beispiel #9
0
	virtual void SendNodeReportTypeEvent(ePA_SceneNodeEvent eventType, MkArray<MkHashStr>& path, MkDataNode* argument)
	{
		if ((eventType == ePA_SNE_CursorLBtnReleased) && (path.GetSize() == 1))
		{
			if (path[0] == BattleBtnName)
			{
				MK_PAGE_MGR.SetMoveMessage(GamePage::AppLobby::Condition::Battle);
				return;
			}
		}
	
		MkWindowManagerNode::SendNodeReportTypeEvent(eventType, path, argument);
	}
Beispiel #10
0
SupplementDef::eResult SupplementDef::GetResult(const MkArray<eUnit>& units, MkArray<unsigned int>& targetIndice)
{
	unsigned int unitSize = units.GetSize();

	// 유효성 검증
	MK_CHECK(unitSize <= ADEF_MAX_COMBINATION_SLOT_SIZE, L"입력된 unit 갯수가 " + MkStr(ADEF_MAX_COMBINATION_SLOT_SIZE) + L"개를 넘음 : " + MkStr(unitSize))
		return eR_None;

	MK_INDEXING_LOOP(units, i)
	{
		eUnit unit = units[i];
		MK_CHECK((unit == eU_Void) || IsNormalUnit(unit), L"입력된 unit list의 " + MkStr(i) + L"번째에 비정상 unit 존재 : " + MkStr(unit))
			return eR_None;
	}
void MkCheckBoxControlNode::_SetCaption(const MkArray<MkHashStr>& textNode, const MkStr& caption)
{
	if (textNode.Empty() || (!MK_STATIC_RES.TextNodeExist(textNode)))
	{
		RemoveChildNode(CaptionNodeName);
		m_CaptionString.Clear();
		return;
	}

	// MkWindowTagNode 사용
	MkWindowTagNode* node = NULL;
	if (ChildExist(CaptionNodeName))
	{
		node = dynamic_cast<MkWindowTagNode*>(GetChildNode(CaptionNodeName));
	}
	else
	{
		node = MkWindowTagNode::CreateChildNode(this, CaptionNodeName);
		if (node != NULL)
		{
			node->SetAlignmentPivotIsWindowRect(true);
			node->SetAlignmentPosition(eRAP_RMostCenter);
			node->SetAlignmentOffset(MkFloat2(node->GetLengthOfBetweenIconAndText(), 0.f));
		}
	}

	if (node != NULL)
	{
		m_CaptionString = caption;
		if (caption.Empty())
		{
			node->SetTextName(textNode);
		}
		else
		{
			node->SetTextName(textNode, caption);
		}
	}
}
Beispiel #12
0
void MkDataPack::GetValidUnitList(const MkDataPack& source, MkArray<MkHashStr>& keyList) const
{
	keyList.Clear();
	MkArray<MkHashStr> myOwn;
	GetUnitKeyList(myOwn);
	if (!myOwn.Empty())
	{
		keyList.Reserve(myOwn.GetSize());
		MK_INDEXING_LOOP(myOwn, i)
		{
			const MkHashStr& currKey = myOwn[i];
			if (!(source.IsValidKey(currKey) && source.Equals(currKey, *m_UnitTable[currKey])))
			{
				keyList.PushBack(currKey); // 자신에게만 속하거나 값이 다른 key
			}
		}
	}
Beispiel #13
0
bool MkFileChunk::AttachOriginalFiles
(const MkPathName& chunkFilePath, MkFilePathListContainer& filePathListContainer, MkArray<MkPathName>& memberFilePathList,
 unsigned int chunkSizeGuideline, unsigned int percentageForCompressing, bool createNewChunk)
{
	memberFilePathList.Clear();

	MkArray<MkPathName>& relativeFilePathList = filePathListContainer.GetRelativeFilePathList();
	unsigned int startCount = relativeFilePathList.GetSize();
	MK_CHECK(startCount > 0, L"파일 경로 리스트가 비어 " + m_AbsoluteChunkFilePath + L" 청크 파일 구성 불가")
		return false;

	if (createNewChunk)
	{
		MK_CHECK(!chunkFilePath.IsDirectoryPath(), chunkFilePath + L" 청크 파일 경로 오류")
			return false;

		Clear();

		// 새 청크 파일 이름
		m_AbsoluteChunkFilePath.ConvertToRootBasisAbsolutePath(chunkFilePath);
	}

	// 크기 예약
	m_BlockList.Reserve(m_BlockList.GetSize() + startCount);
	memberFilePathList.Reserve(startCount);

	// 인터페이스 생성. createNewChunk에 따라 청크 파일 생성
	MkInterfaceForFileWriting chunkFileInterface;
	if (!chunkFileInterface.SetUp(m_AbsoluteChunkFilePath, createNewChunk))
		return false;

	// 새 청크 파일의 경우 블록 카운트를 기록하기 위한 태그 공간 확보
	if (createNewChunk)
	{
		m_ChunkSize = sizeof(unsigned int);
		_AddCountTag(chunkFileInterface, m_ChunkSize);
	}

	// 뒤에서부터 앞으로 순회
	MK_INDEXING_RLOOP(relativeFilePathList, i)
	{
		const MkPathName& currPath = filePathListContainer.GetRelativeFilePath(i);

		MkFileBlock& currBlock = m_BlockList.PushBack();
		unsigned int blockSize = currBlock.SetUpFromOriginalFileAndAttachToChunkFile
			(filePathListContainer.GetAbsoluteOriginalFilePath(i), currPath, chunkFileInterface, percentageForCompressing, filePathListContainer.GetOuterWrittenTime(i));

		if (blockSize == 0)
		{
			if (createNewChunk)
			{
				m_AbsoluteChunkFilePath.DeleteCurrentFile();
			}
			return false;
		}

		memberFilePathList.PushBack(currPath);

		++m_AvailableBlockCount;

		m_ChunkSize += blockSize;
		if (m_ChunkSize >= chunkSizeGuideline)
			break;
	}

	chunkFileInterface.Clear();

	// 블록 카운트 수정
	MkInterfaceForFileTag<unsigned int> ftInterface;
	if (!ftInterface.SetUp(m_AbsoluteChunkFilePath))
	{
		if (createNewChunk)
		{
			m_AbsoluteChunkFilePath.DeleteCurrentFile();
		}
		return false;
	}

	ftInterface.Overwrite(m_BlockList.GetSize(), 0);
	ftInterface.Clear();

	// 청크에 구성된 파일들을 리스트에서 삭제
	filePathListContainer.PopBack(memberFilePathList.GetSize());
	return true;
}
Beispiel #14
0
void MkWindowThemedNode::Save(MkDataNode& node) const
{
	// component panel 제외
	static MkArray<MkHashStr> panelExceptions(10);
	if (panelExceptions.Empty())
	{
		panelExceptions.PushBack(MkWindowThemeUnitData::ImagePositionName);
		panelExceptions.PushBack(MkWindowThemeUnitData::EdgeAndTablePositionName[MkWindowThemeUnitData::eP_LT]);
		panelExceptions.PushBack(MkWindowThemeUnitData::EdgeAndTablePositionName[MkWindowThemeUnitData::eP_MT]);
		panelExceptions.PushBack(MkWindowThemeUnitData::EdgeAndTablePositionName[MkWindowThemeUnitData::eP_RT]);
		panelExceptions.PushBack(MkWindowThemeUnitData::EdgeAndTablePositionName[MkWindowThemeUnitData::eP_LC]);
		panelExceptions.PushBack(MkWindowThemeUnitData::EdgeAndTablePositionName[MkWindowThemeUnitData::eP_MC]);
		panelExceptions.PushBack(MkWindowThemeUnitData::EdgeAndTablePositionName[MkWindowThemeUnitData::eP_RC]);
		panelExceptions.PushBack(MkWindowThemeUnitData::EdgeAndTablePositionName[MkWindowThemeUnitData::eP_LB]);
		panelExceptions.PushBack(MkWindowThemeUnitData::EdgeAndTablePositionName[MkWindowThemeUnitData::eP_MB]);
		panelExceptions.PushBack(MkWindowThemeUnitData::EdgeAndTablePositionName[MkWindowThemeUnitData::eP_RB]);
	}
	_AddExceptionList(node, SystemKey_PanelExceptions, panelExceptions);

	// shadow node 제외
	static MkArray<MkHashStr> nodeExceptions;
	if (nodeExceptions.Empty())
	{
		nodeExceptions.PushBack(ShadowNodeName);
	}
	_AddExceptionList(node, SystemKey_NodeExceptions, nodeExceptions);

	// run
	MkVisualPatternNode::Save(node);
}
Beispiel #15
0
void MkShaderEffectPool::SetUp(const MkPathName& shaderDirectory)
{
	LPDIRECT3DDEVICE9 device = MK_DEVICE_MGR.GetDevice();
	MK_CHECK(device != NULL, L"NULL device여서 MkShaderEffectPool 초기화 실패")
		return;

	// 경로 점검
	MkPathName dirPath;
	dirPath.ConvertToRootBasisAbsolutePath(shaderDirectory);
	dirPath.CheckAndAddBackslash();
	MK_CHECK(dirPath.IsDirectoryPath() && dirPath.CheckAvailable(), dirPath + L" 경로가 존재하지 않아 MkShaderEffectPool 초기화 실패")
		return;

	// fxo 파일 검색
	MkArray<MkPathName> filePathList;
	MkArray<MkPathName> emptyFilter;
	MkArray<MkStr> prefixFilter;
	MkArray<MkPathName> extensionFilter;
	extensionFilter.PushBack(L"fxo");
	dirPath.GetWhiteFileList(filePathList, emptyFilter, extensionFilter, prefixFilter, emptyFilter, false, false);

	MK_INDEXING_LOOP(filePathList, i)
	{
		MkHashStr effectName = filePathList[i].GetFileName(false);
		MkPathName currFilePath = dirPath + filePathList[i];
		unsigned int fileSize = currFilePath.GetFileSize();
		unsigned int writtenTime = currFilePath.GetWrittenTime();
		
		if (m_Pool.Exist(effectName))
		{
			_EffectData& ed = m_Pool[effectName];
			if ((ed.fileSize != fileSize) || (ed.fileWrittenTime != writtenTime)) // 크기/수정일시 변경 확인
			{
				ed.effect->Clear();
				if (ed.effect->SetUp(effectName, currFilePath))
				{
					ed.fileSize = fileSize;
					ed.fileWrittenTime = writtenTime;

					MK_DEV_PANEL.MsgToLog(effectName.GetString() + L" effect 갱신");
				}
				else
				{
					delete ed.effect;
					m_Pool.Erase(effectName);
				}
			}
		}
		else
		{
			MkShaderEffect* effect = new MkShaderEffect;
			MK_CHECK(effect != NULL, effectName.GetString() + L" effect 객체 생성 실패")
				continue;

			if (effect->SetUp(effectName, currFilePath))
			{
				_EffectData& ed = m_Pool.Create(effectName);
				ed.effect = effect;
				ed.fileSize = fileSize;
				ed.fileWrittenTime = writtenTime;

				MK_DEV_PANEL.MsgToLog(effectName.GetString() + L" effect 생성");
			}
			else
			{
				delete effect;
			}
		}
	}
Beispiel #16
0
void MkImageInfo::SetUp(const MkInt2& imageSize, const MkDataNode* node)
{
	Clear();

	// ready to uv converting
	MkFloat2 fImageSize(static_cast<float>(imageSize.x), static_cast<float>(imageSize.y));

	// empty subset
	Subset& emptySubset = m_Subsets.Create(MkHashStr::EMPTY);
	emptySubset.rectSize = fImageSize;
	emptySubset.uv[MkFloatRect::eLeftTop] = MkFloat2::Zero;
	emptySubset.uv[MkFloatRect::eRightTop] = MkFloat2(1.f, 0.f);
	emptySubset.uv[MkFloatRect::eLeftBottom] = MkFloat2(0.f, 1.f);
	emptySubset.uv[MkFloatRect::eRightBottom] = MkFloat2(1.f, 1.f);

	if (node == NULL)
		return;

	// group
	node->GetDataEx(GROUP_KEY, m_Group, 0);

	// parse nodes
	MkArray<MkHashStr> keyList;
	node->GetChildNodeList(keyList);
	MK_INDEXING_LOOP(keyList, i)
	{
		const MkHashStr& childName = keyList[i];
		const MkDataNode& childNode = *node->GetChildNode(childName);

		do
		{
			// 필수 key로 subset/sequence 종류 판단
			if (childNode.IsValidKey(SIZE_KEY)) // subset
			{
				MkInt2 position;
				childNode.GetData(POSITION_KEY, position, 0);

				MkInt2 size;
				childNode.GetData(SIZE_KEY, size, 0);
				MK_CHECK(size.IsPositive(), childName.GetString() + L" 노드의 " + SIZE_KEY.GetString() + L" 값 오류")
					break;

				MkInt2 table(1, 1);
				childNode.GetData(TABLE_KEY, table, 0);
				MK_CHECK(table.IsPositive(), childName.GetString() + L" 노드의 " + TABLE_KEY.GetString() + L" 값 오류")
					break;

				MkFloat2 fSubsetSize(static_cast<float>(size.x), static_cast<float>(size.y));
				MkFloat2 fUVSize(fSubsetSize.x / fImageSize.x, fSubsetSize.y / fImageSize.y);

				// single subset
				if ((table.x == 1) && (table.y == 1))
				{
					_RegisterSubset(childName, fSubsetSize, position, fImageSize, fUVSize);
				}
				// multi subset
				else
				{
					MkInt2 offset = size;
					childNode.GetData(OFFSET_KEY, offset, 0);

					MkInt2 currPivot = position;
					for (int y = 0; y < table.y; ++y)
					{
						for (int x = 0; x < table.x; ++x)
						{
							_RegisterSubset(childName.GetString() + MkStr(y * table.x + x), fSubsetSize, currPivot, fImageSize, fUVSize);
							currPivot.x += offset.x;
						}
						currPivot.x = position.x;
						currPivot.y += offset.y;
					}
				}
			}
			else if (childNode.IsValidKey(TOTAL_RANGE_KEY) && childNode.IsValidKey(SUBSET_LIST_KEY)) // sequence
			{
				float totalRange = 0.f;
				childNode.GetData(TOTAL_RANGE_KEY, totalRange, 0);
				MK_CHECK(totalRange > 0.f, childName.GetString() + L" 노드의 " + TOTAL_RANGE_KEY.GetString() + L" 값 오류")
					break;

				MkArray<MkHashStr> subsetList;
				childNode.GetDataEx(SUBSET_LIST_KEY, subsetList);
				MK_CHECK(!subsetList.Empty(), childName.GetString() + L" 노드의 " + SUBSET_LIST_KEY.GetString() + L" 값 오류")
					break;

				MkArray<float> timeList;
				childNode.GetData(TIME_LIST_KEY, timeList);

				bool loop = true;
				childNode.GetData(LOOP_KEY, loop, 0);

				// time list 검증 및 자동생성
				if (timeList.Empty())
				{
					timeList.Reserve(subsetList.GetSize());
					float oneFrameTime = totalRange / static_cast<float>(subsetList.GetSize());
					float timeStamp = 0.f;
					MK_INDEXING_LOOP(subsetList, j)
					{
						timeList.PushBack(timeStamp);
						timeStamp += oneFrameTime;
					}
				}
MkTitleBarControlNode* MkWindowFactory::_CreateMessageBox
(const MkHashStr& name, const MkStr& titleStr, const MkArray<MkHashStr>& titleTextName, const MkStr& descStr, const MkArray<MkHashStr>& descTextName,
 MkWindowBaseNode* callBackWindow, eMsgBoxType boxType, eMsgBoxButton btnType) const
{
	// icon type
	MkWindowThemeData::eIconType iconType = MkWindowThemeData::eIT_None;
	MkWindowThemeData::eComponentType bodyType = MkWindowThemeData::eCT_None;
	switch (boxType)
	{
	case eMBT_Default:
		iconType = MkWindowThemeData::eIT_Default;
		bodyType = MkWindowThemeData::eCT_DefaultBox;
		break;
	case eMBT_Notice:
		iconType = MkWindowThemeData::eIT_Notice;
		bodyType = MkWindowThemeData::eCT_DefaultBox;
		break;
	case eMBT_Information:
		iconType = MkWindowThemeData::eIT_Information;
		bodyType = MkWindowThemeData::eCT_DefaultBox;
		break;
	case eMBT_Warning:
		iconType = MkWindowThemeData::eIT_Warning;
		bodyType = MkWindowThemeData::eCT_NoticeBox;
		break;
	case eMBT_EditMode:
		iconType = MkWindowThemeData::eIT_EditMode;
		bodyType = MkWindowThemeData::eCT_DefaultBox;
		break;
	}

	if ((iconType == MkWindowThemeData::eIT_None) || (bodyType == MkWindowThemeData::eCT_None))
		return NULL;

	// create title
	MkTitleBarControlNode* titleNode = MkTitleBarControlNode::CreateChildNode(NULL, name);
	if (titleNode != NULL)
	{
		do
		{
			titleNode->SetTitleBar(m_ThemeName, m_FrameType, 10.f, (btnType == eMBB_None)); // length는 의미 없음. 이후 body frame에서 재설정 할 것임
			titleNode->SetIcon(iconType);

			if (titleTextName.Empty())
			{
				titleNode->SetCaption(titleStr);
			}
			else
			{
				titleNode->SetCaption(titleTextName);
			}
			
			// create body frame
			MkBodyFrameControlNode* bodyFrame = MkBodyFrameControlNode::CreateChildNode(titleNode, BodyFrameName);
			if (bodyFrame == NULL)
				break;

			// body frame dispositioner
			MkWindowDispositioner windowDispositioner;
			windowDispositioner.SetMargin(MkFloat2(8.f, 8.f)); // border
			windowDispositioner.AddNewLine(); // title에 해당하는 빈 영역
			windowDispositioner.AddDummyToCurrentLine(titleNode->CalculateWindowSize());

			// create text tag
			MkFloat2 textRegion;
			MkWindowTagNode* tagNode = descTextName.Empty() ?
				CreateTextTagNode(OneAndOnlyTagName, descStr, textRegion) : CreateTextTagNode(OneAndOnlyTagName, descTextName, textRegion);
			
			if (tagNode == NULL)
				break;

			bodyFrame->AttachChildNode(tagNode);

			windowDispositioner.AddNewLine(MkWindowDispositioner::eLHA_Center); // text tag는 중앙 정렬
			windowDispositioner.AddRectToCurrentLine(OneAndOnlyTagName, textRegion);

			// call back target path
			MkArray<MkHashStr> callbackTarget;
			if (callBackWindow != NULL)
			{
				callBackWindow->GetWindowPath(callbackTarget);
			}

			MkWindowBaseNode* okBtn = NULL;
			MkWindowBaseNode* cancelBtn = NULL;
			if (btnType != eMBB_None)
			{
				// create ok btn
				okBtn = CreateOkButtonNode();
				if (okBtn == NULL)
					break;

				bodyFrame->AttachChildNode(okBtn);

				if (!callbackTarget.Empty())
				{
					okBtn->SetCallBackTargetWindowPath(callbackTarget);
				}

				windowDispositioner.AddNewLine(MkWindowDispositioner::eLHA_Center); // button set도 중앙 정렬
				windowDispositioner.AddRectToCurrentLine(okBtn->GetNodeName(), okBtn->CalculateWindowSize());

				// create cancel btn
				if (btnType == eMBB_OkCancel)
				{
					cancelBtn = CreateCancelButtonNode();
					if (cancelBtn == NULL)
						break;
					
					bodyFrame->AttachChildNode(cancelBtn);

					if (!callbackTarget.Empty())
					{
						cancelBtn->SetCallBackTargetWindowPath(callbackTarget);
					}

					windowDispositioner.AddRectToCurrentLine(cancelBtn->GetNodeName(), cancelBtn->CalculateWindowSize());
				}
			}

			// dispositioner 계산
			windowDispositioner.Calculate();

			// body frame size
			MkFloat2 clientSize = windowDispositioner.GetRegion();
			//clientSize += MkFloat2(10.f, 10.f); // border
			bodyFrame->SetBodyFrame(m_ThemeName, bodyType, true, MkBodyFrameControlNode::eHT_IncludeParentAtTop, clientSize);

			// 하위 node 위치 반영
			windowDispositioner.ApplyPositionToNode(tagNode);
			windowDispositioner.ApplyPositionToNode(okBtn);
			windowDispositioner.ApplyPositionToNode(cancelBtn);

			return titleNode;
		}
		while (false);

		MK_DELETE(titleNode);
	}
	return NULL;
}
bool MkCheatMessage::__ExcuteMsg(const MkStr& inputMsg, MkStr& resultMsg) const
{
	if (inputMsg.Empty())
		return false;

	MkStr msgCopy = inputMsg;
	MkStringTableForParser stringTable;
	stringTable.BuildStringTable(msgCopy);

	msgCopy.RemoveKeyword(MkStr::CR);

	bool result = false;

	// 라인별 분리
	MkArray<MkStr> lines;
	unsigned int lineCount = msgCopy.Tokenize(lines, MkStr::LF);
	MK_INDEXING_LOOP(lines, i)
	{
		MkArray<MkStr> tokens;
		MkStr command;
		unsigned int tokenCount = lines[i].Tokenize(tokens);
		if (tokenCount > 0) // 유효문자가 존재하면
		{
			bool success = false;
			if (DoAutoParsing(tokens[0]))
			{
				command = tokens[0];

				MkArray<MkStr> argument;
				if (tokenCount > 1) // argument가 존재하면
				{
					argument.Reserve(tokenCount - 1);
					for (unsigned int i=1; i<tokenCount; ++i)
					{
						MkHashStr currToken = tokens[i];
						argument.PushBack(stringTable.Exist(currToken) ? stringTable.GetString(currToken) : tokens[i]);
					}
				}

				success = ExcuteMsg(command, argument, resultMsg);
			}
			else
			{
				MkStr lineMsg = tokens[0];
				for (unsigned int i=1; i<tokenCount; ++i)
				{
					MkHashStr currToken = tokens[i];
					lineMsg += MkStr::SPACE;
					lineMsg += stringTable.Exist(currToken) ? stringTable.GetString(currToken) : tokens[i];
				}

				success = ExcuteLine(lineMsg, resultMsg);
			}

			if (success)
			{
				result = true; // 하나라도 성공하면 의미 있음
			}
			else
			{
				resultMsg += MkStr::CRLF;
				resultMsg += L"> MkCheatMessage::\"" + lines[i] + L"\" 실행 실패";
			}
		}
	}