MFC serialize C++ - c++

I'm trying to serialize a listbox in MFC.
I used this code :
CFileDialog fileDlg(FALSE, _T(".txt"), NULL, 0, _T("Text File (.txt)|*.txt|")
_T("All files (*.*)|*.*||"));
if (fileDlg.DoModal() == IDOK)
{
const int numItems = m_listBox.GetCount();
CString itemText;
CStdioFile file;
if (file.Open(fileDlg.GetFileName(), CStdioFile::modeCreate | CStdioFile::modeWrite))
{
for (int i = 0; i < numItems; ++i)
{
m_listBox.GetText(i, itemText);
file.WriteString(itemText);
file.WriteString(_T("\n"));
}
file.Close();
}
But the saved file is always empty.
I tried a lot of versions of functions that save from listbox to text file but it didn't work.

In your code you are using CFileDialog::GetFileName. Is that intentional? That will only pass in the file name.
I would use CFileDialog::GetPathName which returns the full path to the file.
And you should be using a debugger (compile in debug mode) so you can walk your code.
The CStdioFile::Open method can also be passed a pointer to an exception object. Have a look at the help.

Related

Reading multiple serialized objects from a file

While making my Breakout game in MFC I chose to serialize my CBlock objects so the player can make its own "maps" on a level editor I made, everything is fine while saving; everything I do is to serialize all my CBlock objects with a for since I have all my CBlock objects on a vector<CBlock*>. The problem comes when reading the files. The main problem is that my program does not know how to stop reading when the end of the file ends. I've trying most of the bool methods from CArchive. The only one that kinda worked was CArchive::IsLoading() but the problem is that it still continues to read from file despite having reached the end of the file.
CString m_filter = TEXT("Super Breakout Maker Files (*.sbm)|*.sbm|All Files (*.*)|*.*||");
CFile m_loadFile;
CFileDialog m_fileDlg(TRUE, TEXT(".sbm"), TEXT("mylayout"), OFN_HIDEREADONLY, m_filter, NULL, 0, TRUE);
//CFileDialog m_fileDlg(FALSE, TEXT(".sbm"), TEXT("mylayout"), 0, m_filter);
if (m_fileDlg.DoModal() == IDOK)
{
if (m_blockLayout.size() > 0)
{
for (int i = 0; i < m_blockLayout.size(); i++)
{
delete(m_blockLayout[i]);
}
m_blockLayout.clear();
}
m_loadFile.Open(m_fileDlg.GetFileName(), CFile::modeRead);
CArchive m_loadArchive(&m_loadFile, CArchive::load);
while (m_loadArchive.IsLoading()==true)
{
CBlock* block = new CBlock;
block->Serialize(m_loadArchive);
block->AssignBlockType();
block->m_blockState.CreateCompatibleDC(pDC);
LoadBlock(block->m_blockState, m_blockStateArray, block->GetBlockType(), block->GetHits());
m_blockLayout.push_back(block);
}
m_loadArchive.Close();
if (m_blockLayout.size() > 0)
{
MessageBox(TEXT("Your layout was successfully loaded! Resume game to play."), TEXT("Notification"), MB_ICONINFORMATION);
m_pBall->SetInitialPosition(m_ballBMP, m_pBar, m_barBMP);
}
else
{
MessageBox(TEXT("Unable to read file. Corrupted or incompatible data."), TEXT("Notification"), MB_ICONERROR);
}
}
else
{
return;
}
m_loadFile.Close();
This is my loading method, but as I mentioned, the iteration does not know where to end reading.
Couple of simpler options, easiest would be to store how many blocks are in the file as the first thing in the file before your blocks. Read for that many blocks, then exit.
have a predefined block with specific attributes and member variables that is your "End Of File" Block, whenever you read that specific block, you know to discard it and stop reading.
The other alternative is to just have some specific string at the end of all your block data and check the next line after every block is read for that specific string (this would require some pointer variable for your line in the file though)

Using a CListCtrl with Drag and Drop not working

Using Visual Studio 2017 I am trying to enable drag and drop on a CListCtrl, I have added the code for this such as:
ON_WM_DROPFILES()
DragAcceptFiles();
m_listctrl.DragAcceptFiles();
void ProgramNameHere::OnDropFiles(HDROP hDropInfo)
{
CString sFile;
DWORD nBuffer = 0;
// Get the number of files dropped
int nFilesDropped = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);
for (int i = 0; i<nFilesDropped; i++)
{
// Get the buffer size of the file.
nBuffer = DragQueryFile(hDropInfo, i, NULL, 0);
// Get path and name of the file
DragQueryFile(hDropInfo, i, sFile.GetBuffer(nBuffer + 1), nBuffer + 1);
sFile.ReleaseBuffer();
MessageBox(PathFindFileName(sFile), PathFindFileName(sFile));
}
// Free the memory block containing the dropped-file information
DragFinish(hDropInfo);
CDialogEx::OnDropFiles(hDropInfo);
}
I am able to get it working when I drop a file onto the dialog itself anywhere but when I try and drop it onto the List Control it doesn't work.
Would anyone have any idea what I am doing wrong?

List all files recursively function in MFC error?

I want to list all my files and folders (include sub-folders) and show it into my list box so I think about writing a recursive function to display them. But the code work well if I show all files and folders in the selecting folder, but it can not scan in sub-folders (it show only the first folder and no more). Please help me to know what is the error?
This is my function (I add it into my Dialog class)
void CFileListingDlg::ListFile(CString path)
{
CFileFind hFile;
BOOL bFound;
CString filePath;
bFound=hFile.FindFile(path+L"\\*.*");
while(bFound)
{
bFound=hFile.FindNextFile();
if(!hFile.IsDots())
{
m_lFiles.AddString(hFile.GetFilePath());
//It work well with selecting folder if I remove this line
//But it shows only first folder when I use it
if(hFile.IsDirectory()) ListFile(hFile.GetFilePath()+L"\\*.*");
}
}
}
And then, I call it when click Browser button with the code
void CFileListingDlg::OnBnClickedBtnBrowse()
{
// TODO: Add your control notification handler code here
// TODO: Add your control notification handler code here
CFolderPickerDialog folderDialog(_T("E:\\Test"));
if(folderDialog.DoModal()==IDOK)
{
m_eFolder.SetWindowText(folderDialog.GetPathName());
m_lFiles.ResetContent();
ListFile(folderDialog.GetPathName());
}
}
Here is the proper way to implement recursive files listing:
void ListFiles(const CString& sPath, CStringArray& files)
{
CFileFind finder;
// build a string with wildcards
CString sWildcard(sPath);
sWildcard += _T("\\*.*");
BOOL bWorking = finder.FindFile(sWildcard);
while (bWorking)
{
bWorking = finder.FindNextFile();
// skip . and .. files; otherwise, we'd
// recur infinitely!
if (finder.IsDots())
continue;
// if it's a directory, recursively traverse it
if (finder.IsDirectory())
{
CString sFile = finder.GetFilePath();
files.Add(sFile);
ListFiles(sFile, files);
}
}
finder.Close();
}

c++ mfc csv file read

i have a problem with csv file reading. I'm pretty new to mfc and i hope someone can help me. So...i have a button and with it i open file dialog and choose csv file. In csv file i have diferent shapes(rectangle,ellipse,pollygon) with color and position info(separtor is ;). Now i need to show this informations in a ListBox and here i'm stuck. I got so far(code)...and i don't know it's ok and i can't find any good help so i hope someone can give me a hint.
void CDialogDrawing::OnBnClickedButton2()
{
TCHAR filtri[] = _T("CSV files (*.csv)|*.csv||");
CString path;
CFileDialog dlg(TRUE, _T("csv"), _T("*.csv"), OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, filtri);
dlg.m_ofn.lpstrTitle = _T("Open...");
if(dlg.DoModal() == IDOK) //OK
{
path = dlg.GetPathName();
//
CStdioFile readFile;
CFileException fileException;
CString strLine;
if(readFile.Open(path, CFile::modeRead, &fileException))
{
while (readFile.ReadString(strLine));
{
seznamLikov.AddString(strLine);
}
}
else
{
CString strErrorMsg;
strErrorMsg.Format(_T("Can't open file %s , error : %u"), path, fileException.m_cause);
AfxMessageBox(strErrorMsg);
}
readFile.Close();
}
}
Trailing semi-colon after the while:
while (readFile.ReadString(strLine));
{
seznamLikov.AddString(strLine);
}
remove it as it is equivalent to:
while (readFile.ReadString(strLine)) {}
{
seznamLikov.AddString(strLine);
}
meaning AddString() will be invoked only once, after ReadString() fails.

How to display the selected file name in the ListControl in MFC in Visual Studio?

I have created a grid function using list control. There are two columns in the list. Data and NAME.
The user should select a file; and the data inside the file should be diplayed in first column "DATA" and file name should be displayed in the 2nd column "NAME".
I have written a code but nothing is appearing in the list
CFileFind finder;
bool bFound;
CString filename = "C:\\ Location\\*.txt";
bFound = finder.FindFile(filename);
if(bFound)
{
while(bFound)
{
bFound = finder.FindNextFile();
if(bFound)
{
m_List.AddString(finder.GetFileName()); //This is where the actual data is added
}
}
CStdioFile files;
CFileException exp;
CString strLine;
if (files.Open(filename, CFile::modeRead, &exp))
{
while(files.ReadString(strLine)){}
}
}
void CuserspecificationDlg::InsertItems()
{
HWND hWnd = ::GetDlgItem(m_hWnd, IDC_LIST1);
// Set the LVCOLUMN structure with the required
// column information
..
..
SetCell(hWnd,out,1,1); // where out is the Cstring variable for edit control
}
What can be the mistake?
Please see a tutorial on how to use List box here. You could define a member variable of type CListBox that is mapped to your list box via the control wizard.