タイルの削除、保存、ロード、読み込み

5591 ワード

装飾ボタン

まず自分が望むようにダイアログを飾り、戦士法師のボタンはコンビネーションボタンの中で1つしか選択できないラジオボタンで、剣道は自由にチェックできるチェックボックスだと書いてあります.
削除ボタン
//Delete 
void CUnitTool::OnBnClickedButton3()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
	UpdateData(TRUE);
	int iIndex = m_ListBox.GetCurSel(); 
    	//현재 리스트박스에 선택된 인덱스를 가져옵니다.
        
	CString wstrFindName = L""; 
	m_ListBox.GetText(iIndex, wstrFindName); 
    //인덱스로부터 텍스트를 받아옵니다.

	auto& iter = m_mapUnitInfo.find(wstrFindName);
    // 이터레이터를 사용해 받아온 키를 찾습니다
	if (m_mapUnitInfo.end() == iter)
		return; 
    // 없다면 리턴으로 종료합니다
	Safe_Delete(iter->second); 
    // 우선 밸류에있는 구조체를 삭제해주고
	m_mapUnitInfo.erase(iter); 
	m_ListBox.DeleteString(iIndex); 
    	//맵에서 키를 삭제해줍니다.
    	UpdateData(FALSE);
}
保存、読み込み
SAVEとLOADボタンをクリックして保存とロードを行います.
各ボタンにクリックイベントを追加します.
// SAVE
void CUnitTool::OnBnClickedButton4()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
	CFileDialog Dlg(FALSE, L"dat", L"*.dat");
    //첫번째 인자는 저장인지 불러오기인지 FALSE일경우 저장, 두번째 인자는 기본 확장자,세번째는 기본 저장명 나머지인자는 굳이 추가해주지않아도됨

	TCHAR szFilePath[MAX_PATH]{}; 
	// 현재 경로를 얻어오는 함수 . 
	//D:\박병건\120C\Directx\FrameWork\MFCTool
    
	GetCurrentDirectory(MAX_PATH, szFilePath); //현재 절대 경로 불러오기
    
	//D:\박병건\120C\Directx\FrameWork
	PathRemoveFileSpec(szFilePath); //맨 뒤 경로 삭제
    
	lstrcat(szFilePath, L"\\Data"); // 데이터 폴더에 저장할것이므로 문자열 추가
    
	Dlg.m_ofn.lpstrInitialDir = szFilePath; //경로 열기
	if (IDOK == Dlg.DoModal())
	{
		CString wstrFilePath = Dlg.GetPathName(); 
		//
		HANDLE hFile = CreateFile(Dlg.GetPathName(),GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr );
        //핸들 열어줌
		if (INVALID_HANDLE_VALUE == hFile)
			return; 

		DWORD dwByte = 0; 
		DWORD dwStringByte = 0; 
        
        //포인터변수(여기선 CString 변수)를 그대로 저장할경우 오류발생 꼭 처리해주어야함
        
		for (auto& rPair : m_mapUnitInfo)
		{
			dwStringByte = (rPair.first.GetLength() + 1) * sizeof(wchar_t);
			WriteFile(hFile, &dwStringByte, sizeof(DWORD), &dwByte, nullptr);
            
            //문자열의 길이를 저장
			WriteFile(hFile, rPair.first.GetString(), dwStringByte, &dwByte, nullptr); 
            //문자열 저장
			WriteFile(hFile, &rPair.second->iAtt, sizeof(int), &dwByte, nullptr); 
			WriteFile(hFile, &rPair.second->iDef, sizeof(int), &dwByte, nullptr);
			WriteFile(hFile, &rPair.second->byJob, sizeof(BYTE), &dwByte, nullptr);
			WriteFile(hFile, &rPair.second->byItem, sizeof(BYTE), &dwByte, nullptr);
            //나머지 변수들 저장
		}

		CloseHandle(hFile);
        //핸들 닫아줌
	}
}
//Load
void CUnitTool::OnBnClickedButton5()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
	CFileDialog Dlg(TRUE,// 열기(TRUE) 혹은 저장(FALSE) 모드 
		L"dat", L"*.dat");

	TCHAR szFilePath[MAX_PATH]{};
	// 현재 경로를 얻어오는 함수 . 
	//D:\박병건\120C\Directx\FrameWork\MFCTool
	GetCurrentDirectory(MAX_PATH, szFilePath);
	//D:\박병건\120C\Directx\FrameWork
	PathRemoveFileSpec(szFilePath);
	lstrcat(szFilePath, L"\\Data");
	Dlg.m_ofn.lpstrInitialDir = szFilePath;
    
    //save와 동일
	if (IDOK == Dlg.DoModal())
	{
		CString wstrFilePath = Dlg.GetPathName();
		//
		HANDLE hFile = CreateFile(Dlg.GetPathName(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
        // 제네렉_리드로 핸들 열어줌
        
		if (INVALID_HANDLE_VALUE == hFile)
			return;

		for (auto& rPair : m_mapUnitInfo)
			Safe_Delete(rPair.second); 
		m_mapUnitInfo.clear(); 

		m_ListBox.ResetContent(); 
		// 불러오기 전 기존 데이터 삭제
        
		DWORD dwByte = 0;
		DWORD dwStringByte = 0;
		UNITINFO* pUnitInfo = nullptr; 
		TCHAR* pBuf = nullptr; 
		while (true)
		{
			ReadFile(hFile, &dwStringByte, sizeof(DWORD), &dwByte, nullptr);
            
            
			if (0 == dwByte)
				break; 
                
            //우선 기존 문자열의 길이를 받아옴 만약 이게 없다면 모두 읽어온것이므로 break
			pBuf = new TCHAR[dwStringByte]; 

			ReadFile(hFile, pBuf, dwStringByte, &dwByte, nullptr);
			pUnitInfo = new UNITINFO; 
			pUnitInfo->wstrName = pBuf;
            //읽어본 문자열의 길이 만큼 문자열을 복사해 새로운 유닛인포에 넣어줌
			Safe_Delete_Array(pBuf); 
            
            //용도를 다했으므로 삭제
            
            
			ReadFile(hFile, &pUnitInfo->iAtt, sizeof(int), &dwByte, nullptr);
			ReadFile(hFile, &pUnitInfo->iDef, sizeof(int), &dwByte, nullptr);
			ReadFile(hFile, &pUnitInfo->byJob, sizeof(BYTE), &dwByte, nullptr);
			ReadFile(hFile, &pUnitInfo->byItem, sizeof(BYTE), &dwByte, nullptr);
			//나머지 변수들 불러오기
			m_mapUnitInfo.emplace(pUnitInfo->wstrName, pUnitInfo);
			m_ListBox.AddString(pUnitInfo->wstrName); 
            //map에 추가해주고 리스트박스에도 스트링 추가
		}

		CloseHandle(hFile);
	}
}
タイルを張る
タイルを入れるための窓を構成する


リストボックスをクリックして、プロパティで「ファイルを受け入れる」をtrueとして指定します.
そしてイベントにONDROPFILEを追加
void CMapTool::OnDropFiles(HDROP hDropInfo)
{
	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
	int iCount = DragQueryFile(hDropInfo, 0xffffffff, nullptr, 0);
    //성공적인 드래그 앤 드롭 작업으로 인해 드롭된 파일의 이름을 검색합니다.
	TCHAR szBuf[MAX_PATH] = L""; 
	for (int i = 0 ; i < iCount; ++i )
	{
		DragQueryFile(hDropInfo, i, szBuf, MAX_PATH); 
		m_ListBox.AddString(szBuf); 
        //리스트박스에 스트링을 추가해줍니다.
	}
	UpdateData(FALSE); 
	CDialog::OnDropFiles(hDropInfo);
}