Solved

CFileDialog problem with ZIP files

Posted on 2013-12-18
6
634 Views
Last Modified: 2014-01-13
Hi everybody,

I have a problem in a MFC application where I yet wasn't able to find a solution, I hope someone here can help me. In my application I have following trivial code:
	CFileDialog dlg( TRUE );
	if ( dlg.DoModal() == IDOK )
	{
		AfxMessageBox( dlg.GetFileName() );
	}

Open in new window

This usually works as expected, but I found (at least in Windows 7) this displays an empty message box in case the file selected in the open-file dialog is contained in a ZIP file which can be opened in via the folder bar as shown here:Open file contained in a ZIP archiveI found this is not a general problem of the open-file common dialog, because I get a valid filename to a temporary created file using this none-MFC code:
	TCHAR buf[MAX_PATH + 1] = {};
	OPENFILENAME ofn = { sizeof( OPENFILENAME ) };

	ofn.Flags = OFN_FILEMUSTEXIST;
	ofn.lpstrFile = buf;
	ofn.nMaxFile = MAX_PATH;

	if ( FALSE != GetOpenFileName( &ofn ) )
	{
		MessageBox( NULL == ofn.lpstrFile ? "ERROR!" : ofn.lpstrFile );
	}

Open in new window

Beside this I even found my application can open such a file using DDE if it's double-clicked in the Explorer.

Does anyone have an idea if this can be fixed without replacing every CFileDialog (my application is quite huge, there are about 120 functions where CFileDialog is used)?

If there's no possibility to avoid CFileDialog returns an empty file string maybe anyone has an idea if it's possible to avoid ZIP files are shown as folders in a CFileDialog? This would be a suitable workaround for me.

Thanks in advance,

Best regards,

ZOPPO
0
Comment
Question by:Zoppo
  • 4
  • 2
6 Comments
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 100 total points
ID: 39727522
maybe anyone has an idea if it's possible to avoid ZIP files are shown as folders in a CFileDialog?
you could try to derive from CFileDialog, then overload the OnInitDialog, call CFileDialog::OnInitDialog. after that you should be able to retrieve tree control from dialog child windows. if you would subclass the tree control you could try to hook into the following message

(HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)lpInsertStruct); 

Open in new window

and prevent it to display zip-folders and subfolders by suppressing the message(s).

sounds complex? yes, it is, sorry.

Sara
0
 
LVL 30

Author Comment

by:Zoppo
ID: 39731208
Hi sarabande,

thanks for that idea, I'll think about it and make some tests. A problem is this even means I'll have to change a large amount of code, in addition to try to find a way to override some MFC functionality which internally use CFileDialog, but maybe it's worthwhile if it's not much more than replacing a class name.

I just took a look into CFileDialog and think I first need to understand how it works, unfortunateley I'm not quite sure how to do this since CFileDialog (at least in VS 2010) is implemented using some IFileDialog interface, I'm not sure if it's is already created when OnInitDialog (which in fact isn't implemened for CFileDialog) is called, all I found yet is the interface is created in the constructor and the dialog is shown in CFileDialog::DoModal using IModalWindow::Show, I don't know yet whether the dialog is already created at that time or where/how I can subclass controls in there.

I'll try to further understand how this works, maybe best is to try to find whether the problem comes from IFileDialog or from the way how it's used in CFileDialog.

So I'll make more tests and debugging. I'll keep you informed, but maybe with long breaks in between because I'll go for a 3-week holiday now, in this time I'll check my mails only sporadically :o)

Have a nice day,

best regards,

ZOPPO
0
 
LVL 32

Expert Comment

by:sarabande
ID: 39731416
yes, active-x controls probably could not easily subclassed.

I wonder whether the ability of the explorer to show zip files as folders actually is a capability of the explorer itself or whether the winzip (or your favorite zip) would provide that. if the latter, your issues could be simply a bug. to check that you may try to delete the association of zip files temporarily in the explorer or install another zip utility.

Sara
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 30

Author Comment

by:Zoppo
ID: 39736446
Hi Sara,

IMO it's the explorer himself, it even works before any third-party ZIP software is installed on a clean machine. IMO it's implemented as a shell extension, in registry I found the registered InProcServer32 for .ZIP extension is %SystemRoot%\system32\zipfldr.dll, so it's part of Windows. And I still don't think it's a general Windows problem, I guess it's just a bug in MFC implementation.

BTW: didn't yet continue testing this issue since I'm still in holidays, I just was checking my mails and saw your comment ...

I wish you a Merry Christmas,

best regards,

ZOPPO
0
 
LVL 30

Accepted Solution

by:
Zoppo earned 0 total points
ID: 39765164
Finally I found a convenient solution, I found a way to implement a CFileDialog-derived class which returns a file name to the temporary created copy of a file selected from a ZIP folder without need to change the standard layout/behavior of the CFileDialog.

The solution is to change the options used by the IFileDialog used in CFileDialog::DoModal like this:
INT_PTR CMyFileDialog::DoModal()
{
	if ( NULL != m_pIFileDialog )
	{
		FILEOPENDIALOGOPTIONS opts;
		IFileDialog* pDlg = static_cast<IFileDialog*>(m_pIFileDialog);
		pDlg->GetOptions( &opts );
		pDlg->SetOptions( opts | FOS_FORCEFILESYSTEM );
	}

	return CFileDialog::DoModal();
}

Open in new window

That's it ...

Unfortunateley I didn't yet found a possibility to find out whether the returned filename comes from within a ZIP or is a real file. IMO this would be great too in order to inform the user such a file won't be updated in the ZIP file when it's saved. But this is another problem I even have when such a file is opened from Explorer via DDE, so it's not related to CFileDialog.

ZOPPO
0
 
LVL 30

Author Closing Comment

by:Zoppo
ID: 39776068
I found the solution myself, but for the spent time/effort I assigned some points to Sara too ...
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
A short article about a problem I had getting the GPS LocationListener working.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
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.

758 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

Need Help in Real-Time?

Connect with top rated Experts

25 Experts available now in Live!

Get 1:1 Help Now