?
Solved

GetSaveFileName: How to change the selected type filter after checking if it is possible?  (*.xlsx --> *.xls)

Posted on 2011-09-16
6
Medium Priority
?
1,099 Views
Last Modified: 2012-05-12
Hi,

Briefly: The user uses the standard Save As... dialog, and selected the .XLSX format to be used for export.  His/her Excel does not support that format.  Because of that, I would like to display an information message box, and after pressing OK I would like to correct the choice in the filter combo-box the older .XLS format.  How to do the correction?

The background: I want the user to choose the export format in our application. It uses the standard Save As... dialog.  The user is given always the full list of formats that the application is capable to export.  However, some formats require other applications being present at the machine.  If the user wants to export the older MS Excel format (.xls), the MS Excel must be found.  If the user wants to export using the newer MS Excel format (.xlsx), the sufficient version of MS Excel must be installed.  I want the list of possible output formats be always fully displayed; otherwise, our customers tend to complain that "you should support the new Excel" even though they do no thave the newer Excel installed.  I want to tell them what to do via the application (not via the phone or e-mail ;).

Actually, we use the WTL::CFileDialogImpl<> wrapper around the Save As dialog functionality.  The derived class constructor looks like this:

CExportDialog::CExportDialog() : 

    WTL::CFileDialogImpl<CExportDialog> (
       FALSE,                // ... Save As dialog
       NULL,                 // default extension
       NULL,                 // default FileName 
       OFN_HIDEREADONLY 
       | OFN_OVERWRITEPROMPT //
       | OFN_NOCHANGEDIR     // 
       | OFN_EXPLORER        // I want the CDN_TYPECHANGE be generated.
       ,
       NULL,                 // Filter
       NULL),                // hWndParent
  
    // Initial export directory name got from the saved configuration.
    //
    m_DirName(GetLastExportPath())
{ 
    USES_CONVERSION;

    // Combo box of the file filters.
    //
    m_ofn.lpstrFilter = TEXT("HTML (*.htm)\0*.htm\0"
                             "MS Excel 97-2003 (*.xls)\0*.xls\0" 
                             "MS Excel 2007+ (*.xlsx)\0*.xlsx\0" 
                             "TXT ; (*.txt)\0*.txt\0"
                             "MS Word 97-2003 (*.doc)\0*.doc\0" 
                             "MS Word 2007+ (*.docx)\0*.docx\0" 
                             "MS Word (*.rtf)\0*.rtf\0" 
                             );

    // Initially set export type as the last saved from previous export. 
    // This string identification is the application specific -- see below.
    //
    m_ExportType = GetLastExportType();

    // Based on the m_ExportType, set the information for the dialog.
    //
    if (m_ExportType == "HTML")
    {
        m_ofn.nFilterIndex = 1;
        m_ofn.lpstrDefExt = TEXT("htm");
    }
    else if (m_ExportType == "XLS")
    {
        m_ofn.nFilterIndex = 2;
        m_ofn.lpstrDefExt = TEXT("xls");
    }
    else if (m_ExportType == "XLSX")
    {
        m_ofn.nFilterIndex = 3;
        m_ofn.lpstrDefExt = TEXT("xlsx");
    }
    ... snip ...
    else
    {
        // Correction in the case of the unexpected identification.
        //
        m_ExportType = "HTML";
        m_ofn.nFilterIndex = 1;
        m_ofn.lpstrDefExt = TEXT("htm");
    }

    // Get the generated filename suggested to the user (ignore the details).
    //
    lstrcpyn(m_szFileName, A2CT(GetNextFilename_().c_str()), _MAX_PATH);

    // Set the dialog caption.
    //
    m_ofn.lpstrTitle = TEXT("This is the dialog caption");

    // Set the initial directory for the dialog.
    //
    m_szInitialDir[0] = '\0';                             // init
    m_ofn.lpstrInitialDir = m_szInitialDir; 

    if ( ! m_DirName.empty())
        lstrcpyn(m_szInitialDir, A2CT(m_DirName.c_str()), // set the explicit one
                 sizeof(m_szInitialDir));
}

Open in new window


The CExportDialog class overrides also the OnTypeChange() method that is activated by the event CDN_TYPECHANGE.  I tried to make that method resposible for checking and correction of the type:

void CExportDialog::OnTypeChange(LPOFNOTIFY lpon)
{
    ATLASSERT(lpon != 0);
    ATLASSERT(lpon->lpOFN != 0);
  
    // Get the index in the filter list boxu (1 for the first item).
    //
    int nFilterIndex = lpon->lpOFN->nFilterIndex;

    // Get the application dependent export type identification based on the index
    // and set the default extension for the saved file.
    // 
    switch (nFilterIndex)
    {
    case 1:
        m_ExportType = "HTML"; 
        SetDefExt(TEXT("htm")); 
        break;

    case 2:
        m_ExportType = "XLS";
        SetDefExt(TEXT("xls"));
        break;

    case 3:
        m_ExportType = "XLSX";
        SetDefExt(TEXT("xlsx"));
        break;

    ... snip ...
    
    default:
        ATLASSERT(false);  // makes sense only for DEBUG
    }

    // Here I tried to check and correct say the XSLT to XSL, display 
    // the information message box, and set the corrected information 
    // to the dialog. However, I have failed to update the visible status
    // of the dialog.  What should be done in the method?
    //
    CheckAndMakeCorrection_();

    // The corrected type implies another auto-generated filename.
    //
    SetControlText(edt1, A2CT(GetNextFilename_().c_str()));
}

Open in new window


Say, I am able to detect that the user wanted XLSX and can check that the situatio allows only the XLS.  I tried the following code (all the code in the "if" body is questionable -- I am not sure here):

    m_ExportType = "XLS";
    ...
    if (m_ExportType == "XLS")
    {
        m_ofn.nFilterIndex = 2;
        m_ofn.lpstrDefExt = TEXT("xls");
        SetDefExt(TEXT("xls"));
    }

Open in new window


It does not do what I would expect.  It visually adds the corrected extension to the file name (probably because of the SetDefExt(), but it does not chage the combo box of the filter, nor the content of the filtered file names.

How should I do that?

Thanks for your time and experience,
   Petr
0
Comment
Question by:pepr
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
6 Comments
 
LVL 16

Accepted Solution

by:
HooKooDooKu earned 1000 total points
ID: 36552195
After setting the m_ofn.nFilterIndex, have you tried calling a method or sending a message that the Filter list box (or the whole window) needs to be repainted?
0
 
LVL 29

Author Comment

by:pepr
ID: 36554062
Hi HooKooDooKu.  Well, yes and no.  I tried things like UpdateWindow (the whole one), but it was not that.  I did not try to send anything to the combo box.  Looking at the code now, I should probably do something similar like I did with the SetControlText(edt1, A2CT(GetNextFilename_().c_str()));

0
 
LVL 29

Author Comment

by:pepr
ID: 36597533
(I did not forget to my question. Let me some more time, please. ;)
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Assisted Solution

by:geoffkk
geoffkk earned 1000 total points
ID: 36815028
You could use Application.version to determine which formats are supported and construct the string m_ofn.lpstrFilter accordingly.

Geoff
0
 
LVL 29

Author Comment

by:pepr
ID: 36816408
@geoffkk: Yes, I could construct the string.  However, I have reasons not to do so -- as explained in the question.  Actually, the application supports it, and I want to show the user that it is supported, if the conditions are met.
0
 
LVL 29

Author Closing Comment

by:pepr
ID: 36917248
Than you both!  I gave you "A" grade as you apparently tried your best.  The solution was easy to follow but it was not accurate and was only partially complete.  But this is not your fault :)  I have chosen to solve the problem differently.  Have a nice day. Petr
0

Featured Post

Get real performance insights from real users

Key features:
- Total Pages Views and Load times
- Top Pages Viewed and Load Times
- Real Time Site Page Build Performance
- Users’ Browser and Platform Performance
- Geographic User Breakdown
- And more

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When asking a question in a forum or creating documentation, screenshots are vital tools that can convey a lot more information and save you and your reader a lot of time
In the absence of a fully-fledged GPO Management product like AGPM, the script in this article will provide you with a simple way to watch the domain (or a select OU) for GPOs changes and automatically take backups when policies are added, removed o…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question