|
No clue, just a suggestion: don't convert the project, recreate it from scratch. It shouldn't be too difficult or time-consuming. It may just be that your old project has been customized in ways that VC.NET can't deal and then it gets a heart attack.
Regards,
Alvaro
Hey! It compiles! Ship it.
|
|
|
|
|
Thanks for taking the time. I know what you mean, but I am trying to avoid that route becuase this one creates 18 DLLs and 1 EXE, in a single project. So, recreating it in .NET with all the options and flags will be a tricky & time-consuming process. Hence my reluctance....
But, THANKS again....
regards,
(vinod)
|
|
|
|
|
18 DLLs? Talk about modularization!
It sounds like you're gonna be spending some time recreating it. Yet another alternative may be to make VC.NET convert each project (DLL) individually and at the end put them all together under one solution.
Good luck!
Alvaro
Hey! It compiles! Ship it.
|
|
|
|
|
I have an SDI application and it requires the use of multiple text files for it's input. I originally had no problems with using these files for input. Now, the program will crash if the user opens their file (through File -> Open) before an input file is opened. I'm pretty sure it's because the application is an SDI. The only reason why the user needs to open a file is because I need the filename, I don't care what's actually in the file that they want to open. Is there another way that I could obtain this filename, without actually opening the file, but with still having the user believe that it has been opened?
Sorry if this is a bit confusing, I can't think of any other way to explain it.
|
|
|
|
|
This sounds more like an Options or Configuration dialog sort of thing.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
The text files that the program uses for input have nothing to do with the file that the user selects to open. The user doesn't even know that these files are being used. That is why it was decided to stick with the typical File -> Open. By the time I'm done with this, it may be necessary to actually use this file the user wants to open, but for now it's not required.
I was just wondering if there was any way to have more than one file open at a time when using SDI?
|
|
|
|
|
Like David mentioned, you may want to consider creating an "Options" dialog box where the user can tell you the name of the file(s), and you can save that in the registry or something similar.
Opening multiple files should be no problem -- use the CFile class. Showing them is another story. If it's an SDI app then you can only show one at a time. But perhaps you don't even care about showing the files. If that's the case don't complicate your life with SDI or MDI. Create a dialog-based app and add all the controls you need to it.
Regards,
Alvaro
Hey! It compiles! Ship it.
|
|
|
|
|
I'm not displaying any of the file information (as of yet). The files unknown to the user are used mainly for storing output, and reading for input.
Using other files for input/ouput works just fine if the user never "opens" a file. As soon as the user does this, it seems to not create any of the other files required for the output.
In my CMainFrame constructor I have:
CMainFrame::CMainFrame()
{
m_fileName = "inputParams.txt"; //used first for output, later as input
CFile m_filePtr(m_fileName, CFile::modeCreate);
}
Later on, a modeless dialog opens up which first attempts to open m_fileName for reading. It will successfully do this as long as the user has not "opened" a file:
BOOL CSetupModeless::OnInitDialog()
{
CDialog::OnInitDialog();
CFileException e;
CFile paramFilePtr = ((CMainFrame*)m_parent)->m_filePtr;
paramFileName = ((CMainFrame*)m_parent)->m_fileName;
//attempt to open inputParams.txt for reading only
if((paramFilePtr.Open(paramFileName, CFile::modeRead, &e )) == false )
{
//it will only come in here if user "opened" a file first
AfxMessageBox("error");
}
else
{
//it will come in here all the time, until
//the user "opens" a file... this is where it should go!
}
return TRUE;
}
Anyone know what would stop it from entering into the else when the user "opens" a file?
|
|
|
|
|
I notice a couple of glaring problems with your code:
1. In your CMainFrame constructor you initialize the m_filePtr member, but in reality you're not! All you're doing is creating a local variable called m_filePtr, which then immediately gets destroyed when the constructor exits. You should do it this way instead:
CMainFrame::CMainFrame()
{
m_fileName = "inputParams.txt";
m_filePtr.Open(m_fileName, CFile::modeCreate);
}
OR even better,
CMainFrame::CMainFrame() :
m_fileName("inputParams.txt"),
m_filePtr(m_fileName, CFile::modeCreate)
{
}
2. Inside your OnInitDialog, you should retrive a reference to your m_filePtr member, not a copy (although I'm not sure what that does):
CFile& paramFilePtr = ((CMainFrame*)m_parent)->m_filePtr;
I hope this helps.
Regards,
Alvaro
Hey! It compiles! Ship it.
|
|
|
|
|
I'll try fixing that up a bit tomorrow... I see what you mean about what I had in my MainFrame constructor, although it confuses me as to why it would work every other time I ran my program (always works as long as the user never actually opens a file)...
Thanks a lot for your help... and hopefully I'll get this all straightened out!
|
|
|
|
|
The frame object should not have anything to do with files. It's for frame manipulation. Having a CFile object anywhere near it is a fundamentally bad idea.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
So then where should I be attempting to create this file? I need this file to exist throughout the entire program execution, so I don't want to create it every time the modeless dialog that uses it opens up.
Is it best to maybe put that CFile object inside the Doc class?
|
|
|
|
|
b_girl wrote:
...so I don't want to create it every time the modeless dialog that uses it opens up.
If the file and the dialog are that closely related, why not let the dialog object open/close the file accordingly? Otherwise, leaving a file open for the duration of the application is an invitation for trouble.
b_girl wrote:
Is it best to maybe put that CFile object inside the Doc class?
It's certainly better than the frame's class. Whether it's "best" or not would depend on some other factors, which are unknown at this point.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
DavidCrow wrote:
why not let the dialog object open/close the file accordingly?
the dialog object does open/close the file whenever it needs to. the file doesn't stay open the whole time. i'm talking about just creating the file (with mode::Create). as of right now, the mainframe class creates the file but that's all it does. the rest of the operations on the file are carried out by the dialog object.
|
|
|
|
|
b_girl wrote:
i'm talking about just creating the file (with mode::Create).
Let the dialog object create the file, too.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
But the dialog object may be created/destroyed more than once... and i need that file to stay in-tact. the first time the dialog object is created, the file will be used for writing. the file needs to remain after the dialog object is destroyed, because every other time the dialog object is created the file will be used for reading.
|
|
|
|
|
b_girl wrote:
the file needs to remain after the dialog object is destroyed...
Files don't go away, unless they are explicitly deleted. The persistence of a disk file has nothing to do with whether an object (e.g., dialog) exists or not.
What is wrong with:
class CMyDialog : public CDialog
{
private:
CStdioFile file;
};
BOOL CMyDialog::OnInitDialog( void )
{
CDialog::OnInitDialog();
file.Open(_T("..."), CFile::modeCreate | CFile::modeNoTruncate | CFile::modeReadWrite);
or
int nMode = CFile::modeCreate | CFile::modeNoTruncate;
if (_access(_T("..."), 0) == 0)
nMode |= CFile::modeRead;
else
nMode |= CFile::modeWrite;
file.Open(_T("..."), nMode);
or
int nMode;
if (_access(_T("..."), 0) == 0)
nMode = CFile::modeRead;
else
nMode = CFile::modeCreate | CFile::modeWrite;
file.Open(_T("..."), nMode);
}
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
you know, maybe there's nothing wrong with that. i didn't realize you could combine modes like that.
i'm assuming this:
file.Open(_T("..."), CFile::modeCreate | CFile::modeNoTruncate | CFile::modeReadWrite);
will create the file if it hasn't been created, and allow it to be read/written...
like i said before (or i think i did at least), i'm somewhat new to programming for windows with vc++, so i don't completely know all the little tricks and such.
|
|
|
|
|
b_girl wrote:
...so i don't completely know all the little tricks and such.
For more "tricks," see these two links:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cfile.3a3a.cfile.asp
http://msdn.microsoft.com/library/en-us/vclib/html/_mfc_CFile.3a3a.Open.asp?frame=true
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
The file still doesn't contain any data after it's been written to. This is what I have:
class CMyDialog : public CDialog
{
private:
CStdioFile file;
};
BOOL CSetupModeless::OnInitDialog()
{
CDialog::OnInitDialog();
paramFileName = "inputParams.txt";
if((paramFile.Open(paramFileName, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeReadWrite)) == 0)
AfxMessageBox("error opening paramFile");
}
void CSetupModeless::OnOK()
{
CString setupInput;
setupInput = setup->constructSetupInput();
AfxMessageBox(setupInput); //check to make sure string comes back with proper info
paramFile.WriteString(setupInput);
paramFile.Close();
}
Is there anything wrong with that??? constructSetupInput is just a function that returns the string that needs to be written to the file. The value of setupInput does come back correctly.
|
|
|
|
|
void CSetupModeless::OnOK()
{
CString setupInput = setup->constructSetupInput();
AfxMessageBox(setupInput);
if (NULL != paramFile.m_pStream && paramFile.m_hFile != CFile::hFileNull)
{
TRY
{
paramFile.WriteString(setupInput);
paramFile.Close();
}
CATCH(CFileException, *e)
{
e->ReportError();
}
}
}
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
well, the solution to my problem was a lot simpler than i was expecting.
i had:
paramFileName = "inputParams.txt";
if(paramFile.Open(paramFileName, CFile::modeCreate| CFile::modeNoTruncate | CFile::modeReadWrite) == 0)
AfxMessageBox("error opening paramFile");
when i should have just had:
if(paramFile.Open(_T("C:\\inputParams.txt"), CFile::modeCreate| CFile::modeNoTruncate | CFile::modeReadWrite) == 0)
AfxMessageBox("error opening paramFile");
What does the _T("..") mean?
Thank you sooo much for all your help!
|
|
|
|
|
The _T() macro is not what solved your problem. Using an absolute path is.
b_girl wrote:
What does the _T("..") mean?
It will eventually resolve to something familiar. Put your cursor on it and press F12.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
Is there any way to find out the directory that the progam is running out of?
I have found out how to get the current working directory, but this is not what I want because if the user changes directories, the current working directory changes with it. I want to be able to have these extra files in the directory that my program is running out of.
I have done this:
BOOL CSetupModeless::OnInitDialog()
{
int drive, maxLength;
maxLength = 100;
drive = _getdrive();
static char path[100];
_getdcwd(drive,path,maxLength);
//...
}
but that doesn't give me the desired results.
|
|
|
|
|
GetModuleFileName[Ex]() will do it.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|