Link to home
Start Free TrialLog in
Avatar of chrisedgington
chrisedgington

asked on

CFileDialog in MFC Win32 console application

Simple question methinks:

I'm being lazy because I've been programming all day and my brain hurts :'(

Can someone give me some code to bring up a file dialog box please?

I've tried blatanty pasting the following into (a trivial version of) my program and it causes a debug assertion error. (afxwin1.inl line 22)

// declare  file dialog

CFileDialog filedlg (FALSE, "*.txt", "*.txt",
OFN_HIDEREADONLY | OFN_NOREADONLYRETURN | OFN_LONGNAMES,
"Text Files (*.txt)|*.txt|All Files (*.*)|*.*||", NULL);

// show "Save As" file dialog

if (filedlg.DoModal () == IDOK) // user has chosen a file, so
{
filename = filedlg.GetPathName (); // extract its filename
out.open(filename); // open file
out << "test data" << endl; // write data
out.close(); // close file
}


I'm sure that I am making a simple cock-up somewhere. And someone knows what it is... :)

Cheers
Avatar of lakshman_ce
lakshman_ce

I think you are displaying a Save As file dialog box and then you are trying to open a file. First param should be TRUE for a file open dialog.. Plz refer the constructor of CFileDialog and the example below..

From MSDN,

Definition for CFileDialog constructor
explicit CFileDialog(
   BOOL bOpenFileDialog,
   LPCTSTR lpszDefExt = NULL,
   LPCTSTR lpszFileName = NULL,
   DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
   LPCTSTR lpszFilter = NULL,
   CWnd* pParentWnd = NULL,
   DWORD dwSize = 0
);
Parameters
bOpenFileDialog
Set to TRUE to construct a File Open dialog box or FALSE to construct a File Save As dialog box.
lpszDefExt
The default filename extension. If the user does not include an extension in the Filename edit box, the extension specified by lpszDefExt is automatically appended to the filename. If this parameter is NULL, no file extension is appended.
lpszFileName
The initial filename that appears in the filename edit box. If NULL, no filename initially appears.
dwFlags
A combination of one or more flags that allow you to customize the dialog box. For a description of these flags, see the OPENFILENAME structure in the Platform SDK. If you modify the m_ofn.Flags structure member, use a bitwise-OR operator in your changes to keep the default behavior intact.
lpszFilter
A series of string pairs that specify filters you can apply to the file. If you specify file filters, only selected files will appear in the Files list box. See the Remarks section for more information on how to work with file filters.
pParentWnd
A pointer to the file dialog-box object's parent or owner window.
dwSize
The size of the OPENFILENAME structure. This value is dependent on the operating system version, so MFC can determine the appropriate kind of dialog to create (for example, new Windows 2000 dialogs as opposed to NT4 dialogs).
Remarks
Either a File Open or File Save As dialog box is constructed, depending on the value of bOpenFileDialog.

To allow the user to select multiple files, set the OFN_ALLOWMULTISELECT flag before calling DoModal. You need to supply your own filename buffer to accommodate the returned list of multiple filenames. Do this by replacing m_ofn.lpstrFile with a pointer to a buffer you have allocated, after constructing the CFileDialog, but before calling DoModal. Additionally, you must set m_ofn.nMaxFile with the number of characters in the buffer pointed to by m_ofn.lpstrFile.

To allow the user to resize an Explorer-style dialog box using either the mouse or keyboard, set the OFN_ENABLESIZING flag. Setting this flag is necessary only if you provide a hook procedure or custom template. The flag works only with an Explorer-style dialog box; old-style dialog boxes do not permit resizing.

The lpszFilter parameter is used to determine the type of filename a file must have to be displayed in the file list box. The first string in the string pair describes the filter; the second string indicates the file extension to use. Multiple extensions may be specified using ';' as the delimiter. The string ends with two '|' characters, followed by a NULL character. You can also use a CString object for this parameter.

For example, Microsoft Excel permits users to open files with extensions .XLC (chart) or .XLS (worksheet), among others. The filter for Excel could be written as:

static char BASED_CODE szFilter[] = "Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|*.xlc; *.xls|All Files (*.*)|*.*||";
Note, however, that if you plan to use this string to directly update the OPENFILENAME structure, that you should delimit your strings with the null character, '\0', instead of the vertical bars (|).

Example
void CChildFrame::OnFileOpen()
{
   // szFilters is a text string that includes two file name filters:
   // "*.my" for "MyType Files" and "*.*' for "All Files."
   char CChildFrame::szFilters[]=
      "MyType Files (*.my)|*.my|All Files (*.*)|*.*||";

   // Create an Open dialog; the default file name extension is ".my".
   CFileDialog fileDlg (TRUE, "my", "*.my",
      OFN_FILEMUSTEXIST| OFN_HIDEREADONLY, szFilters, this);
   
   // Display the file dialog. When user clicks OK, fileDlg.DoModal()
   // returns IDOK.
   if( fileDlg.DoModal ()==IDOK )
   {
      CString pathName = fileDlg.GetPathName();
   
      // Implement opening and reading file in here.
      ...
      //Change the window's title to the opened file's title.
      CString fileName = fileDlg.GetFileTitle ();
   
      SetWindowText(fileName);
   }

}



-Lakshman
Avatar of chrisedgington

ASKER

Thanks for your input.

The bool flag (open/save) notwithstanding, the call to CFileDialog still causes the debug assertion error. I'm not convinced that there isn't some very simple solution to it? Is there an include file that I need to use (other than stdafx.h?)
I had just copied that code from elsewhere which is why it wasn't entirely appropriate for what I'm trying to do.
If I comment out the subsequent code, it still doesn't work-there is something fishy about this:

CFileDialog filedlg (TRUE, "*.txt", "*.txt",
OFN_HIDEREADONLY | OFN_NOREADONLYRETURN | OFN_LONGNAMES,
"Text Files (*.txt)|*.txt|All Files (*.*)|*.*||", NULL);

Hit me with it like a smelly kipper, if you would...

Cheers
I guess it happens while you are trying to open the file and write to it.

Please comment out these lines

out.open(filename); // open file
out << "test data" << endl; // write data
out.close(); // close file

and try whether it crashes..

then just check what happens while writing to the file...

-Lakshman
ConGui: Sample for Console I/O with GUI I/O
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcsample98/html/vcsmpcongui.asp

"The ConGui sample demonstrates how a standard console application can take advantage of some of the graphical capabilities of Windows NT.

Caution   This sample application illustrates a method by which a console application can utilize some (but not all) of the graphical user interface (GUI) capabilities of the Win32 API. It was not the original design intention of the Console layer of Windows NT to allow it to interact in this manner with the graphical API, and because of this, problems can occur if you try to accomplish too much. Therefore, exercise restraint in using the graphical Win32 API in your console application. If your needs go beyond the simple methods illustrated here, consider designing your application as a full GUI application."
...And I thought it was a simple question! 100 odd meg download, and then it's a fully working program {without a file_open dialog but something n times more complex}.

I'm looking, but this isn't the nicely documented example one would hope for in mfc.. although I'm sure the answer is in there somewhere.

In the meantime whilst I attempt to figure out the relevant code, anyone care to point me in the right direction? :)

Ok. Change of tack.

Here's a *points free-for-all* for the person who answers this first (will split the points with Chensu since he answered the original question, or thereabouts):

I've re-written my program to work as a Dialog based mfc app. I want to be able to write output to the screen (thru a list box in the dialog), but I need to be able to do this from within my own classes, which aren't part of the CDialog class. I therefore figure that I need to get me a pointer to my dialog class. How would I do this?

I'm currently trying it through AfxGetApp() but not getting anywhere since this seems to want to return me pointers to Documents, which isn't altogether helpful.

 
I figured that one out for myself. Constructors are a wonderful thing, indeed.

Instead (I may or may not be taking liberties here), I'd like to know,

I have a (std, although I could make it a CString) string to which I want to add the contents of an int variable (this is for writing to this listbox in the dialog app). How do I go about it? I thought I could use the insertion (<<) operator, but the compiler is spitting at that.

ASKER CERTIFIED SOLUTION
Avatar of chensu
chensu
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks Chensu.

I had done precisely that in my constructor.

I also managed to find another method of getting an int into the string; using ostringstreams.

Hence I gave you a B-not a reflection on you, more on the fact that I managed to find a way around the problem in the meantime. Take heart from the fact that I had increased the number of points in the meantime... :)

Cheers for the help.