Index: /trunk/cf/task.cpp
===================================================================
--- /trunk/cf/task.cpp	(revision 13)
+++ /trunk/cf/task.cpp	(revision 14)
@@ -77,4 +77,5 @@
 
 	cf::memory::free(mMutex);
+	mMutex = NULL;
 }
 
Index: /trunk/msg.cpp
===================================================================
--- /trunk/msg.cpp	(revision 13)
+++ /trunk/msg.cpp	(revision 14)
@@ -42,4 +42,9 @@
 	}
 
+	std::string Message::serialize() const
+	{
+		return json::Serialize(mObject);
+	}
+
 	// request
 	void Request::setUserID(const std::string & id)
@@ -83,5 +88,12 @@
 		DECLARE_TEMPLATE_OBJECT(obj, ProtocolType::LOGIN);
 
-		obj[ProtocolType::PW] = mID + DELIMITER + pw;
+		obj[ProtocolType::PW] = pw;
+
+		return json::Serialize(obj);
+	}
+
+	std::string Request::logout() const
+	{
+		DECLARE_TEMPLATE_OBJECT(obj, ProtocolType::LOGOUT);
 
 		return json::Serialize(obj);
@@ -97,16 +109,21 @@
 	}
 
-	std::string Request::openSession(const std::string & to) const
+	std::string Request::openSession(const std::vector<std::string> & idList) const
 	{
 		DECLARE_TEMPLATE_OBJECT(obj, ProtocolType::OPEN_SESSION);
 
-		obj[ProtocolType::TO] = to;
+		json::Array ar;
+		std::vector<std::string>::const_iterator iter;
+		for (iter = idList.begin(); iter != idList.end(); iter++)
+			ar.push_back(*iter);
+
+		obj[ProtocolType::ID_LIST] = ar;
 
 		return json::Serialize(obj);
 	}
 
-	std::string Request::chat(const std::string & sessid, const std::string & message, const int sensitive) const
+	std::string Request::tell(const std::string & sessid, const std::string & message, const int sensitive) const
 	{
-		DECLARE_TEMPLATE_OBJECT(obj, ProtocolType::CHAT);
+		DECLARE_TEMPLATE_OBJECT(obj, ProtocolType::TELL);
 
 		obj[ProtocolType::FROM] = mID;
@@ -133,5 +150,5 @@
 	std::string Response::result(const std::string & requestType, const bool status) const
 	{
-		DECLARE_TEMPLATE_OBJECT(obj, ProtocolType::RESULT);
+		DECLARE_TEMPLATE_OBJECT(obj, requestType);
 
 		obj[ProtocolType::RESULT] = status;
Index: /trunk/msg.hpp
===================================================================
--- /trunk/msg.hpp	(revision 13)
+++ /trunk/msg.hpp	(revision 14)
@@ -32,8 +32,10 @@
 	DECLARE_KEY(PW);
 	DECLARE_KEY(LOGIN);
+	DECLARE_KEY(LOGOUT);
 	DECLARE_KEY(ADD_FRIEND);
 	DECLARE_KEY(OPEN_SESSION);
 	DECLARE_KEY(TO);
-	DECLARE_KEY(CHAT);
+	DECLARE_KEY(LISTEN);
+	DECLARE_KEY(TELL);
 	DECLARE_KEY(FROM);
 	DECLARE_KEY(SESSION_ID);
@@ -50,8 +52,7 @@
 	class Message
 	{
-	private:
+	public:
 		json::Object mObject;
 
-	public:
 		Message();
 
@@ -79,4 +80,6 @@
 
 		std::string type() const;
+
+		std::string serialize() const;
 	};
 
@@ -105,9 +108,11 @@
 		std::string login(const std::string & pw) const;
 
+		std::string logout() const;
+
 		std::string addFriend(const std::string & id) const;
 
-		std::string openSession(const std::string & to) const;
+		std::string openSession(const std::vector<std::string> & idList) const;
 
-		std::string chat(const std::string & sessid, const std::string & message, const int sensitive) const;
+		std::string tell(const std::string & sessid, const std::string & message, const int sensitive) const;
 
 		std::string getFriendList() const;
@@ -122,6 +127,4 @@
 
 		std::string friendList(const std::vector<SFriend> & friendList) const;
-
-		std::string openSession(const std::vector<std::string> & idList) const;
 	};
 };
@@ -156,5 +159,5 @@
 
 	for (size_t iter = 1; iter < strings.size(); iter++)
-		concat += strings[iter];
+		concat += "," + strings[iter];
 
 	return concat;
Index: /trunk/msgclnt.cpp
===================================================================
--- /trunk/msgclnt.cpp	(revision 13)
+++ /trunk/msgclnt.cpp	(revision 14)
@@ -6,4 +6,6 @@
 
 #include <stdlib.h>
+
+#include "cf/codec.h"
 
 // --------------------------------------------------------------
@@ -21,10 +23,10 @@
 } SCallbackWorkerArg;
 
-static int messageQworekr(void * arg)
+static int messageQworker(void * arg)
 {
 	SMessageQWorkerArg * inst = (SMessageQWorkerArg *)arg;
 
 	Protocol::Message message;
-	cf::bin raw;
+	cf::size_t size;
 
 	while (true)
@@ -32,5 +34,9 @@
 		try
 		{
-			raw = inst->socket->receive();
+			size = 0;
+
+			cf::bin raw = inst->socket->receive();
+			size = raw.size();
+
 			message.parse(raw.toString());
 		}
@@ -40,6 +46,11 @@
 
 			// closed
-			if (raw.size() == 0)
+			if (size == 0)
+			{
+				// dummy logout
+				message.parse(Protocol::Request().logout());
+				inst->messageQ->push(message);
 				break;
+			}
 		}
 
@@ -52,12 +63,14 @@
 }
 
-static inline SConversation toCnversation(const Protocol::Message & message)
+static inline SConversation toConversation(const Protocol::Message & message)
 {
 	SConversation c;
+	std::string chat = message.get<std::string>(ProtocolType::MESSAGE);
+
+	if (chat.length() > 0)
+		c.message = cf::codec::hex::getInstance()->decode(chat).toString();
 
 	c.sessid = message.get<std::string>(ProtocolType::SESSION_ID);
-	c.message = message.get<std::string>(ProtocolType::MESSAGE);
 	c.sensitive = message.get<int>(ProtocolType::SENSITIVE);
-	c.isError = message.get<bool>(ProtocolType::RESULT);
 
 	c.from = message.get<std::string>(ProtocolType::FROM);
@@ -84,11 +97,15 @@
 	while (true)
 	{
-		message = inst->messageQ->pop(ProtocolType::CHAT, false);
+		message = inst->messageQ->pop(ProtocolType::LISTEN, false);
 		if (message.type() != ProtocolType::NONE)
-			inst->callback.onChat(toCnversation(message));
+			inst->callback.onListen(toConversation(message));
 
 		message = inst->messageQ->pop(ProtocolType::OPEN_SESSION, false);
 		if (message.type() != ProtocolType::NONE)
 			inst->callback.onOpenSession(toOpenSession(message));
+
+		message = inst->messageQ->pop(ProtocolType::LOGOUT, false);
+		if (message.type() != ProtocolType::NONE)
+			break;
 	}
 
@@ -109,18 +126,23 @@
 Protocol::Message MessageQ::pop(const std::string & requestType, bool isWait)
 {
-	while (isWait)
-	{
-		SYNCHRONIZED(mutex)
-		{
-			Protocol::Message message = messageQ.front();
-
-			if (message.type() == requestType)
-			{
-				messageQ.erase(messageQ.begin());
-
-				return message;
-			}
-		}
-	}
+	do
+	{
+		mutex.lock();
+		if (messageQ.size() == 0)
+		{
+			mutex.unlock();
+			continue;
+		}
+
+		Protocol::Message message = messageQ.front();
+
+		if (message.type() == requestType)
+		{
+			messageQ.erase(messageQ.begin());
+			mutex.unlock();
+			return message;
+		}
+		mutex.unlock();
+	} while (isWait);
 
 	return Protocol::Message(); // return dummy NONE
@@ -130,5 +152,5 @@
 
 chev::chev()
-	: listener(messageQworekr),
+	: listener(messageQworker),
 	  caller(callbackWorker)
 {
@@ -138,4 +160,6 @@
 {
 	socket.close();
+	listener.join();
+	caller.join();
 }
 
@@ -254,23 +278,18 @@
 }
 
-std::string chev::getSessionID(std::vector<std::string> & idList)
-{
-	try
-	{
-		idList.insert(idList.begin(), request.getUserID());
-
-		if (idList.size() == 2)
-			std::sort(idList.begin(), idList.end());
-
-		std::string concat = joinStrings(idList);
+std::string chev::getSessionID(const std::vector<std::string> & idList)
+{
+	try
+	{
+		std::vector<std::string> toList = idList;
+		toList.insert(toList.begin(), request.getUserID());
+
+		std::string concat = joinStrings(toList);
 
 		if (sessionMap.find(concat) == sessionMap.end())
 		{
-			socket.send(request.openSession(concat));
-
-			Protocol::Message message = messageQ.pop(ProtocolType::SESSION_ID);
-
-			if (!message.get<bool>(ProtocolType::RESULT))
-				THROW_EXCEPTION("failed to open session id");
+			socket.send(request.openSession(toList));
+
+			Protocol::Message message = messageQ.pop(ProtocolType::OPEN_SESSION);
 
 			sessionMap[concat] = message.get<std::string>(ProtocolType::SESSION_ID);
@@ -291,9 +310,12 @@
 	try
 	{
-		const SConversation & c = conversation;
-
-		socket.send(request.chat(c.sessid, c.message, c.sensitive));
-
-		return messageQ.pop(ProtocolType::CHAT).get<bool>(ProtocolType::RESULT);
+		SConversation c = conversation;
+
+		if (c.message.length() > 0)
+			c.message = cf::codec::hex::getInstance()->encode(c.message);
+
+		socket.send(request.tell(c.sessid, c.message, c.sensitive));
+
+		return messageQ.pop(ProtocolType::TELL).get<bool>(ProtocolType::RESULT);
 	}
 	catch (cf::exception & e)
Index: /trunk/msgclnt.h
===================================================================
--- /trunk/msgclnt.h	(revision 13)
+++ /trunk/msgclnt.h	(revision 14)
@@ -15,5 +15,4 @@
 	std::string message;
 	int sensitive;
-	bool isError;
 
 	// only for listen
@@ -29,5 +28,5 @@
 typedef struct SCallback
 {
-	int(*onChat)(SConversation &);
+	int(*onListen)(SConversation &);
 	int(*onOpenSession)(SOpenSession &);
 } SCallback;
@@ -77,5 +76,5 @@
 	std::vector<SFriend> getFriendList();
 
-	std::string getSessionID(std::vector<std::string> & idList);
+	std::string getSessionID(const std::vector<std::string> & idList);
 
 	bool tell(const SConversation & conversation);
Index: /trunk/msgsrv.cpp
===================================================================
--- /trunk/msgsrv.cpp	(revision 13)
+++ /trunk/msgsrv.cpp	(revision 14)
@@ -16,5 +16,5 @@
 // --------------------------------------------------------------
 
-typedef struct
+typedef struct LoginSession
 {
 	cf::network::tcp * sock;
@@ -22,7 +22,7 @@
 } LoginSession;
 std::map<std::string, LoginSession> gOnlineUsers;
-
-
-//================================================================
+std::map<std::string, std::vector<std::string> > gSessionMap;
+
+// --------------------------------------------------------------
 
 int cb_getFriendList(void * userArg, int argc, char ** argv, char ** colName)
@@ -75,4 +75,5 @@
 		: db(NULL)
 	{
+		Init();
 	}
 	
@@ -139,11 +140,11 @@
 		throw(cf::exception)
 	{
-		int result;
-		char * errMsg;
+		int result = 0;
+		char * errMsg = NULL;
 
 		result = sqlite3_exec(db, query.c_str(), cb, userArg, &errMsg);
 
 		if (result != SQLITE_OK)
-			THROW_EXCEPTION (errMsg);
+			THROW_EXCEPTION("[DBERROR][" << result << "] " << errMsg);
 	}
 
@@ -163,6 +164,4 @@
 		{
 			FORWARD_EXCEPTION(e);
-
-			return false;
 		}
 	}
@@ -175,5 +174,5 @@
 			bool isExist = false;
 			std::string existQuery = "select * from T_ACCOUNT where id = '" + id + "'";
-			std::string insertQuery = "insert into T_ACCOUNT values('" + id + "', '" + pw + "', '" + sms + "', '" + ip + "')";
+			std::string insertQuery = "insert into T_ACCOUNT(id, pw) values('" + id + "', '" + pw + "')";
 
 			this->exec(existQuery, cb_join, &isExist);
@@ -282,4 +281,21 @@
 {
 	gOnlineUsers.erase(id);
+	LOG(STR(id << " was logged out"));
+}
+
+static unsigned int generateSeed()
+{
+	unsigned int ret = 0;
+	int t = (int)time(NULL);
+
+	cf::bin b;
+	b.resize(sizeof(int));
+
+	b.set((cf::uint8_t*)&t, sizeof(int));
+	cf::bin s = crypto().sha256(b);
+
+	memcpy(&ret, s.buffer(), sizeof(unsigned int));
+
+	return ret;
 }
 
@@ -287,5 +303,5 @@
 {
 	char random[8] = {0x00,};
-	sprintf(random, "%06d", rand() % 1000000);
+	sprintf(random, "%06d", generateSeed() % 1000000);
 
 	return random;
@@ -294,5 +310,5 @@
 static std::string httpSMS(const Protocol::Message & parser)
 {
-	std::string phone = parser.get<std::string>("phone");
+	std::string phone = parser.get<std::string>(ProtocolType::PHONE);
 
 #define CRLF    "\r\n"
@@ -306,5 +322,4 @@
 		CRLF;
 
-	Protocol::Response response;
 	cf::network::tcp smsSock;
 	cf::network::host smsServer(url, 80);
@@ -312,4 +327,5 @@
 	smsSock.connect(smsServer);
 	smsSock.send(http);
+	smsSock.receive();
 	smsSock.close();
 
@@ -329,5 +345,5 @@
 }
 
-static bool login(const Protocol::Message & parser)
+static bool login(const Protocol::Message & parser, cf::network::tcp & sock, cf::bin & key)
 	throw (cf::exception)
 {
@@ -335,16 +351,33 @@
 	std::string pw = parser.get<std::string>(ProtocolType::PW);
 
-	return dbmgr.login(id, pw);
-}
-
-static bool chat(const Protocol::Message & parser,
-				 const std::string & message)
+	bool result = dbmgr.login(id, pw);
+	if (result)
+	{
+		LoginSession loginSess;
+		loginSess.sock = &sock;
+		loginSess.key = key;
+		gOnlineUsers[id] = loginSess;
+	}
+
+	return result;
+}
+
+static bool chat(const Protocol::Message & message)
 {
 	bool result = false;
-	std::string to = parser.get<std::string>(ProtocolType::TO);
-
-	if (isOnline(to))
-	{
-		gOnlineUsers[to].sock->send(message);
+	Protocol::Message parser = message;
+	std::string sessid = parser.get<std::string>(ProtocolType::SESSION_ID);
+	std::vector<std::string> idList = gSessionMap[sessid];
+	std::string sender = parser.get<std::string>(ProtocolType::ID);
+	parser.mObject[ProtocolType::TYPE] = ProtocolType::LISTEN;
+	std::string serialized = parser.serialize();
+
+	for (size_t iter = 0; iter < idList.size(); iter++)
+	{
+		std::string id = idList[iter];
+
+		if (sender != id && isOnline(id))
+			gOnlineUsers[id].sock->send(serialized);
+
 		result = true;
 	}
@@ -362,24 +395,28 @@
 }
 
-static bool opensession(const Protocol::Message & parser)
-{
+static bool openSession(const Protocol::Message & message)
+{
+	Protocol::Message parser = message;
 	bool result = false;
 	std::string sessid;
 	std::vector<std::string> idList = parser.getList<std::string>(ProtocolType::ID_LIST);
-	std::string concat = idList[0];
-
-	for (size_t iter = 1; iter < concat.size(); iter++)
-		concat += idList[iter];	
+	std::string concat = joinStrings(idList);
 
 	sessid = createSessionID(concat);
 
+	parser.mObject[ProtocolType::SESSION_ID] = sessid;
+	std::string serialized = parser.serialize();
+
 	for (size_t iter = 0; iter < idList.size(); iter++)
 	{
-		if (isOnline(idList[iter]))
-			gOnlineUsers[idList[iter]].sock->send(sessid);
+		std::string id = idList[iter];
+		if (isOnline(id))
+			gOnlineUsers[id].sock->send(serialized);
 
 		result = true;
 	}
 
+	gSessionMap[sessid] = idList;
+
 	return result;
 }
@@ -396,31 +433,46 @@
 static std::string workerInitiator(cf::network::tcp & sock)
 {
+	Protocol::Message parser;
+
 	try
 	{
 		std::string sms;
+		std::string id;
+		bool loggedIn = false;
 
 		while (true)
 		{
-			Protocol::Message parser;
 			parser.parse(sock.receive().toString());
 
-			if (parser.type() == "sms")
+			if (parser.type() == ProtocolType::SMS)
 			{
 				sms = httpSMS(parser);
 			}
-			else if (parser.type() == "join")
+			else if (parser.type() == ProtocolType::JOIN)
 			{
-				if (join(parser, sms, sock.peer().address()))
+				if (!join(parser, sms, sock.peer().address()))
 					THROW_EXCEPTION("user(" << parser.get<std::string>(ProtocolType::ID) << ") cannot join");
 			}
-			else if (parser.type() == "login")
+			else if (parser.type() == ProtocolType::LOGIN)
 			{
-				if (login(parser))
-					parser.get<std::string>(ProtocolType::ID);
-			}			
+				std::string ip = sock.peer().address();
+				cf::bin seed = sms + DELIMITER + ip;
+				cf::bin key = crypto().sha256(seed);
+
+				if (login(parser, sock, key))
+					id = parser.get<std::string>(ProtocolType::ID);
+
+				loggedIn = true;
+			}
+
+			// success
+			sock.send(Protocol::Response().result(parser.type(), true));
+			if (loggedIn)
+				return id;
 		}
 	}
 	catch (cf::exception & e)
 	{
+		sock.send(Protocol::Response().result(parser.type(), false));
 		FORWARD_EXCEPTION(e);
 	}
@@ -436,5 +488,5 @@
 	try
 	{
-		workerInitiator(*sock);
+		id = workerInitiator(*sock);
 
 		Protocol::Response response;
@@ -449,17 +501,18 @@
 			LOG(message);
 
-			if (parser.type() == "chat")
-				result = chat(parser, message);
-			else if (parser.type() == "opensession")
-				result = opensession(parser);
-//			else if (parser.type() == "getFriendList")
-//				result = 
-
-			sock->send(response.result(parser.type(), result));
+			if (parser.type() == ProtocolType::TELL)
+			{
+				result = chat(parser);
+				sock->send(response.result(parser.type(), result));
+			}
+			else if (parser.type() == ProtocolType::OPEN_SESSION)
+			{
+				result = openSession(parser);
+			}
 		}
 	}
 	catch (cf::exception & e)
 	{
-		LOG(e.what());
+		LOG(e.stackTrace());
 	}
 
@@ -472,6 +525,4 @@
 {
 	cf::network::tcp sock;
-
-	srand((unsigned int)time(NULL));
 
 	try
Index: /trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFC.h
===================================================================
--- /trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFC.h	(revision 13)
+++ /trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFC.h	(revision 14)
@@ -31,2 +31,14 @@
 
 extern CChevMsgrClient_MFCApp theApp;
+
+#include <string>
+
+static std::string wstr2str(const std::wstring & wstr)
+{
+	return std::string().assign(wstr.begin(), wstr.end());
+}
+
+static std::wstring str2wstr(const std::string & str)
+{
+	return std::wstring().assign(str.begin(), str.end());
+}
Index: /trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFC.vcxproj
===================================================================
--- /trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFC.vcxproj	(revision 13)
+++ /trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFC.vcxproj	(revision 14)
@@ -192,5 +192,8 @@
     <ClInclude Include="ChevMsgrClient_MFC.h" />
     <ClInclude Include="ChevMsgrClient_MFCDlg.h" />
+    <ClInclude Include="LoginDlg.h" />
+    <ClInclude Include="RegisterDlg.h" />
     <ClInclude Include="Resource.h" />
+    <ClInclude Include="SMSDlg.h" />
     <ClInclude Include="stdafx.h" />
     <ClInclude Include="targetver.h" />
@@ -199,4 +202,7 @@
     <ClCompile Include="ChevMsgrClient_MFC.cpp" />
     <ClCompile Include="ChevMsgrClient_MFCDlg.cpp" />
+    <ClCompile Include="LoginDlg.cpp" />
+    <ClCompile Include="RegisterDlg.cpp" />
+    <ClCompile Include="SMSDlg.cpp" />
     <ClCompile Include="stdafx.cpp">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
Index: /trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFC.vcxproj.filters
===================================================================
--- /trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFC.vcxproj.filters	(revision 13)
+++ /trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFC.vcxproj.filters	(revision 14)
@@ -34,4 +34,13 @@
       <Filter>헤더 파일</Filter>
     </ClInclude>
+    <ClInclude Include="LoginDlg.h">
+      <Filter>헤더 파일</Filter>
+    </ClInclude>
+    <ClInclude Include="RegisterDlg.h">
+      <Filter>헤더 파일</Filter>
+    </ClInclude>
+    <ClInclude Include="SMSDlg.h">
+      <Filter>헤더 파일</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
@@ -43,4 +52,13 @@
     </ClCompile>
     <ClCompile Include="stdafx.cpp">
+      <Filter>소스 파일</Filter>
+    </ClCompile>
+    <ClCompile Include="SMSDlg.cpp">
+      <Filter>소스 파일</Filter>
+    </ClCompile>
+    <ClCompile Include="LoginDlg.cpp">
+      <Filter>소스 파일</Filter>
+    </ClCompile>
+    <ClCompile Include="RegisterDlg.cpp">
       <Filter>소스 파일</Filter>
     </ClCompile>
Index: /trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFCDlg.cpp
===================================================================
--- /trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFCDlg.cpp	(revision 13)
+++ /trunk/msvc14/ChevMsgrClient_MFC/ChevMsgrClient_MFCDlg.cpp	(revision 14)
@@ -7,4 +7,8 @@
 #include "ChevMsgrClient_MFCDlg.h"
 #include "afxdialogex.h"
+
+#include "LoginDlg.h"
+#include "RegisterDlg.h"
+#include "SMSDlg.h"
 
 #ifdef _DEBUG
@@ -101,4 +105,10 @@
 	// TODO: ¿©±â¿¡ Ãß°¡ ÃÊ±âÈ­ ÀÛ¾÷À» Ãß°¡ÇÕ´Ï´Ù.
 
+	CLoginDlg loginDlg;
+	CSMSDlg smsDlg;
+	CRegisterDlg regDlg;
+
+	loginDlg.DoModal();
+
 	return TRUE;  // Æ÷Ä¿½º¸¦ ÄÁÆ®·Ñ¿¡ ¼³Á¤ÇÏÁö ¾ÊÀ¸¸é TRUE¸¦ ¹ÝÈ¯ÇÕ´Ï´Ù.
 }
Index: /trunk/msvc14/ChevMsgrClient_MFC/LoginDlg.cpp
===================================================================
--- /trunk/msvc14/ChevMsgrClient_MFC/LoginDlg.cpp	(revision 14)
+++ /trunk/msvc14/ChevMsgrClient_MFC/LoginDlg.cpp	(revision 14)
@@ -0,0 +1,34 @@
+// Login.cpp : ±¸Çö ÆÄÀÏÀÔ´Ï´Ù.
+//
+
+#include "stdafx.h"
+#include "ChevMsgrClient_MFC.h"
+#include "LoginDlg.h"
+#include "afxdialogex.h"
+
+
+// CLoginDlg ´ëÈ­ »óÀÚÀÔ´Ï´Ù.
+
+IMPLEMENT_DYNAMIC(CLoginDlg, CDialogEx)
+
+CLoginDlg::CLoginDlg(CWnd* pParent /*=NULL*/)
+	: CDialogEx(IDD_DIALOG_LOGIN, pParent)
+{
+
+}
+
+CLoginDlg::~CLoginDlg()
+{
+}
+
+void CLoginDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CLoginDlg, CDialogEx)
+END_MESSAGE_MAP()
+
+
+// CLoginDlg ¸Þ½ÃÁö Ã³¸®±âÀÔ´Ï´Ù.
Index: /trunk/msvc14/ChevMsgrClient_MFC/LoginDlg.h
===================================================================
--- /trunk/msvc14/ChevMsgrClient_MFC/LoginDlg.h	(revision 14)
+++ /trunk/msvc14/ChevMsgrClient_MFC/LoginDlg.h	(revision 14)
@@ -0,0 +1,23 @@
+#pragma once
+
+
+// CLoginDlg ´ëÈ­ »óÀÚÀÔ´Ï´Ù.
+
+class CLoginDlg : public CDialogEx
+{
+	DECLARE_DYNAMIC(CLoginDlg)
+
+public:
+	CLoginDlg(CWnd* pParent = NULL);   // Ç¥ÁØ »ý¼ºÀÚÀÔ´Ï´Ù.
+	virtual ~CLoginDlg();
+
+// ´ëÈ­ »óÀÚ µ¥ÀÌÅÍÀÔ´Ï´Ù.
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_DIALOG_LOGIN };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV Áö¿øÀÔ´Ï´Ù.
+
+	DECLARE_MESSAGE_MAP()
+};
Index: /trunk/msvc14/ChevMsgrClient_MFC/RegisterDlg.cpp
===================================================================
--- /trunk/msvc14/ChevMsgrClient_MFC/RegisterDlg.cpp	(revision 14)
+++ /trunk/msvc14/ChevMsgrClient_MFC/RegisterDlg.cpp	(revision 14)
@@ -0,0 +1,34 @@
+// Register.cpp : ±¸Çö ÆÄÀÏÀÔ´Ï´Ù.
+//
+
+#include "stdafx.h"
+#include "ChevMsgrClient_MFC.h"
+#include "RegisterDlg.h"
+#include "afxdialogex.h"
+
+
+// CRegisterDlg ´ëÈ­ »óÀÚÀÔ´Ï´Ù.
+
+IMPLEMENT_DYNAMIC(CRegisterDlg, CDialogEx)
+
+CRegisterDlg::CRegisterDlg(CWnd* pParent /*=NULL*/)
+	: CDialogEx(IDD_DIALOG_REGISTER, pParent)
+{
+
+}
+
+CRegisterDlg::~CRegisterDlg()
+{
+}
+
+void CRegisterDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CRegisterDlg, CDialogEx)
+END_MESSAGE_MAP()
+
+
+// CRegisterDlg ¸Þ½ÃÁö Ã³¸®±âÀÔ´Ï´Ù.
Index: /trunk/msvc14/ChevMsgrClient_MFC/RegisterDlg.h
===================================================================
--- /trunk/msvc14/ChevMsgrClient_MFC/RegisterDlg.h	(revision 14)
+++ /trunk/msvc14/ChevMsgrClient_MFC/RegisterDlg.h	(revision 14)
@@ -0,0 +1,23 @@
+#pragma once
+
+
+// CRegisterDlg ´ëÈ­ »óÀÚÀÔ´Ï´Ù.
+
+class CRegisterDlg : public CDialogEx
+{
+	DECLARE_DYNAMIC(CRegisterDlg)
+
+public:
+	CRegisterDlg(CWnd* pParent = NULL);   // Ç¥ÁØ »ý¼ºÀÚÀÔ´Ï´Ù.
+	virtual ~CRegisterDlg();
+
+// ´ëÈ­ »óÀÚ µ¥ÀÌÅÍÀÔ´Ï´Ù.
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_DIALOG_REGISTER };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV Áö¿øÀÔ´Ï´Ù.
+
+	DECLARE_MESSAGE_MAP()
+};
Index: /trunk/msvc14/ChevMsgrClient_MFC/SMSDlg.cpp
===================================================================
--- /trunk/msvc14/ChevMsgrClient_MFC/SMSDlg.cpp	(revision 14)
+++ /trunk/msvc14/ChevMsgrClient_MFC/SMSDlg.cpp	(revision 14)
@@ -0,0 +1,34 @@
+// SMS.cpp : ±¸Çö ÆÄÀÏÀÔ´Ï´Ù.
+//
+
+#include "stdafx.h"
+#include "ChevMsgrClient_MFC.h"
+#include "SMSDlg.h"
+#include "afxdialogex.h"
+
+
+// CSMSDlg ´ëÈ­ »óÀÚÀÔ´Ï´Ù.
+
+IMPLEMENT_DYNAMIC(CSMSDlg, CDialogEx)
+
+CSMSDlg::CSMSDlg(CWnd* pParent /*=NULL*/)
+	: CDialogEx(IDD_DIALOG_SMS, pParent)
+{
+
+}
+
+CSMSDlg::~CSMSDlg()
+{
+}
+
+void CSMSDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CSMSDlg, CDialogEx)
+END_MESSAGE_MAP()
+
+
+// CSMSDlg ¸Þ½ÃÁö Ã³¸®±âÀÔ´Ï´Ù.
Index: /trunk/msvc14/ChevMsgrClient_MFC/SMSDlg.h
===================================================================
--- /trunk/msvc14/ChevMsgrClient_MFC/SMSDlg.h	(revision 14)
+++ /trunk/msvc14/ChevMsgrClient_MFC/SMSDlg.h	(revision 14)
@@ -0,0 +1,23 @@
+#pragma once
+
+
+// CSMSDlg ´ëÈ­ »óÀÚÀÔ´Ï´Ù.
+
+class CSMSDlg : public CDialogEx
+{
+	DECLARE_DYNAMIC(CSMSDlg)
+
+public:
+	CSMSDlg(CWnd* pParent = NULL);   // Ç¥ÁØ »ý¼ºÀÚÀÔ´Ï´Ù.
+	virtual ~CSMSDlg();
+
+// ´ëÈ­ »óÀÚ µ¥ÀÌÅÍÀÔ´Ï´Ù.
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_DIALOG_SMS };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV Áö¿øÀÔ´Ï´Ù.
+
+	DECLARE_MESSAGE_MAP()
+};
Index: /trunk/msvc14/chevmsgr.sln
===================================================================
--- /trunk/msvc14/chevmsgr.sln	(revision 13)
+++ /trunk/msvc14/chevmsgr.sln	(revision 14)
@@ -12,4 +12,5 @@
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "client\client.vcxproj", "{E1C8D6C3-6426-417E-9B20-8A8D0F824CDB}"
 	ProjectSection(ProjectDependencies) = postProject
+		{A5238B12-5F59-4AF2-BC5C-DD93352082FD} = {A5238B12-5F59-4AF2-BC5C-DD93352082FD}
 		{39F45AE4-072E-44C4-8E2B-94DAC2333A5D} = {39F45AE4-072E-44C4-8E2B-94DAC2333A5D}
 	EndProjectSection
@@ -18,6 +19,14 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChevMsgrClient_MFC", "ChevMsgrClient_MFC\ChevMsgrClient_MFC.vcxproj", "{D1A1A73A-7E56-40FA-9D43-B8737C585D18}"
+	ProjectSection(ProjectDependencies) = postProject
+		{E1C8D6C3-6426-417E-9B20-8A8D0F824CDB} = {E1C8D6C3-6426-417E-9B20-8A8D0F824CDB}
+	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crypto", "crypto\crypto.vcxproj", "{A5238B12-5F59-4AF2-BC5C-DD93352082FD}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testClient", "testClient\testClient.vcxproj", "{765F513C-69FF-40AA-8EAF-624AE2DCA5F0}"
+	ProjectSection(ProjectDependencies) = postProject
+		{E1C8D6C3-6426-417E-9B20-8A8D0F824CDB} = {E1C8D6C3-6426-417E-9B20-8A8D0F824CDB}
+	EndProjectSection
 EndProject
 Global
@@ -69,4 +78,12 @@
 		{A5238B12-5F59-4AF2-BC5C-DD93352082FD}.Release|x86.ActiveCfg = Release|Win32
 		{A5238B12-5F59-4AF2-BC5C-DD93352082FD}.Release|x86.Build.0 = Release|Win32
+		{765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Debug|x64.ActiveCfg = Debug|x64
+		{765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Debug|x64.Build.0 = Debug|x64
+		{765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Debug|x86.ActiveCfg = Debug|Win32
+		{765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Debug|x86.Build.0 = Debug|Win32
+		{765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Release|x64.ActiveCfg = Release|x64
+		{765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Release|x64.Build.0 = Release|x64
+		{765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Release|x86.ActiveCfg = Release|Win32
+		{765F513C-69FF-40AA-8EAF-624AE2DCA5F0}.Release|x86.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /trunk/msvc14/testClient/test.cpp
===================================================================
--- /trunk/msvc14/testClient/test.cpp	(revision 14)
+++ /trunk/msvc14/testClient/test.cpp	(revision 14)
@@ -0,0 +1,90 @@
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <sstream>
+
+#include "msgclnt.h"
+
+#define T(_expr) if ((_expr) == false) { std::cerr << c.getLastError() << std::endl; return -1; }
+#define CIN(v) std::cout << #v << "\t: "; std::cin >> v
+
+std::string ip;
+std::string port;
+std::string id;
+std::string pw;
+std::string phone;
+std::string sms;
+
+std::vector<std::string> toList;
+
+int showChat(SConversation & c)
+{
+	std::cout << "[" << c.sessid << "][" << c.sensitive << "sec] "
+			  << c.from << ": " << c.message
+			  << std::endl;
+
+	return 0;
+}
+
+int newChat(SOpenSession & o)
+{
+	std::cout << "[" << o.sessid << "] => " << joinStrings(o.idList) << std::endl;
+	return 0;
+}
+
+bool sendChat(chev & m)
+{
+	SConversation c;
+	std::getline(std::cin, c.message);
+
+	c.from = id;
+	c.sensitive = 0;
+	c.sessid = m.getSessionID(toList);
+
+	return m.tell(c);
+}
+
+int main(int argc, char ** argv)
+{
+	// declaration
+	chev c;
+	SCallback cb;
+
+	std::string ini = argv[1];
+	std::string tok, to;
+
+	std::ifstream f(ini);
+
+	std::getline(f, ip);
+	std::getline(f, port);
+	std::getline(f, id);
+	std::getline(f, pw);
+	std::getline(f, phone);
+	std::getline(f, to);
+
+	std::istringstream is(to);
+	while (std::getline(is, tok, ','))
+		toList.push_back(tok);
+
+	// init
+	cb.onListen = showChat;
+	cb.onOpenSession = newChat;
+
+	// connect
+	T(c.connect(ip, atoi(port.c_str())));
+	T(c.listen(cb));
+	T(c.sms(phone));
+
+	CIN(sms);
+	T(c.join(id, pw, sms));
+	std::getline(std::cin, sms);
+
+	T(c.login(id, pw));
+
+	while (true)
+	{
+		T(sendChat(c));
+	}
+
+	return 0;
+}
Index: /trunk/msvc14/testClient/testClient.vcxproj
===================================================================
--- /trunk/msvc14/testClient/testClient.vcxproj	(revision 14)
+++ /trunk/msvc14/testClient/testClient.vcxproj	(revision 14)
@@ -0,0 +1,158 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{765F513C-69FF-40AA-8EAF-624AE2DCA5F0}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>testClient</RootNamespace>
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\properties.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\properties.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\properties.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\properties.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>$(OutDir)\client.lib;$(OutDir)\cf++.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>$(OutDir)\client.lib;$(OutDir)\cf++.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>$(OutDir)\client.lib;$(OutDir)\cf++.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>$(OutDir)\client.lib;$(OutDir)\cf++.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="test.cpp" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
Index: /trunk/msvc14/testClient/testClient.vcxproj.filters
===================================================================
--- /trunk/msvc14/testClient/testClient.vcxproj.filters	(revision 14)
+++ /trunk/msvc14/testClient/testClient.vcxproj.filters	(revision 14)
@@ -0,0 +1,22 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="소스 파일">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="헤더 파일">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="리소스 파일">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="test.cpp">
+      <Filter>소스 파일</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
